Browse Source

+ added OldValue and CurrentValue field for watchpoints
+ InitBreakpoints and DoneBreakpoints
+ MessageBox if GDB stops bacause of a watchpoint !

pierre 26 years ago
parent
commit
7917d69435
1 changed files with 148 additions and 13 deletions
  1. 148 13
      ide/text/fpdebug.pas

+ 148 - 13
ide/text/fpdebug.pas

@@ -17,7 +17,8 @@ unit FPDebug;
 interface
 
 uses
-  Views,Objects,GDBCon,GDBInt;
+  Views,FPViews,
+  Objects,GDBCon,GDBInt;
 
 type
   PDebugController=^TDebugController;
@@ -35,6 +36,7 @@ type
     procedure AnnotateError;
     procedure InsertBreakpoints;
     procedure RemoveBreakpoints;
+    procedure ResetBreakpointsValues;
     procedure DoDebuggerScreen;virtual;
     procedure DoUserScreen;virtual;
     procedure Reset;virtual;
@@ -52,7 +54,9 @@ type
      typ  : BreakpointType;
      state : BreakpointState;
      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 }
      Conditions : PString; { conditions relative to that breakpoint }
      IgnoreCount : Longint; { how many counts should be ignored }
@@ -61,34 +65,46 @@ type
      GDBState : BreakpointState;
      constructor Init_function(Const AFunc : String);
      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  Remove;
      procedure  Enable;
      procedure  Disable;
+     procedure  ResetValues;
      destructor Done;virtual;
   end;
 
   TBreakpointCollection=object(TCollection)
       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;
       procedure Update;
       procedure FreeItem(Item: Pointer); virtual;
+      procedure ShowBreakpoints(W : PSourceWindow);
     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
   Debugger : PDebugController;
   BreakpointCollection : PBreakpointCollection;
   
 procedure InitDebugger;
 procedure DoneDebugger;
+procedure InitBreakpoints;
+procedure DoneBreakpoints;
 
 implementation
 
 uses
   Dos,Mouse,Video,
   App,Strings,
-  FPViews,FPVars,FPUtils,FPConst,
+  FPVars,FPUtils,FPConst,
   FPIntf,FPCompile,FPIde;
 
 
@@ -127,6 +143,15 @@ begin
    BreakpointCollection^.ForEach(@DoDelete);
 end;
 
+procedure TDebugController.ResetBreakpointsValues;
+  procedure DoResetVal(PB : PBreakpoint);
+    begin
+      PB^.ResetValues;
+    end;
+begin
+   BreakpointCollection^.ForEach(@DoResetVal);
+end;
+
 destructor TDebugController.Done;
 begin
   { kill the program if running }
@@ -137,6 +162,7 @@ end;
 
 procedure TDebugController.Run;
 begin
+  ResetBreakpointsValues;
   inherited Run;
   MyApp.SetCmdState([cmResetDebugger],true);
 end;
@@ -174,8 +200,11 @@ procedure TDebugController.DoSelectSourceLine(const fn:string;line:longint);
 var
   W: PSourceWindow;
   Found : boolean;
-  
+  PB : PBreakpoint;
+  S : String;
+  BreakIndex : longint;
 begin
+  BreakIndex:=stop_breakpoint_number;
   Desktop^.Lock;
   if Line>0 then
     dec(Line);
@@ -229,6 +258,36 @@ begin
     end;
   LastFileName:=fn;
   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;
 
 procedure TDebugController.DoEndSession(code:longint);
@@ -274,20 +333,26 @@ begin
   state:=bs_enabled;
   GDBState:=bs_deleted;
   Name:=NewStr(AFunc);
+  FileName:=nil;
+  Line:=0;
   IgnoreCount:=0;
   Commands:=nil;
   Conditions:=nil;
+  OldValue:=nil;
+  CurrentValue:=nil;
 end;
 
-constructor TBreakpoint.Init_type(atyp : BreakpointType;Const AFunc : String);
+constructor TBreakpoint.Init_type(atyp : BreakpointType;Const AnExpr : String);
 begin
   typ:=atyp;
   state:=bs_enabled;
   GDBState:=bs_deleted;
-  Name:=NewStr(AFunc);
+  Name:=NewStr(AnExpr);
   IgnoreCount:=0;
   Commands:=nil;
   Conditions:=nil;
+  OldValue:=nil;
+  CurrentValue:=nil;
 end;
 
 constructor TBreakpoint.Init_file_line(AFile : String; ALine : longint);
@@ -295,17 +360,19 @@ begin
   typ:=bt_file_line;
   state:=bs_enabled;
   GDBState:=bs_deleted;
-  AFile:=NameAndExtOf(AFile);
   { d:test.pas:12 does not work !! }
   { I do not know how to solve this if
   if (Length(AFile)>1) and (AFile[2]=':') then
     AFile:=Copy(AFile,3,255);
     Only use base name for now !! PM }
-  Name:=NewStr(AFile);
+  FileName:=NewStr(AFile);
+  Name:=nil;
   Line:=ALine;
   IgnoreCount:=0;
   Commands:=nil;
   Conditions:=nil;
+  OldValue:=nil;
+  CurrentValue:=nil;
 end;
 
 procedure TBreakpoint.Insert;
@@ -316,7 +383,7 @@ begin
   if (GDBState=bs_deleted) and (state=bs_enabled) then
     begin
       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
         Debugger^.Command('break '+name^)
       else if typ=bt_watch then
@@ -340,6 +407,8 @@ begin
       { Here there was a problem !! }
         begin
           GDBIndex:=0;
+          ErrorBox(#3'Could not set Breakpoint'#13+
+            #3+BreakpointTypeStr[typ]+' '+Name^,nil);
           state:=bs_disabled;
         end;
     end
@@ -362,7 +431,9 @@ procedure TBreakpoint.Enable;
 begin
   If not assigned(Debugger) then Exit;
   if GDBIndex>0 then
-    Debugger^.Command('enable '+IntToStr(GDBIndex));
+    Debugger^.Command('enable '+IntToStr(GDBIndex))
+  else
+    Insert;
   GDBState:=bs_enabled;
 end;
 
@@ -374,11 +445,24 @@ begin
   GDBState:=bs_disabled;
 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;
 begin
   Remove;
+  ResetValues;
   if assigned(Name) then
     DisposeStr(Name);
+  if assigned(FileName) then
+    DisposeStr(FileName);
   if assigned(Conditions) then
     DisposeStr(Conditions);
   if assigned(Commands) then
@@ -410,13 +494,50 @@ begin
     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;
 
 var PB : PBreakpoint;
 
   function IsThere(P : PBreakpoint) : boolean;
   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;
 begin
     PB:=FirstThat(@IsThere);
@@ -477,13 +598,27 @@ begin
   Use_gdb_file:=false;
 end;
 
+procedure InitBreakpoints;
 begin
   New(BreakpointCollection,init(10,10));
+end;
+
+procedure DoneBreakpoints;
+begin
+  Dispose(BreakpointCollection,Done);
+  BreakpointCollection:=nil;
+end;
+
 end.
 
 {
   $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
     + added DoContToCursor(F4)
     * Breakpoints are now inserted correctly (was mainlyy a problem