mirror of
https://gitlab.com/freepascal.org/lazarus/lazarus.git
synced 2025-04-23 18:20:00 +02:00
GDBMI-Debugger: Option "gdbsNone" to start without internal start break.
This may not work on all platforms, depending on how gdb reports the target-PID. This should work for all/any gdb-server session git-svn-id: trunk@61588 -
This commit is contained in:
parent
7925f988ef
commit
1caa4b3b33
@ -94,6 +94,7 @@ type
|
||||
|
||||
TGDBMITargetFlag = (
|
||||
tfHasSymbols, // Debug symbols are present
|
||||
tfPidDetectionDone,
|
||||
tfRTLUsesRegCall, // the RTL is compiled with RegCall calling convention
|
||||
tfClassIsPointer, // with dwarf class names are pointer. with stabs they are not
|
||||
tfExceptionIsPointer, // Can happen, if stabs and dwarf are mixed
|
||||
@ -135,7 +136,7 @@ type
|
||||
gdfeNone, gdfeDefault, gdfeEscSpace, gdfeQuote
|
||||
);
|
||||
TGDBMIDebuggerStartBreak = (
|
||||
gdsbDefault, gdsbEntry, gdsbMainAddr, gdsbMain, gdsbAddZero
|
||||
gdsbDefault, gdbsNone, gdsbEntry, gdsbMainAddr, gdsbMain, gdsbAddZero
|
||||
);
|
||||
TGDBMIUseNoneMiRunCmdsState = (
|
||||
gdnmNever, gdnmAlways, gdnmFallback
|
||||
@ -818,6 +819,7 @@ type
|
||||
FCommandProcessingLock: Integer;
|
||||
|
||||
FMainAddrBreak: TGDBMIInternalBreakPoint;
|
||||
FPasMainAddrBreak: TGDBMIInternalBreakPoint;
|
||||
FBreakAtMain: TDBGBreakPoint;
|
||||
FBreakErrorBreak: TGDBMIInternalBreakPoint;
|
||||
FRunErrorBreak: TGDBMIInternalBreakPoint;
|
||||
@ -2166,9 +2168,10 @@ procedure TGDBMIDbgInstructionQueue.HandleGdbDataBeforeInstruction(var AData: St
|
||||
|
||||
// check internal error
|
||||
Debugger.CheckForInternalError(Line, TheInstruction.DebugText);
|
||||
|
||||
end;
|
||||
|
||||
var
|
||||
s: String;
|
||||
begin
|
||||
if AData <> ''
|
||||
then case AData[1] of
|
||||
@ -2180,6 +2183,13 @@ begin
|
||||
//'=': DoMsgAsync(AData);
|
||||
end;
|
||||
|
||||
if not (tfPidDetectionDone in TGDBMIDebugger(Debugger).FTargetInfo.TargetFlags) then begin
|
||||
s := GetPart(['Switching to process '], [' local', ']'], AData, True);
|
||||
TGDBMIDebugger(Debugger).FTargetInfo.TargetPID := StrToIntDef(s, 0);
|
||||
if TGDBMIDebugger(Debugger).FTargetInfo.TargetPID <> 0 then
|
||||
Include(TGDBMIDebugger(Debugger).FTargetInfo.TargetFlags, tfPidDetectionDone);
|
||||
end;
|
||||
|
||||
inherited HandleGdbDataBeforeInstruction(AData, SkipData, TheInstruction);
|
||||
end;
|
||||
|
||||
@ -2341,16 +2351,7 @@ function TGDBMIDebuggerInstruction.ProcessInputFromGdb(const AData: String): Boo
|
||||
end;
|
||||
|
||||
procedure DoMsgAsync(Line: String);
|
||||
var
|
||||
S: String;
|
||||
begin
|
||||
S := GetPart('=', ',', Line, False, False);
|
||||
if s = 'thread-group-started' then begin // thread-group-started // needed in RunToMain
|
||||
// Todo, store in seperate field
|
||||
if FCmd is TGDBMIDebuggerCommandStartDebugging then
|
||||
FLogWarnings := FLogWarnings + Line + LineEnding;
|
||||
end;
|
||||
|
||||
FCmd.FTheDebugger.DoNotifyAsync(Line);
|
||||
end;
|
||||
|
||||
@ -2716,8 +2717,12 @@ var
|
||||
s: String;
|
||||
List: TGDBMINameValueList;
|
||||
begin
|
||||
if TargetInfo^.TargetPID <> 0 then
|
||||
if (TargetInfo^.TargetPID <> 0) or
|
||||
(tfPidDetectionDone in TargetInfo^.TargetFlags)
|
||||
then
|
||||
exit;
|
||||
|
||||
Include(TargetInfo^.TargetFlags, tfPidDetectionDone);
|
||||
(* PID via "info program"
|
||||
|
||||
Somme linux, gdb 7.1
|
||||
@ -2942,7 +2947,7 @@ var
|
||||
end;
|
||||
|
||||
var
|
||||
S: String;
|
||||
S, s2: String;
|
||||
idx: Integer;
|
||||
{$IFDEF DBG_ASYNC_WAIT}
|
||||
GotPrompt: integer;
|
||||
@ -3026,6 +3031,13 @@ begin
|
||||
DebugLn(DBG_VERBOSE, '[DBGTGT] ', S);
|
||||
end;
|
||||
end;
|
||||
|
||||
if not (tfPidDetectionDone in FTheDebugger.FTargetInfo.TargetFlags) then begin
|
||||
s2 := GetPart(['Switching to process '], [' local', ']'], S, True);
|
||||
FTheDebugger.FTargetInfo.TargetPID := StrToIntDef(s2, 0);
|
||||
if FTheDebugger.FTargetInfo.TargetPID <> 0 then
|
||||
Include(FTheDebugger.FTargetInfo.TargetFlags, tfPidDetectionDone);
|
||||
end;
|
||||
Break;
|
||||
end;
|
||||
|
||||
@ -5060,7 +5072,7 @@ function TGDBMIDebuggerCommandStartDebugging.DoExecute: Boolean;
|
||||
MaybeAddMainBrk(mtEntry, 0, false);
|
||||
MaybeAddMainBrk(mtMainAddr, 0);
|
||||
end;
|
||||
else begin // gdsbDefault
|
||||
gdsbDefault: begin
|
||||
// SetByName: "main", this is the best aproach, unless any library also exports main.
|
||||
MaybeAddMainBrk(mtMain, -1);
|
||||
MaybeAddMainBrk(mtEntry, -1, true); // Previous versions used "+0" as 2nd in the list
|
||||
@ -5069,6 +5081,7 @@ function TGDBMIDebuggerCommandStartDebugging.DoExecute: Boolean;
|
||||
// set only, if no other is set (e.g. 2nd attempt)
|
||||
MaybeAddMainBrk(mtEntry, 0, false);
|
||||
end;
|
||||
else ;// gdbsNone
|
||||
end;
|
||||
Result := bcnt < FTheDebugger.FMainAddrBreak.BreakSetCount; // added new breaks
|
||||
end;
|
||||
@ -5077,14 +5090,6 @@ function TGDBMIDebuggerCommandStartDebugging.DoExecute: Boolean;
|
||||
var
|
||||
s: String;
|
||||
begin
|
||||
s := GetPart(['=thread-group-started,'], [LineEnding], ALogTxt, True, False);
|
||||
if s <> '' then
|
||||
s := GetPart(['pid="'], ['"'], s, True, False);
|
||||
if s <> '' then begin
|
||||
Result := StrToIntDef(s, 0);
|
||||
if Result <> 0 then exit;
|
||||
end;
|
||||
|
||||
s := GetPart(['process '], [' local', ']'], ALogTxt, True);
|
||||
Result := StrToIntDef(s, 0);
|
||||
end;
|
||||
@ -5127,7 +5132,6 @@ function TGDBMIDebuggerCommandStartDebugging.DoExecute: Boolean;
|
||||
BrkErr: Boolean;
|
||||
begin
|
||||
EntryPointNum := StrToQWordDef(EntryPoint, 0);
|
||||
TargetInfo^.TargetPID := 0;
|
||||
FDidKillNow := False;
|
||||
|
||||
// TODO: async
|
||||
@ -5160,8 +5164,11 @@ function TGDBMIDebuggerCommandStartDebugging.DoExecute: Boolean;
|
||||
exit;
|
||||
end;
|
||||
s := r.Values + FLogWarnings;
|
||||
if TargetInfo^.TargetPID = 0 then
|
||||
if TargetInfo^.TargetPID = 0 then begin
|
||||
TargetInfo^.TargetPID := ParseLogForPid(s);
|
||||
if TargetInfo^.TargetPID <> 0 then
|
||||
Include(TargetInfo^.TargetFlags, tfPidDetectionDone);
|
||||
end;
|
||||
|
||||
s2 := '';
|
||||
if R.State = dsRun
|
||||
@ -5285,6 +5292,9 @@ function TGDBMIDebuggerCommandStartDebugging.DoExecute: Boolean;
|
||||
exit;
|
||||
|
||||
TargetInfo^.TargetPID := ParseLogForPid(rval);
|
||||
if TargetInfo^.TargetPID <> 0 then
|
||||
Include(TargetInfo^.TargetFlags, tfPidDetectionDone);
|
||||
|
||||
if TargetInfo^.TargetPID <> 0 then
|
||||
exit;
|
||||
|
||||
@ -5361,6 +5371,8 @@ begin
|
||||
|
||||
TargetInfo^.TargetCPU := '';
|
||||
TargetInfo^.TargetOS := osUnknown;
|
||||
Exclude(TargetInfo^.TargetFlags, tfPidDetectionDone);
|
||||
TargetInfo^.TargetPID := 0;
|
||||
|
||||
// try to retrieve the filetype and program entry point
|
||||
FileType := '';
|
||||
@ -5389,23 +5401,25 @@ begin
|
||||
(* We need a breakpoint at entry-point or main, to continue initialization
|
||||
"main" could map to more than one location, so we try entry point first
|
||||
*)
|
||||
RunToMain(EntryPoint);
|
||||
if DebuggerProperties.InternalStartBreak <> gdbsNone then begin
|
||||
RunToMain(EntryPoint);
|
||||
|
||||
if DebuggerState = dsStop
|
||||
then begin
|
||||
Result := False;
|
||||
FSuccess := False;
|
||||
Exit;
|
||||
end;
|
||||
|
||||
if DebuggerState = dsError
|
||||
then begin
|
||||
Result := False;
|
||||
FSuccess := False;
|
||||
Exit;
|
||||
end;
|
||||
end;
|
||||
DefaultTimeOut := DebuggerProperties.TimeoutForEval; // Getting address for breakpoints may need timeout
|
||||
|
||||
if DebuggerState = dsStop
|
||||
then begin
|
||||
Result := False;
|
||||
FSuccess := False;
|
||||
Exit;
|
||||
end;
|
||||
|
||||
if DebuggerState = dsError
|
||||
then begin
|
||||
Result := False;
|
||||
FSuccess := False;
|
||||
Exit;
|
||||
end;
|
||||
|
||||
DebugLn(DBG_VERBOSE, '[Debugger] Target PID: %u', [TargetInfo^.TargetPID]);
|
||||
|
||||
Exclude(FTheDebugger.FDebuggerFlags, dfSetBreakFailed);
|
||||
@ -5436,12 +5450,25 @@ begin
|
||||
FTheDebugger.RunQueue; // run all the breakpoints
|
||||
Application.ProcessMessages; // workaround, allow source-editor to queue line info request (Async call)
|
||||
|
||||
if FTheDebugger.FBreakAtMain <> nil
|
||||
then begin
|
||||
CanContinue := False;
|
||||
TGDBMIBreakPoint(FTheDebugger.FBreakAtMain).Hit(CanContinue);
|
||||
if DebuggerProperties.InternalStartBreak = gdbsNone then begin
|
||||
if FContinueCommand = nil then begin
|
||||
// set breakpoint for first line (Step-In/Over instead of run)
|
||||
FTheDebugger.FPasMainAddrBreak.SetByName(Self);
|
||||
end;
|
||||
ReleaseRefAndNil(FContinueCommand);
|
||||
FContinueCommand := TGDBMIDebuggerCommandExecute.Create(FTheDebugger, ectRun);
|
||||
CanContinue := True;
|
||||
StoppedAtEntryPoint := False;
|
||||
end
|
||||
else CanContinue := True;
|
||||
|
||||
else begin
|
||||
if FTheDebugger.FBreakAtMain <> nil
|
||||
then begin
|
||||
CanContinue := False;
|
||||
TGDBMIBreakPoint(FTheDebugger.FBreakAtMain).Hit(CanContinue);
|
||||
end
|
||||
else CanContinue := True;
|
||||
end;
|
||||
|
||||
//if FTheDebugger.DebuggerFlags * [dfSetBreakFailed, dfSetBreakPending] <> [] then begin
|
||||
// if FTheDebugger.OnFeedback
|
||||
@ -5616,9 +5643,13 @@ begin
|
||||
NewPID := StrToIntDef(FProcessID, 0);
|
||||
end;
|
||||
|
||||
TargetInfo^.TargetPID := NewPID;
|
||||
if NewPID <> 0 then
|
||||
TargetInfo^.TargetPID := NewPID;
|
||||
|
||||
DetectTargetPid(True);
|
||||
if NewPID = 0 then
|
||||
DetectTargetPid(True);
|
||||
|
||||
include(TargetInfo^.TargetFlags, tfPidDetectionDone);
|
||||
if TargetInfo^.TargetPID = 0 then begin
|
||||
ExecuteCommand('detach', [], R);
|
||||
SetDebuggerErrorState(Format(gdbmiCommandStartMainRunNoPIDError, [LineEnding]));
|
||||
@ -6279,6 +6310,13 @@ begin
|
||||
Exit;
|
||||
end;
|
||||
|
||||
if FTheDebugger.FPasMainAddrBreak.MatchId(BreakID)
|
||||
then begin
|
||||
SetDebuggerState(dsPause); // after GetLocation => dsPause may run stack, watches etc
|
||||
FTheDebugger.DoCurrent(FTheDebugger.FCurrentLocation);
|
||||
exit;
|
||||
end;
|
||||
|
||||
if FTheDebugger.FBreakErrorBreak.MatchId(BreakID)
|
||||
then begin
|
||||
ProcessBreak; // will set dsPause / unless CanContinue
|
||||
@ -7787,6 +7825,7 @@ end;
|
||||
constructor TGDBMIDebuggerBase.Create(const AExternalDebugger: String);
|
||||
begin
|
||||
FMainAddrBreak := TGDBMIInternalBreakPoint.Create('main');
|
||||
FPasMainAddrBreak:= TGDBMIInternalBreakPoint.Create('pascalmain');
|
||||
FBreakErrorBreak := TGDBMIInternalBreakPoint.Create('FPC_BREAK_ERROR');
|
||||
FRunErrorBreak := TGDBMIInternalBreakPoint.Create('FPC_RUNERROR');
|
||||
FExceptionBreak := TGDBMIInternalBreakPoint.Create('FPC_RAISEEXCEPTION');
|
||||
@ -7905,6 +7944,7 @@ begin
|
||||
FreeAndNil(FTypeRequestCache);
|
||||
FreeAndNil(FMaxLineForUnitCache);
|
||||
FreeAndNil(FMainAddrBreak);
|
||||
FreeAndNil(FPasMainAddrBreak);
|
||||
FreeAndNil(FBreakErrorBreak);
|
||||
FreeAndNil(FRunErrorBreak);
|
||||
FreeAndNil(FExceptionBreak);
|
||||
@ -8204,10 +8244,25 @@ end;
|
||||
procedure TGDBMIDebuggerBase.AddThreadGroup(const S: String);
|
||||
var
|
||||
List: TGDBMINameValueList;
|
||||
s1, s2: String;
|
||||
p: LongInt;
|
||||
begin
|
||||
List := TGDBMINameValueList.Create(S);
|
||||
FThreadGroups.Values[List.Values['id']] := List.Values['pid'];
|
||||
List.Free;
|
||||
|
||||
if not (tfPidDetectionDone in FTargetInfo.TargetFlags) then begin
|
||||
s1 := S;
|
||||
s2 := GetPart(['=thread-group-started,'], [LineEnding], s1, True, False);
|
||||
if s2 <> '' then begin
|
||||
s2 := GetPart(['pid="'], ['"'], s2, True, False);
|
||||
Include(FTargetInfo.TargetFlags, tfPidDetectionDone); // only consider the first one
|
||||
if s2 <> '' then begin
|
||||
p := StrToIntDef(s2, 0);
|
||||
FTargetInfo.TargetPID := p;
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
|
||||
procedure TGDBMIDebuggerBase.RemoveThreadGroup(const S: String);
|
||||
@ -8311,11 +8366,11 @@ begin
|
||||
Threads.Changed;
|
||||
end;
|
||||
end;
|
||||
2: DoDbgEvent(ecModule, etModuleLoad, Line);
|
||||
2: DoDbgEvent(ecModule, etModuleLoad, Line); //shlibs
|
||||
3: DoDbgEvent(ecModule, etModuleLoad, ParseLibraryLoaded(Line));
|
||||
4: DoDbgEvent(ecModule, etModuleUnload, ParseLibraryUnloaded(Line));
|
||||
5: DoDbgEvent(ecModule, etDefault, Line);
|
||||
6: AddThreadGroup(Line);
|
||||
5: DoDbgEvent(ecModule, etDefault, Line); //shlibs
|
||||
6: AddThreadGroup(Line); //thread-group-started
|
||||
7: RemoveThreadGroup(Line);
|
||||
8: DoDbgEvent(ecThread, etThreadStart, ParseThread(Line, EventText));
|
||||
9: DoDbgEvent(ecThread, etThreadExit, ParseThread(Line, EventText));
|
||||
|
Loading…
Reference in New Issue
Block a user