mirror of
https://gitlab.com/freepascal.org/fpc/source.git
synced 2025-09-27 02:30:57 +02:00
+ added OldValue and CurrentValue field for watchpoints
+ InitBreakpoints and DoneBreakpoints + MessageBox if GDB stops bacause of a watchpoint !
This commit is contained in:
parent
005b441e7d
commit
7917d69435
@ -17,7 +17,8 @@ unit FPDebug;
|
|||||||
interface
|
interface
|
||||||
|
|
||||||
uses
|
uses
|
||||||
Views,Objects,GDBCon,GDBInt;
|
Views,FPViews,
|
||||||
|
Objects,GDBCon,GDBInt;
|
||||||
|
|
||||||
type
|
type
|
||||||
PDebugController=^TDebugController;
|
PDebugController=^TDebugController;
|
||||||
@ -35,6 +36,7 @@ type
|
|||||||
procedure AnnotateError;
|
procedure AnnotateError;
|
||||||
procedure InsertBreakpoints;
|
procedure InsertBreakpoints;
|
||||||
procedure RemoveBreakpoints;
|
procedure RemoveBreakpoints;
|
||||||
|
procedure ResetBreakpointsValues;
|
||||||
procedure DoDebuggerScreen;virtual;
|
procedure DoDebuggerScreen;virtual;
|
||||||
procedure DoUserScreen;virtual;
|
procedure DoUserScreen;virtual;
|
||||||
procedure Reset;virtual;
|
procedure Reset;virtual;
|
||||||
@ -52,7 +54,9 @@ type
|
|||||||
typ : BreakpointType;
|
typ : BreakpointType;
|
||||||
state : BreakpointState;
|
state : BreakpointState;
|
||||||
owner : PBreakpointCollection;
|
owner : PBreakpointCollection;
|
||||||
Name : PString; { either function name or file name }
|
Name : PString; { either function name or expr to watch }
|
||||||
|
FileName : PString;
|
||||||
|
OldValue,CurrentValue : Pstring;
|
||||||
Line : Longint; { only used for bt_file_line type }
|
Line : Longint; { only used for bt_file_line type }
|
||||||
Conditions : PString; { conditions relative to that breakpoint }
|
Conditions : PString; { conditions relative to that breakpoint }
|
||||||
IgnoreCount : Longint; { how many counts should be ignored }
|
IgnoreCount : Longint; { how many counts should be ignored }
|
||||||
@ -61,34 +65,46 @@ type
|
|||||||
GDBState : BreakpointState;
|
GDBState : BreakpointState;
|
||||||
constructor Init_function(Const AFunc : String);
|
constructor Init_function(Const AFunc : String);
|
||||||
constructor Init_file_line(AFile : String; ALine : longint);
|
constructor Init_file_line(AFile : String; ALine : longint);
|
||||||
constructor Init_type(atyp : BreakpointType;Const AFunc : String);
|
constructor Init_type(atyp : BreakpointType;Const AnExpr : String);
|
||||||
procedure Insert;
|
procedure Insert;
|
||||||
procedure Remove;
|
procedure Remove;
|
||||||
procedure Enable;
|
procedure Enable;
|
||||||
procedure Disable;
|
procedure Disable;
|
||||||
|
procedure ResetValues;
|
||||||
destructor Done;virtual;
|
destructor Done;virtual;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
TBreakpointCollection=object(TCollection)
|
TBreakpointCollection=object(TCollection)
|
||||||
function At(Index: Integer): PBreakpoint;
|
function At(Index: Integer): PBreakpoint;
|
||||||
|
function GetGDB(index : longint) : PBreakpoint;
|
||||||
|
function GetType(typ : BreakpointType;Const s : String) : PBreakpoint;
|
||||||
function ToggleFileLine(Const FileName: String;LineNr : Longint) : boolean;
|
function ToggleFileLine(Const FileName: String;LineNr : Longint) : boolean;
|
||||||
procedure Update;
|
procedure Update;
|
||||||
procedure FreeItem(Item: Pointer); virtual;
|
procedure FreeItem(Item: Pointer); virtual;
|
||||||
|
procedure ShowBreakpoints(W : PSourceWindow);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
const
|
||||||
|
BreakpointTypeStr : Array[BreakpointType] of String[9]
|
||||||
|
= ( 'function','file-line','watch','awatch','rwatch','invalid' );
|
||||||
|
BreakpointStateStr : Array[BreakpointState] of String[8]
|
||||||
|
= ( 'enabled','disabled','invalid' );
|
||||||
|
|
||||||
var
|
var
|
||||||
Debugger : PDebugController;
|
Debugger : PDebugController;
|
||||||
BreakpointCollection : PBreakpointCollection;
|
BreakpointCollection : PBreakpointCollection;
|
||||||
|
|
||||||
procedure InitDebugger;
|
procedure InitDebugger;
|
||||||
procedure DoneDebugger;
|
procedure DoneDebugger;
|
||||||
|
procedure InitBreakpoints;
|
||||||
|
procedure DoneBreakpoints;
|
||||||
|
|
||||||
implementation
|
implementation
|
||||||
|
|
||||||
uses
|
uses
|
||||||
Dos,Mouse,Video,
|
Dos,Mouse,Video,
|
||||||
App,Strings,
|
App,Strings,
|
||||||
FPViews,FPVars,FPUtils,FPConst,
|
FPVars,FPUtils,FPConst,
|
||||||
FPIntf,FPCompile,FPIde;
|
FPIntf,FPCompile,FPIde;
|
||||||
|
|
||||||
|
|
||||||
@ -127,6 +143,15 @@ begin
|
|||||||
BreakpointCollection^.ForEach(@DoDelete);
|
BreakpointCollection^.ForEach(@DoDelete);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
procedure TDebugController.ResetBreakpointsValues;
|
||||||
|
procedure DoResetVal(PB : PBreakpoint);
|
||||||
|
begin
|
||||||
|
PB^.ResetValues;
|
||||||
|
end;
|
||||||
|
begin
|
||||||
|
BreakpointCollection^.ForEach(@DoResetVal);
|
||||||
|
end;
|
||||||
|
|
||||||
destructor TDebugController.Done;
|
destructor TDebugController.Done;
|
||||||
begin
|
begin
|
||||||
{ kill the program if running }
|
{ kill the program if running }
|
||||||
@ -137,6 +162,7 @@ end;
|
|||||||
|
|
||||||
procedure TDebugController.Run;
|
procedure TDebugController.Run;
|
||||||
begin
|
begin
|
||||||
|
ResetBreakpointsValues;
|
||||||
inherited Run;
|
inherited Run;
|
||||||
MyApp.SetCmdState([cmResetDebugger],true);
|
MyApp.SetCmdState([cmResetDebugger],true);
|
||||||
end;
|
end;
|
||||||
@ -174,8 +200,11 @@ procedure TDebugController.DoSelectSourceLine(const fn:string;line:longint);
|
|||||||
var
|
var
|
||||||
W: PSourceWindow;
|
W: PSourceWindow;
|
||||||
Found : boolean;
|
Found : boolean;
|
||||||
|
PB : PBreakpoint;
|
||||||
|
S : String;
|
||||||
|
BreakIndex : longint;
|
||||||
begin
|
begin
|
||||||
|
BreakIndex:=stop_breakpoint_number;
|
||||||
Desktop^.Lock;
|
Desktop^.Lock;
|
||||||
if Line>0 then
|
if Line>0 then
|
||||||
dec(Line);
|
dec(Line);
|
||||||
@ -229,6 +258,36 @@ begin
|
|||||||
end;
|
end;
|
||||||
LastFileName:=fn;
|
LastFileName:=fn;
|
||||||
Desktop^.UnLock;
|
Desktop^.UnLock;
|
||||||
|
if BreakIndex>0 then
|
||||||
|
begin
|
||||||
|
PB:=BreakpointCollection^.GetGDB(stop_breakpoint_number);
|
||||||
|
{ For watch we should get old and new value !! }
|
||||||
|
If PB^.typ<>bt_file_line then
|
||||||
|
begin
|
||||||
|
Command('p '+GetStr(PB^.Name));
|
||||||
|
S:=StrPas(GetOutput);
|
||||||
|
If Pos('=',S)>0 then
|
||||||
|
S:=Copy(S,Pos('=',S)+1,255);
|
||||||
|
If S[Length(S)]=#10 then
|
||||||
|
Delete(S,Length(S),1);
|
||||||
|
if Assigned(PB^.OldValue) then
|
||||||
|
DisposeStr(PB^.OldValue);
|
||||||
|
PB^.OldValue:=PB^.CurrentValue;
|
||||||
|
PB^.CurrentValue:=NewStr(S);
|
||||||
|
If PB^.typ=bt_function then
|
||||||
|
WarningBox(#3'GDB stopped due to'#13+
|
||||||
|
#3+BreakpointTypeStr[PB^.typ]+' '+GetStr(PB^.Name),nil)
|
||||||
|
else if (GetStr(PB^.OldValue)<>S) then
|
||||||
|
WarningBox(#3'GDB stopped due to'#13+
|
||||||
|
#3+BreakpointTypeStr[PB^.typ]+' '+GetStr(PB^.Name)+#13+
|
||||||
|
#3+'Old value = '+GetStr(PB^.OldValue)+#13+
|
||||||
|
#3+'New value = '+GetStr(PB^.CurrentValue),nil)
|
||||||
|
else
|
||||||
|
WarningBox(#3'GDB stopped due to'#13+
|
||||||
|
#3+BreakpointTypeStr[PB^.typ]+' '+GetStr(PB^.Name)+#13+
|
||||||
|
#3+' value = '+GetStr(PB^.CurrentValue),nil);
|
||||||
|
end;
|
||||||
|
end;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
procedure TDebugController.DoEndSession(code:longint);
|
procedure TDebugController.DoEndSession(code:longint);
|
||||||
@ -274,20 +333,26 @@ begin
|
|||||||
state:=bs_enabled;
|
state:=bs_enabled;
|
||||||
GDBState:=bs_deleted;
|
GDBState:=bs_deleted;
|
||||||
Name:=NewStr(AFunc);
|
Name:=NewStr(AFunc);
|
||||||
|
FileName:=nil;
|
||||||
|
Line:=0;
|
||||||
IgnoreCount:=0;
|
IgnoreCount:=0;
|
||||||
Commands:=nil;
|
Commands:=nil;
|
||||||
Conditions:=nil;
|
Conditions:=nil;
|
||||||
|
OldValue:=nil;
|
||||||
|
CurrentValue:=nil;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
constructor TBreakpoint.Init_type(atyp : BreakpointType;Const AFunc : String);
|
constructor TBreakpoint.Init_type(atyp : BreakpointType;Const AnExpr : String);
|
||||||
begin
|
begin
|
||||||
typ:=atyp;
|
typ:=atyp;
|
||||||
state:=bs_enabled;
|
state:=bs_enabled;
|
||||||
GDBState:=bs_deleted;
|
GDBState:=bs_deleted;
|
||||||
Name:=NewStr(AFunc);
|
Name:=NewStr(AnExpr);
|
||||||
IgnoreCount:=0;
|
IgnoreCount:=0;
|
||||||
Commands:=nil;
|
Commands:=nil;
|
||||||
Conditions:=nil;
|
Conditions:=nil;
|
||||||
|
OldValue:=nil;
|
||||||
|
CurrentValue:=nil;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
constructor TBreakpoint.Init_file_line(AFile : String; ALine : longint);
|
constructor TBreakpoint.Init_file_line(AFile : String; ALine : longint);
|
||||||
@ -295,17 +360,19 @@ begin
|
|||||||
typ:=bt_file_line;
|
typ:=bt_file_line;
|
||||||
state:=bs_enabled;
|
state:=bs_enabled;
|
||||||
GDBState:=bs_deleted;
|
GDBState:=bs_deleted;
|
||||||
AFile:=NameAndExtOf(AFile);
|
|
||||||
{ d:test.pas:12 does not work !! }
|
{ d:test.pas:12 does not work !! }
|
||||||
{ I do not know how to solve this if
|
{ I do not know how to solve this if
|
||||||
if (Length(AFile)>1) and (AFile[2]=':') then
|
if (Length(AFile)>1) and (AFile[2]=':') then
|
||||||
AFile:=Copy(AFile,3,255);
|
AFile:=Copy(AFile,3,255);
|
||||||
Only use base name for now !! PM }
|
Only use base name for now !! PM }
|
||||||
Name:=NewStr(AFile);
|
FileName:=NewStr(AFile);
|
||||||
|
Name:=nil;
|
||||||
Line:=ALine;
|
Line:=ALine;
|
||||||
IgnoreCount:=0;
|
IgnoreCount:=0;
|
||||||
Commands:=nil;
|
Commands:=nil;
|
||||||
Conditions:=nil;
|
Conditions:=nil;
|
||||||
|
OldValue:=nil;
|
||||||
|
CurrentValue:=nil;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
procedure TBreakpoint.Insert;
|
procedure TBreakpoint.Insert;
|
||||||
@ -316,7 +383,7 @@ begin
|
|||||||
if (GDBState=bs_deleted) and (state=bs_enabled) then
|
if (GDBState=bs_deleted) and (state=bs_enabled) then
|
||||||
begin
|
begin
|
||||||
if (typ=bt_file_line) then
|
if (typ=bt_file_line) then
|
||||||
Debugger^.Command('break '+name^+':'+IntToStr(Line))
|
Debugger^.Command('break '+NameAndExtOf(FileName^)+':'+IntToStr(Line))
|
||||||
else if typ=bt_function then
|
else if typ=bt_function then
|
||||||
Debugger^.Command('break '+name^)
|
Debugger^.Command('break '+name^)
|
||||||
else if typ=bt_watch then
|
else if typ=bt_watch then
|
||||||
@ -340,6 +407,8 @@ begin
|
|||||||
{ Here there was a problem !! }
|
{ Here there was a problem !! }
|
||||||
begin
|
begin
|
||||||
GDBIndex:=0;
|
GDBIndex:=0;
|
||||||
|
ErrorBox(#3'Could not set Breakpoint'#13+
|
||||||
|
#3+BreakpointTypeStr[typ]+' '+Name^,nil);
|
||||||
state:=bs_disabled;
|
state:=bs_disabled;
|
||||||
end;
|
end;
|
||||||
end
|
end
|
||||||
@ -362,7 +431,9 @@ procedure TBreakpoint.Enable;
|
|||||||
begin
|
begin
|
||||||
If not assigned(Debugger) then Exit;
|
If not assigned(Debugger) then Exit;
|
||||||
if GDBIndex>0 then
|
if GDBIndex>0 then
|
||||||
Debugger^.Command('enable '+IntToStr(GDBIndex));
|
Debugger^.Command('enable '+IntToStr(GDBIndex))
|
||||||
|
else
|
||||||
|
Insert;
|
||||||
GDBState:=bs_enabled;
|
GDBState:=bs_enabled;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
@ -374,11 +445,24 @@ begin
|
|||||||
GDBState:=bs_disabled;
|
GDBState:=bs_disabled;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
procedure TBreakpoint.ResetValues;
|
||||||
|
begin
|
||||||
|
if assigned(OldValue) then
|
||||||
|
DisposeStr(OldValue);
|
||||||
|
OldValue:=nil;
|
||||||
|
if assigned(CurrentValue) then
|
||||||
|
DisposeStr(CurrentValue);
|
||||||
|
CurrentValue:=nil;
|
||||||
|
end;
|
||||||
|
|
||||||
destructor TBreakpoint.Done;
|
destructor TBreakpoint.Done;
|
||||||
begin
|
begin
|
||||||
Remove;
|
Remove;
|
||||||
|
ResetValues;
|
||||||
if assigned(Name) then
|
if assigned(Name) then
|
||||||
DisposeStr(Name);
|
DisposeStr(Name);
|
||||||
|
if assigned(FileName) then
|
||||||
|
DisposeStr(FileName);
|
||||||
if assigned(Conditions) then
|
if assigned(Conditions) then
|
||||||
DisposeStr(Conditions);
|
DisposeStr(Conditions);
|
||||||
if assigned(Commands) then
|
if assigned(Commands) then
|
||||||
@ -410,13 +494,50 @@ begin
|
|||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
function TBreakpointCollection.GetGDB(index : longint) : PBreakpoint;
|
||||||
|
|
||||||
|
function IsNum(P : PBreakpoint) : boolean;
|
||||||
|
begin
|
||||||
|
IsNum:=P^.GDBIndex=index;
|
||||||
|
end;
|
||||||
|
|
||||||
|
begin
|
||||||
|
if index=0 then
|
||||||
|
GetGDB:=nil
|
||||||
|
else
|
||||||
|
GetGDB:=FirstThat(@IsNum);
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure TBreakpointCollection.ShowBreakpoints(W : PSourceWindow);
|
||||||
|
|
||||||
|
procedure SetInSource(P : PBreakpoint);
|
||||||
|
begin
|
||||||
|
If assigned(P^.FileName) and (P^.FileName^=W^.Editor^.FileName) then
|
||||||
|
W^.Editor^.SetLineBreakState(P^.Line,P^.state=bs_enabled);
|
||||||
|
end;
|
||||||
|
|
||||||
|
begin
|
||||||
|
ForEach(@SetInSource);
|
||||||
|
end;
|
||||||
|
|
||||||
|
function TBreakpointCollection.GetType(typ : BreakpointType;Const s : String) : PBreakpoint;
|
||||||
|
|
||||||
|
function IsThis(P : PBreakpoint) : boolean;
|
||||||
|
begin
|
||||||
|
IsThis:=(P^.typ=typ) and (P^.Name^=S);
|
||||||
|
end;
|
||||||
|
|
||||||
|
begin
|
||||||
|
GetType:=FirstThat(@IsThis);
|
||||||
|
end;
|
||||||
|
|
||||||
function TBreakpointCollection.ToggleFileLine(Const FileName: String;LineNr : Longint) : boolean;
|
function TBreakpointCollection.ToggleFileLine(Const FileName: String;LineNr : Longint) : boolean;
|
||||||
|
|
||||||
var PB : PBreakpoint;
|
var PB : PBreakpoint;
|
||||||
|
|
||||||
function IsThere(P : PBreakpoint) : boolean;
|
function IsThere(P : PBreakpoint) : boolean;
|
||||||
begin
|
begin
|
||||||
IsThere:=(P^.typ=bt_file_line) and (P^.Name^=FileName) and (P^.Line=LineNr);
|
IsThere:=(P^.typ=bt_file_line) and (P^.FileName^=FileName) and (P^.Line=LineNr);
|
||||||
end;
|
end;
|
||||||
begin
|
begin
|
||||||
PB:=FirstThat(@IsThere);
|
PB:=FirstThat(@IsThere);
|
||||||
@ -477,13 +598,27 @@ begin
|
|||||||
Use_gdb_file:=false;
|
Use_gdb_file:=false;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
procedure InitBreakpoints;
|
||||||
begin
|
begin
|
||||||
New(BreakpointCollection,init(10,10));
|
New(BreakpointCollection,init(10,10));
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure DoneBreakpoints;
|
||||||
|
begin
|
||||||
|
Dispose(BreakpointCollection,Done);
|
||||||
|
BreakpointCollection:=nil;
|
||||||
|
end;
|
||||||
|
|
||||||
end.
|
end.
|
||||||
|
|
||||||
{
|
{
|
||||||
$Log$
|
$Log$
|
||||||
Revision 1.9 1999-02-08 17:43:43 pierre
|
Revision 1.10 1999-02-10 09:55:07 pierre
|
||||||
|
+ added OldValue and CurrentValue field for watchpoints
|
||||||
|
+ InitBreakpoints and DoneBreakpoints
|
||||||
|
+ MessageBox if GDB stops bacause of a watchpoint !
|
||||||
|
|
||||||
|
Revision 1.9 1999/02/08 17:43:43 pierre
|
||||||
* RestDebugger or multiple running of debugged program now works
|
* RestDebugger or multiple running of debugged program now works
|
||||||
+ added DoContToCursor(F4)
|
+ added DoContToCursor(F4)
|
||||||
* Breakpoints are now inserted correctly (was mainlyy a problem
|
* Breakpoints are now inserted correctly (was mainlyy a problem
|
||||||
|
Loading…
Reference in New Issue
Block a user