+ Published OnClick for TMenuItem
  + Published PopupMenu property for TEdit and TMemo (Doesn't work yet)
  * Fixed debugger running twice
  + Added Debugger output form
  * Enabled breakpoints

git-svn-id: trunk@1450 -
This commit is contained in:
lazarus 2002-02-20 23:33:24 +00:00
parent fc555077c1
commit 721fce0aee
12 changed files with 827 additions and 669 deletions

2
.gitattributes vendored
View File

@ -58,9 +58,7 @@ components/synedit/synhighlighterxml.pas svneol=native#text/pascal
components/synedit/syntextdrawer.pp svneol=native#text/pascal components/synedit/syntextdrawer.pp svneol=native#text/pascal
debugger/breakpointsdlg.pp svneol=native#text/pascal debugger/breakpointsdlg.pp svneol=native#text/pascal
debugger/cmdlinedebugger.pp svneol=native#text/pascal debugger/cmdlinedebugger.pp svneol=native#text/pascal
debugger/dbgbreakpoint.pp svneol=native#text/pascal
debugger/dbgoutputform.pp svneol=native#text/pascal debugger/dbgoutputform.pp svneol=native#text/pascal
debugger/dbgwatch.pp svneol=native#text/pascal
debugger/debugger.pp svneol=native#text/pascal debugger/debugger.pp svneol=native#text/pascal
debugger/gdbdebugger.pp svneol=native#text/pascal debugger/gdbdebugger.pp svneol=native#text/pascal
debugger/gdbmidebugger.pp svneol=native#text/pascal debugger/gdbmidebugger.pp svneol=native#text/pascal

View File

@ -287,7 +287,7 @@ var
WaitSet: Integer; WaitSet: Integer;
Idx, Count: Integer; Idx, Count: Integer;
begin begin
WriteLN('[TCmdLineDebugger.GetOutput] Enter'); // WriteLN('[TCmdLineDebugger.GetOutput] Enter');
if (FTargetProcess = nil) if (FTargetProcess = nil)
then OutHandle := 0 then OutHandle := 0
@ -343,11 +343,13 @@ begin
end; end;
until OutputBuf = WaitPrompt; until OutputBuf = WaitPrompt;
WriteLN('[TCmdLineDebugger.GetOutput] Leave'); // WriteLN('[TCmdLineDebugger.GetOutput] Leave');
end; end;
procedure TCmdLineDebugger.KillTargetProcess; procedure TCmdLineDebugger.KillTargetProcess;
begin begin
if FTargetProcess = nil then Exit;
FTargetProcess.Terminate(0); FTargetProcess.Terminate(0);
FTargetProcess.WaitOnExit; FTargetProcess.WaitOnExit;
try try
@ -364,7 +366,7 @@ const
begin begin
if FDbgProcess <> nil if FDbgProcess <> nil
then begin then begin
WriteLN(Format('[TCmdLineDebugger.SendCmd] CMD: <%s>', [ACommand])); // WriteLN(Format('[TCmdLineDebugger.SendCmd] CMD: <%s>', [ACommand]));
DoDbgOutput('<' + ACommand + '>'); DoDbgOutput('<' + ACommand + '>');
if ACommand <> '' if ACommand <> ''
then FDbgProcess.Input.Write(ACommand[1], Length(ACommand)); then FDbgProcess.Input.Write(ACommand[1], Length(ACommand));
@ -387,6 +389,14 @@ end;
end. end.
{ ============================================================================= { =============================================================================
$Log$ $Log$
Revision 1.6 2002/02/20 23:33:23 lazarus
MWE:
+ Published OnClick for TMenuItem
+ Published PopupMenu property for TEdit and TMemo (Doesn't work yet)
* Fixed debugger running twice
+ Added Debugger output form
* Enabled breakpoints
Revision 1.5 2002/02/06 08:58:29 lazarus Revision 1.5 2002/02/06 08:58:29 lazarus
MG: fixed compiler warnings and asking to create non existing files MG: fixed compiler warnings and asking to create non existing files

View File

@ -1,400 +0,0 @@
{ $Id$ }
{ ---------------------------------------
DBGBreakpoint.pp - Breakpoint classes
---------------------------------------
@created(Wed Feb 25st WET 2001)
@lastmod($Date$)
@author(Marc Weustink <marc@@dommelstein.net>)
This unit contains the class definitions of the
Breakpoints used by the debugger
/***************************************************************************
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
***************************************************************************/
}
unit DBGBreakpoint;
{$mode objfpc}{$H+}
interface
uses
Classes;
type
TDBGBreakPointActions = (bpaStop, bpaEnableGroup, bpaDisableGroup);
TDBGBreakPointGroup = class;
TDBGBreakPointClass = class of TDBGBreakPoint;
TDBGBreakPoint = class(TCollectionItem)
private
FDebugger: TObject; // reference to our debugger
FGroup: TDBGBreakPointGroup;
FValid: Boolean;
FEnabled: Boolean;
FHitCount: Integer;
FExpression: String;
FSource: String;
FLine: Integer;
FActions: TDBGBreakPointActions;
procedure SetActions(const AValue: TDBGBreakPointActions);
procedure SetEnabled(const AValue: Boolean);
procedure SetExpression(const AValue: String);
procedure SetGroup(const AValue: TDBGBreakPointGroup);
protected
procedure AssignTo(Dest: TPersistent); override;
procedure DoActionChange; virtual;
procedure DoEnableChange; virtual;
procedure DoExpressionChange; virtual;
procedure DoStateChange; virtual;
procedure SetHitCount(const AValue: Integer);
procedure SetLocation(const ASource: String; const ALine: Integer); virtual;
procedure SetValid(const AValue: Boolean);
property Debugger: TObject read FDebugger;
public
procedure AddDisableGroup(const AGroup: TDBGBreakPointGroup);
procedure AddEnableGroup(const AGroup: TDBGBreakPointGroup);
constructor Create(ACollection: TCollection); override;
procedure RemoveDisableGroup(const AGroup: TDBGBreakPointGroup);
procedure RemoveEnableGroup(const AGroup: TDBGBreakPointGroup);
property Actions: TDBGBreakPointActions read FActions write SetActions;
property Enabled: Boolean read FEnabled write SetEnabled;
property Group: TDBGBreakPointGroup read FGroup write SetGroup;
property HitCount: Integer read FHitCount;
property Expression: String read FExpression write SetExpression;
property Source: String read FSource;
property Line: Integer read FLine;
property Valid: Boolean read FValid;
end;
TDBGBreakPoints = class(TCollection)
private
FDebugger: TObject; // reference to our debugger
function GetItem(const AnIndex: Integer): TDBGBreakPoint;
procedure SetItem(const AnIndex: Integer; const AValue: TDBGBreakPoint);
protected
procedure DoStateChange;
public
constructor Create(const ADebugger: TObject; const ABreakPointClass: TDBGBreakPointClass);
function Add(const ASource: String; const ALine: Integer): TDBGBreakPoint;
function Find(const ASource: String; const ALine: Integer): TDBGBreakPoint;
property Items[const AnIndex: Integer]: TDBGBreakPoint read GetItem write SetItem; default;
end;
TDBGBreakPointGroup = class(TCollectionItem)
private
FEnabled: Boolean;
FName: String;
FBreakpoints: TList;
function GetBreakpoint(const AIndex: Integer): TDBGBreakPoint;
procedure SetEnabled(const AValue: Boolean);
procedure SetName(const AValue: String);
protected
public
function Add(const ABreakPoint: TDBGBreakPoint): Integer;
function Count: Integer;
constructor Create(ACollection: TCollection); override;
procedure Delete(const AIndex: Integer);
destructor Destroy; override;
function Remove(const ABreakPoint: TDBGBreakPoint): Integer;
property Breakpoints[const AIndex: Integer]: TDBGBreakPoint read GetBreakpoint;
property Enabled: Boolean read FEnabled write SetEnabled;
property Name: String read FName write SetName;
end;
TDBGBreakPointGroups = class(TCollection)
private
function GetItem(const AnIndex: Integer): TDBGBreakPointGroup;
procedure SetItem(const AnIndex: Integer; const AValue: TDBGBreakPointGroup);
protected
public
constructor Create;
property Items[const AnIndex: Integer]: TDBGBreakPointGroup read GetItem write SetItem; default;
end;
implementation
uses
Debugger;
{ TDBGBreakPoint }
procedure TDBGBreakPoint.AddDisableGroup(const AGroup: TDBGBreakPointGroup);
begin
end;
procedure TDBGBreakPoint.AddEnableGroup(const AGroup: TDBGBreakPointGroup);
begin
end;
procedure TDBGBreakPoint.AssignTo(Dest: TPersistent);
begin
if Dest is TDBGBreakPoint
then begin
TDBGBreakPoint(Dest).SetLocation(FSource, FLine);
TDBGBreakPoint(Dest).SetExpression(FExpression);
TDBGBreakPoint(Dest).SetActions(FActions);
TDBGBreakPoint(Dest).SetEnabled(FEnabled);
end
else inherited;
end;
constructor TDBGBreakPoint.Create(ACollection: TCollection);
begin
inherited Create(ACollection);
FSource := '';
FLine := -1;
FValid := False;
FEnabled := False;
FHitCount := 0;
FExpression := '';
FGroup := nil;
FDebugger := TDBGBreakPoints(ACollection).FDebugger;
end;
procedure TDBGBreakPoint.DoActionChange;
begin
end;
procedure TDBGBreakPoint.DoEnableChange;
begin
end;
procedure TDBGBreakPoint.DoExpressionChange;
begin
end;
procedure TDBGBreakPoint.DoStateChange;
begin
end;
procedure TDBGBreakPoint.RemoveDisableGroup(const AGroup: TDBGBreakPointGroup);
begin
end;
procedure TDBGBreakPoint.RemoveEnableGroup(const AGroup: TDBGBreakPointGroup);
begin
end;
procedure TDBGBreakPoint.SetActions(const AValue: TDBGBreakPointActions);
begin
if FActions <> AValue
then begin
FActions := AValue;
DoActionChange;
end;
end;
procedure TDBGBreakPoint.SetEnabled(const AValue: Boolean);
begin
if FEnabled <> AValue
then begin
FEnabled := AValue;
DoEnableChange;
end;
end;
procedure TDBGBreakPoint.SetExpression(const AValue: String);
begin
if FExpression <> AValue
then begin
FExpression := AValue;
DoExpressionChange;
end;
end;
procedure TDBGBreakPoint.SetGroup(const AValue: TDBGBreakPointGroup);
var
Grp: TDBGBreakPointGroup;
begin
if FGroup <> AValue
then begin
if FGroup <> nil
then begin
Grp := FGroup;
FGroup := nil; // avoid second entrance
Grp.Remove(Self);
end;
FGroup := AValue;
if FGroup <> nil
then begin
FGroup.Add(Self);
end;
end;
end;
procedure TDBGBreakPoint.SetHitCount(const AValue: Integer);
begin
FHitCount := AValue;
end;
procedure TDBGBreakPoint.SetLocation(const ASource: String; const ALine: Integer);
begin
FSource := ASource;
FLine := ALine;
end;
procedure TDBGBreakPoint.SetValid(const AValue: Boolean);
begin
FValid := AValue;
end;
{ TDBGBreakPoints }
function TDBGBreakPoints.Add(const ASource: String; const ALine: Integer): TDBGBreakPoint;
begin
Result := TDBGBreakPoint(inherited Add);
Result.SetLocation(ASource, ALine);
end;
constructor TDBGBreakPoints.Create(const ADebugger: TObject; const ABreakPointClass: TDBGBreakPointClass);
begin
inherited Create(ABreakPointClass);
FDebugger := ADebugger;
end;
procedure TDBGBreakPoints.DoStateChange;
var
n: Integer;
begin
for n := 0 to Count - 1 do
GetItem(n).DoStateChange;
end;
function TDBGBreakPoints.Find(const ASource: String; const ALine: Integer): TDBGBreakPoint;
var
n: Integer;
begin
for n := 0 to Count - 1 do
begin
Result := GetItem(n);
if (Result.Line = ALine)
and (Result.Source = ASource)
then Exit;
end;
Result := nil;
end;
function TDBGBreakPoints.GetItem(const AnIndex: Integer): TDBGBreakPoint;
begin
Result := TDBGBreakPoint(inherited GetItem(AnIndex));
end;
procedure TDBGBreakPoints.SetItem(const AnIndex: Integer; const AValue: TDBGBreakPoint);
begin
SetItem(AnIndex, AValue);
end;
{ TDBGBreakPointGroup }
function TDBGBreakPointGroup.Add(const ABreakPoint: TDBGBreakPoint): Integer;
begin
Result := FBreakpoints.IndexOf(ABreakPoint); //avoid dups
if Result = -1
then begin
Result := FBreakpoints.Add(ABreakPoint);
ABreakpoint.Group := Self;
end;
end;
function TDBGBreakPointGroup.Count: Integer;
begin
Result := FBreakpoints.Count;
end;
constructor TDBGBreakPointGroup.Create(ACollection: TCollection);
begin
inherited Create(ACollection);
FBreakpoints := TList.Create;
FEnabled := True;
end;
procedure TDBGBreakPointGroup.Delete(const AIndex: Integer);
begin
Remove(TDBGBreakPoint(FBreakPoints[AIndex]));
end;
destructor TDBGBreakPointGroup.Destroy;
begin
FBreakpoints.Free;
inherited Destroy;
end;
function TDBGBreakPointGroup.GetBreakpoint(const AIndex: Integer): TDBGBreakPoint;
begin
Result := TDBGBreakPoint(FBreakPoints[AIndex]);
end;
function TDBGBreakPointGroup.Remove(const ABreakPoint: TDBGBreakPoint): Integer;
begin
Result := FBreakpoints.Remove(ABreakPoint);
if ABreakpoint.Group = Self
then ABreakpoint.Group := nil;
end;
procedure TDBGBreakPointGroup.SetEnabled(const AValue: Boolean);
var
n: Integer;
begin
if FEnabled <> AValue
then begin
FEnabled := AValue;
for n := 0 to FBreakPoints.Count - 1 do
TDBGBreakpoint(FBreakPoints[n]).Enabled := FEnabled;
end;
end;
procedure TDBGBreakPointGroup.SetName(const AValue: String);
begin
FName := AValue;
end;
{ TDBGBreakPointGroups }
constructor TDBGBreakPointGroups.Create;
begin
inherited Create(TDBGBreakPointGroup);
end;
function TDBGBreakPointGroups.GetItem(const AnIndex: Integer): TDBGBreakPointGroup;
begin
Result := TDBGBreakPointGroup(inherited GetItem(AnIndex));
end;
procedure TDBGBreakPointGroups.SetItem(const AnIndex: Integer; const AValue: TDBGBreakPointGroup);
begin
inherited SetItem(AnIndex, AValue);
end;
end.
{ =============================================================================
$Log$
Revision 1.6 2002/02/05 23:16:48 lazarus
MWE: * Updated tebugger
+ Added debugger to IDE
Revision 1.5 2001/11/06 23:59:12 lazarus
MWE: + Initial breakpoint support
+ Added exeption handling on process.free
Revision 1.4 2001/11/05 00:12:51 lazarus
MWE: First steps of a debugger.
Revision 1.3 2001/10/18 13:01:31 lazarus
MG: fixed speedbuttons numglyphs>1 and started IDE debugging
Revision 1.2 2001/02/25 16:44:57 lazarus
MWE:
+ Added header and footer
}

View File

@ -1,7 +1,9 @@
LazarusResources.Add('TDbgOutputForm','FORMDATA', LazarusResources.Add('TDbgOutputForm','FORMDATA',
'TPF0'#14'TDbgOutputForm'#14'DbgOutputForm1'#7'CAPTION'#6#12'Debug output' 'TPF0'#14'TDbgOutputForm'#14'DbgOutputForm1'#7'CAPTION'#6#12'Debug output'
+#8'OnCreate'#7#10'FormCreate'#9'OnDestroy'#7#11'FormDestroy'#3'TOP'#2#10#4 +#7'OnClose'#7#9'FormClose'#8'OnCreate'#7#10'FormCreate'#9'OnDestroy'#7#11
+'LEFT'#2#10#6'HEIGHT'#3#150#0#5'WIDTH'#3'-'#1#0#5'TMemo'#9'txtOutput'#4'L' +'FormDestroy'#3'TOP'#2#10#4'LEFT'#2#10#6'HEIGHT'#3#200#0#5'WIDTH'#3#144#1
+'eft'#2#8#3'Top'#2'h'#5'Width'#3'X'#2#6'Height'#3#150#0#5'Align'#7#8'alCl' +#0#5'TMemo'#9'txtOutput'#4'Left'#2#8#3'Top'#2'h'#5'Width'#3'X'#2#6'Height'
+'ient'#0#0#0 +#3#150#0#5'Align'#7#8'alClient'#9'PopupMenu'#7#8'mnuPopup'#0#0#10'TPopupM'
+'enu'#8'mnuPopup'#4'Left'#3#144#1#3'Top'#2'`'#0#9'TMenuItem'#8'popClear'#7
+'Caption'#6#6'&Clear'#7'OnClick'#7#13'popClearClick'#0#0#0#0
); );

View File

@ -25,18 +25,23 @@ interface
uses uses
Classes, Graphics, Controls, Forms, Dialogs, LResources, Classes, Graphics, Controls, Forms, Dialogs, LResources,
Buttons, StdCtrls, Debugger; Buttons, StdCtrls, Menus;
type type
TDbgOutputForm = class(TForm) TDbgOutputForm = class(TForm)
txtOutput: TMemo; txtOutput: TMemo;
mnuPopup: TPopupMenu;
popClear: TMenuItem;
procedure FormClose(Sender: TObject; var Action: TCloseAction);
procedure FormCreate(Sender: TObject); procedure FormCreate(Sender: TObject);
procedure FormDestroy(Sender: TObject); procedure FormDestroy(Sender: TObject);
procedure popClearClick(Sender: TObject);
private private
protected protected
procedure Loaded; override; procedure Loaded; override;
public public
procedure AddText(const AText: String); procedure AddText(const AText: String);
procedure Clear;
end; end;
implementation implementation
@ -46,6 +51,16 @@ begin
txtOutput.Lines.Add(AText); txtOutput.Lines.Add(AText);
end; end;
procedure TDbgOutputForm.Clear;
begin
txtOutput.Lines.Clear;
end;
procedure TDbgOutputForm.FormClose(Sender: TObject; var Action: TCloseAction);
begin
Action := caFree;
end;
procedure TDbgOutputForm.FormCreate(Sender: TObject); procedure TDbgOutputForm.FormCreate(Sender: TObject);
begin begin
txtOutput.Lines.Clear; txtOutput.Lines.Clear;
@ -63,12 +78,25 @@ begin
txtOutput.Scrollbars := ssBoth; txtOutput.Scrollbars := ssBoth;
end; end;
procedure TDbgOutputForm.popClearClick(Sender: TObject);
begin
Clear;
end;
initialization initialization
{$I dbgoutputform.lrc} {$I dbgoutputform.lrc}
end. end.
{ ============================================================================= { =============================================================================
$Log$ $Log$
Revision 1.2 2002/02/20 23:33:24 lazarus
MWE:
+ Published OnClick for TMenuItem
+ Published PopupMenu property for TEdit and TMemo (Doesn't work yet)
* Fixed debugger running twice
+ Added Debugger output form
* Enabled breakpoints
Revision 1.1 2001/11/05 00:12:51 lazarus Revision 1.1 2001/11/05 00:12:51 lazarus
MWE: First steps of a debugger. MWE: First steps of a debugger.

View File

@ -1,171 +0,0 @@
{ $Id$ }
{ -----------------------------------
DBGWatch.pp - Debug Watch classes
-----------------------------------
@created(Wed Feb 25st WET 2001)
@lastmod($Date$)
@author(Marc Weustink <marc@@dommelstein.net>)
This unit contains the class definitions of the
Watches used by the debugger
/***************************************************************************
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
***************************************************************************/
}
unit DBGWatch;
{$mode objfpc}{$H+}
interface
uses
Classes;
type
TDBGWatchClass = class of TDBGWatch;
TDBGWatch = class(TCollectionItem)
private
FDebugger: TObject; // reference to our debugger
FEnabled: Boolean;
FExpression: String;
//FValue: String;
FOnChange: TNotifyEvent;
procedure SetEnabled(const AValue: Boolean);
protected
procedure DoEnableChange; virtual;
procedure DoStateChange; virtual;
function GetValue: String; virtual;
function GetValid: Boolean; virtual;
procedure SetExpression(const AValue: String); virtual;
procedure SetValue(const AValue: String); virtual;
property Debugger: TObject read FDebugger;
public
constructor Create(ACollection: TCollection); override;
property Enabled: Boolean read FEnabled write SetEnabled;
property Expression: String read FExpression write SetExpression;
property Valid: Boolean read GetValid;
property Value: String read GetValue write SetValue;
property OnChange: TNotifyEvent read FOnChange write FOnChange;
end;
TDBGWatches = class(TCollection)
private
FDebugger: TObject; // reference to our debugger
function GetItem(const AnIndex: Integer): TDBGWatch;
procedure SetItem(const AnIndex: Integer; const AValue: TDBGWatch);
protected
procedure DoStateChange;
public
constructor Create(const ADebugger: TObject; const AWatchClass: TDBGWatchClass);
property Items[const AnIndex: Integer]: TDBGWatch read GetItem write SetItem; default;
end;
implementation
uses
Debugger;
{ TDBGWatch }
constructor TDBGWatch.Create(ACollection: TCollection);
begin
inherited Create(ACollection);
FEnabled := False;
FDebugger := TDBGWatches(ACollection).FDebugger;
end;
procedure TDBGWatch.DoEnableChange;
begin
end;
procedure TDBGWatch.DoStateChange;
begin
end;
function TDBGWatch.GetValid: Boolean;
begin
Result := False;
end;
function TDBGWatch.GetValue: String;
begin
if Valid
then Result := '<unknown>'
else Result := '<invalid>';
end;
procedure TDBGWatch.SetEnabled(const AValue: Boolean);
begin
if FEnabled <> AValue
then begin
FEnabled := AValue;
DoEnableChange;
end;
end;
procedure TDBGWatch.SetExpression(const AValue: String);
begin
end;
procedure TDBGWatch.SetValue(const AValue: String);
begin
end;
{ TDBGWatches }
constructor TDBGWatches.Create(const ADebugger: TObject; const AWatchClass: TDBGWatchClass);
begin
FDebugger := ADebugger;
inherited Create(AWatchClass);
end;
procedure TDBGWatches.DoStateChange;
var
n: Integer;
begin
for n := 0 to Count - 1 do
GetItem(n).DoStateChange;
end;
function TDBGWatches.GetItem(const AnIndex: Integer): TDBGWatch;
begin
Result := TDBGWatch(inherited GetItem(AnIndex));
end;
procedure TDBGWatches.SetItem(const AnIndex: Integer; const AValue: TDBGWatch);
begin
inherited SetItem(AnIndex, AValue);
end;
end.
{ =============================================================================
$Log$
Revision 1.7 2002/02/06 08:58:29 lazarus
MG: fixed compiler warnings and asking to create non existing files
Revision 1.6 2002/02/05 23:16:48 lazarus
MWE: * Updated tebugger
+ Added debugger to IDE
Revision 1.5 2001/11/06 23:59:13 lazarus
MWE: + Initial breakpoint support
+ Added exeption handling on process.free
Revision 1.4 2001/11/05 00:12:51 lazarus
MWE: First steps of a debugger.
Revision 1.3 2001/10/18 13:01:31 lazarus
MG: fixed speedbuttons numglyphs>1 and started IDE debugging
Revision 1.2 2001/02/25 16:44:57 lazarus
MWE:
+ Added header and footer
}

View File

@ -27,7 +27,7 @@ unit Debugger;
interface interface
uses uses
Classes, DBGWatch, DBGBreakpoint; Classes;
type type
TDBGLocationRec = record TDBGLocationRec = record
@ -72,8 +72,141 @@ type
*) *)
TDBGBreakPointAction = (bpaStop, bpaEnableGroup, bpaDisableGroup);
TDBGBreakPointActions =set of TDBGBreakPointAction;
TDebugger = class;
TDBGBreakPointGroup = class;
TDBGBreakPointClass = class of TDBGBreakPoint;
TDBGBreakPoint = class(TCollectionItem)
private
FDebugger: TDebugger; // reference to our debugger
FGroup: TDBGBreakPointGroup;
FValid: Boolean;
FEnabled: Boolean;
FHitCount: Integer;
FExpression: String;
FSource: String;
FLine: Integer;
FFirstRun: Boolean;
FActions: TDBGBreakPointActions;
procedure SetActions(const AValue: TDBGBreakPointActions);
procedure SetEnabled(const AValue: Boolean);
procedure SetExpression(const AValue: String);
procedure SetGroup(const AValue: TDBGBreakPointGroup);
protected
procedure AssignTo(Dest: TPersistent); override;
procedure DoActionChange; virtual;
procedure DoEnableChange; virtual;
procedure DoExpressionChange; virtual;
procedure DoStateChange; virtual;
procedure SetHitCount(const AValue: Integer);
procedure SetLocation(const ASource: String; const ALine: Integer); virtual;
procedure SetValid(const AValue: Boolean);
property Debugger: TDebugger read FDebugger;
public
procedure AddDisableGroup(const AGroup: TDBGBreakPointGroup);
procedure AddEnableGroup(const AGroup: TDBGBreakPointGroup);
constructor Create(ACollection: TCollection); override;
procedure RemoveDisableGroup(const AGroup: TDBGBreakPointGroup);
procedure RemoveEnableGroup(const AGroup: TDBGBreakPointGroup);
property Actions: TDBGBreakPointActions read FActions write SetActions;
property Enabled: Boolean read FEnabled write SetEnabled;
property Group: TDBGBreakPointGroup read FGroup write SetGroup;
property HitCount: Integer read FHitCount;
property Expression: String read FExpression write SetExpression;
property Source: String read FSource;
property Line: Integer read FLine;
property Valid: Boolean read FValid;
end;
TDBGBreakPoints = class(TCollection)
private
FDebugger: TDebugger; // reference to our debugger
function GetItem(const AnIndex: Integer): TDBGBreakPoint;
procedure SetItem(const AnIndex: Integer; const AValue: TDBGBreakPoint);
protected
procedure DoStateChange;
public
constructor Create(const ADebugger: TDebugger; const ABreakPointClass: TDBGBreakPointClass);
function Add(const ASource: String; const ALine: Integer): TDBGBreakPoint;
function Find(const ASource: String; const ALine: Integer): TDBGBreakPoint;
property Items[const AnIndex: Integer]: TDBGBreakPoint read GetItem write SetItem; default;
end;
TDBGBreakPointGroup = class(TCollectionItem)
private
FEnabled: Boolean;
FName: String;
FBreakpoints: TList;
function GetBreakpoint(const AIndex: Integer): TDBGBreakPoint;
procedure SetEnabled(const AValue: Boolean);
procedure SetName(const AValue: String);
protected
public
function Add(const ABreakPoint: TDBGBreakPoint): Integer;
function Count: Integer;
constructor Create(ACollection: TCollection); override;
procedure Delete(const AIndex: Integer);
destructor Destroy; override;
function Remove(const ABreakPoint: TDBGBreakPoint): Integer;
property Breakpoints[const AIndex: Integer]: TDBGBreakPoint read GetBreakpoint;
property Enabled: Boolean read FEnabled write SetEnabled;
property Name: String read FName write SetName;
end;
TDBGBreakPointGroups = class(TCollection)
private
function GetItem(const AnIndex: Integer): TDBGBreakPointGroup;
procedure SetItem(const AnIndex: Integer; const AValue: TDBGBreakPointGroup);
protected
public
constructor Create;
property Items[const AnIndex: Integer]: TDBGBreakPointGroup read GetItem write SetItem; default;
end;
TDBGWatchClass = class of TDBGWatch;
TDBGWatch = class(TCollectionItem)
private
FDebugger: TDebugger; // reference to our debugger
FEnabled: Boolean;
FExpression: String;
//FValue: String;
FOnChange: TNotifyEvent;
procedure SetEnabled(const AValue: Boolean);
protected
procedure DoEnableChange; virtual;
procedure DoStateChange; virtual;
function GetValue: String; virtual;
function GetValid: Boolean; virtual;
procedure SetExpression(const AValue: String); virtual;
procedure SetValue(const AValue: String); virtual;
property Debugger: TDebugger read FDebugger;
public
constructor Create(ACollection: TCollection); override;
property Enabled: Boolean read FEnabled write SetEnabled;
property Expression: String read FExpression write SetExpression;
property Valid: Boolean read GetValid;
property Value: String read GetValue write SetValue;
property OnChange: TNotifyEvent read FOnChange write FOnChange;
end;
TDBGWatches = class(TCollection)
private
FDebugger: TDebugger; // reference to our debugger
function GetItem(const AnIndex: Integer): TDBGWatch;
procedure SetItem(const AnIndex: Integer; const AValue: TDBGWatch);
protected
procedure DoStateChange;
public
constructor Create(const ADebugger: TDebugger; const AWatchClass: TDBGWatchClass);
property Items[const AnIndex: Integer]: TDBGWatch read GetItem write SetItem; default;
end;
TDBGOutputEvent = procedure(Sender: TObject; const AText: String) of object; TDBGOutputEvent = procedure(Sender: TObject; const AText: String) of object;
TDBGCurrentLineEvent = procedure(Sender: TObject; const ALocation: TDBGLocationRec) of object; TDBGCurrentLineEvent = procedure(Sender: TObject; const ALocation: TDBGLocationRec) of object;
TDBGExceptionEvent = procedure(Sender: TObject; const AExceptionID: Integer; const AExceptionText: String) of object;
TDebugger = class(TObject) TDebugger = class(TObject)
private private
@ -84,6 +217,7 @@ type
FState: TDBGState; FState: TDBGState;
FWatches: TDBGWatches; FWatches: TDBGWatches;
FOnCurrent: TDBGCurrentLineEvent; FOnCurrent: TDBGCurrentLineEvent;
FOnException: TDBGExceptionEvent;
FOnOutput: TDBGOutputEvent; FOnOutput: TDBGOutputEvent;
FOnDbgOutput: TDBGOutputEvent; FOnDbgOutput: TDBGOutputEvent;
FOnState: TNotifyEvent; FOnState: TNotifyEvent;
@ -94,6 +228,7 @@ type
function CreateWatches: TDBGWatches; virtual; function CreateWatches: TDBGWatches; virtual;
procedure DoCurrent(const ALocation: TDBGLocationRec); procedure DoCurrent(const ALocation: TDBGLocationRec);
procedure DoDbgOutput(const AText: String); procedure DoDbgOutput(const AText: String);
procedure DoException(const AExceptionID: Integer; const AExceptionText: String);
procedure DoOutput(const AText: String); procedure DoOutput(const AText: String);
procedure DoState; procedure DoState;
function GetCommands: TDBGCommands; function GetCommands: TDBGCommands;
@ -103,6 +238,7 @@ type
procedure SetState(const AValue: TDBGState); procedure SetState(const AValue: TDBGState);
public public
constructor Create; {virtual; Virtual constructor makes no sense} constructor Create; {virtual; Virtual constructor makes no sense}
//MWE: there will be a day that they do make sense :-)
destructor Destroy; override; destructor Destroy; override;
procedure Init; virtual; // Initializes the debugger procedure Init; virtual; // Initializes the debugger
@ -120,9 +256,10 @@ type
property BreakPointGroups: TDBGBreakPointGroups read FBreakPointGroups; // list of all breakpointgroups property BreakPointGroups: TDBGBreakPointGroups read FBreakPointGroups; // list of all breakpointgroups
property Commands: TDBGCommands read GetCommands; // All current available commands of the debugger property Commands: TDBGCommands read GetCommands; // All current available commands of the debugger
property FileName: String read FFileName write SetFileName; // The name of the exe to be debugged property FileName: String read FFileName write SetFileName; // The name of the exe to be debugged
property State: TDBGState read FState; // The current stete of the debugger property State: TDBGState read FState; // The current state of the debugger
property Watches: TDBGWatches read FWatches; // list of all watches localvars etc property Watches: TDBGWatches read FWatches; // list of all watches localvars etc
property OnCurrent: TDBGCurrentLineEvent read FOnCurrent write FOnCurrent; // Passes info about the current line being debugged property OnCurrent: TDBGCurrentLineEvent read FOnCurrent write FOnCurrent; // Passes info about the current line being debugged
property OnException: TDBGExceptionEvent read FOnException write FOnException; // Fires when the debugger received an exeption
property OnState: TNotifyEvent read FOnState write FOnState; // Fires when the current state of the debugger changes property OnState: TNotifyEvent read FOnState write FOnState; // Fires when the current state of the debugger changes
property OnOutput: TDBGOutputEvent read FOnOutput write FOnOutput; // Passes all output of the debugged target property OnOutput: TDBGOutputEvent read FOnOutput write FOnOutput; // Passes all output of the debugged target
property OnDbgOutput: TDBGOutputEvent read FOnDbgOutput write FOnDbgOutput; // Passes all debuggeroutput property OnDbgOutput: TDBGOutputEvent read FOnDbgOutput write FOnDbgOutput; // Passes all debuggeroutput
@ -143,7 +280,9 @@ const
{dsError} [] {dsError} []
); );
{ =========================================================================== }
{ TDebugger } { TDebugger }
{ =========================================================================== }
constructor TDebugger.Create; constructor TDebugger.Create;
begin begin
@ -201,6 +340,11 @@ begin
if Assigned(FOnDbgOutput) then FOnDbgOutput(Self, AText); if Assigned(FOnDbgOutput) then FOnDbgOutput(Self, AText);
end; end;
procedure TDebugger.DoException(const AExceptionID: Integer; const AExceptionText: String);
begin
if Assigned(FOnException) then FOnException(Self, AExceptionID, AExceptionText);
end;
procedure TDebugger.DoOutput(const AText: String); procedure TDebugger.DoOutput(const AText: String);
begin begin
if Assigned(FOnOutput) then FOnOutput(Self, AText); if Assigned(FOnOutput) then FOnOutput(Self, AText);
@ -265,10 +409,13 @@ begin
then begin then begin
if FState in [dsRun, dsPause] if FState in [dsRun, dsPause]
then Stop; then Stop;
// Reset state
FFileName := '';
SetState(dsIdle);
FFileName := AValue; FFileName := AValue;
if FFilename = '' if FFilename <> ''
then SetState(dsIdle) then SetState(dsStop);
else SetState(dsStop);
end; end;
end; end;
@ -277,6 +424,8 @@ begin
if AValue <> FState if AValue <> FState
then begin then begin
FState := AValue; FState := AValue;
FBreakpoints.DoStateChange;
FWatches.DoStateChange;
DoState; DoState;
end; end;
end; end;
@ -296,9 +445,365 @@ begin
ReqCmd(dcStop, []); ReqCmd(dcStop, []);
end; end;
{ =========================================================================== }
{ TDBGBreakPoint }
{ =========================================================================== }
procedure TDBGBreakPoint.AddDisableGroup(const AGroup: TDBGBreakPointGroup);
begin
end;
procedure TDBGBreakPoint.AddEnableGroup(const AGroup: TDBGBreakPointGroup);
begin
end;
procedure TDBGBreakPoint.AssignTo(Dest: TPersistent);
begin
if Dest is TDBGBreakPoint
then begin
TDBGBreakPoint(Dest).SetLocation(FSource, FLine);
TDBGBreakPoint(Dest).SetExpression(FExpression);
TDBGBreakPoint(Dest).SetActions(FActions);
TDBGBreakPoint(Dest).SetEnabled(FEnabled);
end
else inherited;
end;
constructor TDBGBreakPoint.Create(ACollection: TCollection);
begin
inherited Create(ACollection);
FSource := '';
FLine := -1;
FValid := False;
FEnabled := False;
FHitCount := 0;
FExpression := '';
FGroup := nil;
FFirstRun := True;
FActions := [bpaStop];
FDebugger := TDBGBreakPoints(ACollection).FDebugger;
end;
procedure TDBGBreakPoint.DoActionChange;
begin
end;
procedure TDBGBreakPoint.DoEnableChange;
begin
end;
procedure TDBGBreakPoint.DoExpressionChange;
begin
end;
procedure TDBGBreakPoint.DoStateChange;
begin
case Debugger.State of
dsStop, dsIdle: begin
FFirstRun := True;
end;
dsRun: begin
if FFirstRun
then begin
FHitCount := 0;
FFirstRun := False;
end;
end;
end;
end;
procedure TDBGBreakPoint.RemoveDisableGroup(const AGroup: TDBGBreakPointGroup);
begin
end;
procedure TDBGBreakPoint.RemoveEnableGroup(const AGroup: TDBGBreakPointGroup);
begin
end;
procedure TDBGBreakPoint.SetActions(const AValue: TDBGBreakPointActions);
begin
if FActions <> AValue
then begin
FActions := AValue;
DoActionChange;
end;
end;
procedure TDBGBreakPoint.SetEnabled(const AValue: Boolean);
begin
if FEnabled <> AValue
then begin
FEnabled := AValue;
DoEnableChange;
end;
end;
procedure TDBGBreakPoint.SetExpression(const AValue: String);
begin
if FExpression <> AValue
then begin
FExpression := AValue;
DoExpressionChange;
end;
end;
procedure TDBGBreakPoint.SetGroup(const AValue: TDBGBreakPointGroup);
var
Grp: TDBGBreakPointGroup;
begin
if FGroup <> AValue
then begin
if FGroup <> nil
then begin
Grp := FGroup;
FGroup := nil; // avoid second entrance
Grp.Remove(Self);
end;
FGroup := AValue;
if FGroup <> nil
then begin
FGroup.Add(Self);
end;
end;
end;
procedure TDBGBreakPoint.SetHitCount(const AValue: Integer);
begin
FHitCount := AValue;
end;
procedure TDBGBreakPoint.SetLocation(const ASource: String; const ALine: Integer);
begin
FSource := ASource;
FLine := ALine;
end;
procedure TDBGBreakPoint.SetValid(const AValue: Boolean);
begin
FValid := AValue;
end;
{ =========================================================================== }
{ TDBGBreakPoints }
{ =========================================================================== }
function TDBGBreakPoints.Add(const ASource: String; const ALine: Integer): TDBGBreakPoint;
begin
Result := TDBGBreakPoint(inherited Add);
Result.SetLocation(ASource, ALine);
end;
constructor TDBGBreakPoints.Create(const ADebugger: TDebugger; const ABreakPointClass: TDBGBreakPointClass);
begin
inherited Create(ABreakPointClass);
FDebugger := ADebugger;
end;
procedure TDBGBreakPoints.DoStateChange;
var
n: Integer;
begin
for n := 0 to Count - 1 do
GetItem(n).DoStateChange;
end;
function TDBGBreakPoints.Find(const ASource: String; const ALine: Integer): TDBGBreakPoint;
var
n: Integer;
begin
for n := 0 to Count - 1 do
begin
Result := GetItem(n);
if (Result.Line = ALine)
and (Result.Source = ASource)
then Exit;
end;
Result := nil;
end;
function TDBGBreakPoints.GetItem(const AnIndex: Integer): TDBGBreakPoint;
begin
Result := TDBGBreakPoint(inherited GetItem(AnIndex));
end;
procedure TDBGBreakPoints.SetItem(const AnIndex: Integer; const AValue: TDBGBreakPoint);
begin
SetItem(AnIndex, AValue);
end;
{ =========================================================================== }
{ TDBGBreakPointGroup }
{ =========================================================================== }
function TDBGBreakPointGroup.Add(const ABreakPoint: TDBGBreakPoint): Integer;
begin
Result := FBreakpoints.IndexOf(ABreakPoint); //avoid dups
if Result = -1
then begin
Result := FBreakpoints.Add(ABreakPoint);
ABreakpoint.Group := Self;
end;
end;
function TDBGBreakPointGroup.Count: Integer;
begin
Result := FBreakpoints.Count;
end;
constructor TDBGBreakPointGroup.Create(ACollection: TCollection);
begin
inherited Create(ACollection);
FBreakpoints := TList.Create;
FEnabled := True;
end;
procedure TDBGBreakPointGroup.Delete(const AIndex: Integer);
begin
Remove(TDBGBreakPoint(FBreakPoints[AIndex]));
end;
destructor TDBGBreakPointGroup.Destroy;
begin
FBreakpoints.Free;
inherited Destroy;
end;
function TDBGBreakPointGroup.GetBreakpoint(const AIndex: Integer): TDBGBreakPoint;
begin
Result := TDBGBreakPoint(FBreakPoints[AIndex]);
end;
function TDBGBreakPointGroup.Remove(const ABreakPoint: TDBGBreakPoint): Integer;
begin
Result := FBreakpoints.Remove(ABreakPoint);
if ABreakpoint.Group = Self
then ABreakpoint.Group := nil;
end;
procedure TDBGBreakPointGroup.SetEnabled(const AValue: Boolean);
var
n: Integer;
begin
if FEnabled <> AValue
then begin
FEnabled := AValue;
for n := 0 to FBreakPoints.Count - 1 do
TDBGBreakpoint(FBreakPoints[n]).Enabled := FEnabled;
end;
end;
procedure TDBGBreakPointGroup.SetName(const AValue: String);
begin
FName := AValue;
end;
{ =========================================================================== }
{ TDBGBreakPointGroups }
{ =========================================================================== }
constructor TDBGBreakPointGroups.Create;
begin
inherited Create(TDBGBreakPointGroup);
end;
function TDBGBreakPointGroups.GetItem(const AnIndex: Integer): TDBGBreakPointGroup;
begin
Result := TDBGBreakPointGroup(inherited GetItem(AnIndex));
end;
procedure TDBGBreakPointGroups.SetItem(const AnIndex: Integer; const AValue: TDBGBreakPointGroup);
begin
inherited SetItem(AnIndex, AValue);
end;
{ =========================================================================== }
{ TDBGWatch }
{ =========================================================================== }
constructor TDBGWatch.Create(ACollection: TCollection);
begin
inherited Create(ACollection);
FEnabled := False;
FDebugger := TDBGWatches(ACollection).FDebugger;
end;
procedure TDBGWatch.DoEnableChange;
begin
end;
procedure TDBGWatch.DoStateChange;
begin
end;
function TDBGWatch.GetValid: Boolean;
begin
Result := False;
end;
function TDBGWatch.GetValue: String;
begin
if Valid
then Result := '<unknown>'
else Result := '<invalid>';
end;
procedure TDBGWatch.SetEnabled(const AValue: Boolean);
begin
if FEnabled <> AValue
then begin
FEnabled := AValue;
DoEnableChange;
end;
end;
procedure TDBGWatch.SetExpression(const AValue: String);
begin
end;
procedure TDBGWatch.SetValue(const AValue: String);
begin
end;
{ =========================================================================== }
{ TDBGWatches }
{ =========================================================================== }
constructor TDBGWatches.Create(const ADebugger: TDebugger; const AWatchClass: TDBGWatchClass);
begin
FDebugger := ADebugger;
inherited Create(AWatchClass);
end;
procedure TDBGWatches.DoStateChange;
var
n: Integer;
begin
for n := 0 to Count - 1 do
GetItem(n).DoStateChange;
end;
function TDBGWatches.GetItem(const AnIndex: Integer): TDBGWatch;
begin
Result := TDBGWatch(inherited GetItem(AnIndex));
end;
procedure TDBGWatches.SetItem(const AnIndex: Integer; const AValue: TDBGWatch);
begin
inherited SetItem(AnIndex, AValue);
end;
end. end.
{ ============================================================================= { =============================================================================
$Log$ $Log$
Revision 1.8 2002/02/20 23:33:24 lazarus
MWE:
+ Published OnClick for TMenuItem
+ Published PopupMenu property for TEdit and TMemo (Doesn't work yet)
* Fixed debugger running twice
+ Added Debugger output form
* Enabled breakpoints
Revision 1.7 2002/02/06 08:58:29 lazarus Revision 1.7 2002/02/06 08:58:29 lazarus
MG: fixed compiler warnings and asking to create non existing files MG: fixed compiler warnings and asking to create non existing files

View File

@ -28,13 +28,22 @@ unit GDBDebugger;
interface interface
uses uses
Classes, Process, Debugger, CmdLineDebugger, DBGBreakPoint, DBGWatch; Classes, Process, Debugger, CmdLineDebugger;
type type
TGDBProgramInfo = record
State: TDBGState;
BreakPoint: Integer; // ID of Breakpoint hit
Signal: Integer; // Signal no if we hit one
SignalText: String; // Signal text if we hit one
end;
TGDBDebugger = class(TCmdLineDebugger) TGDBDebugger = class(TCmdLineDebugger)
private private
FHasSymbols: Boolean; FHasSymbols: Boolean;
function FindBreakpoint(const ABreakpoint: Integer): TDBGBreakPoint;
procedure GDBRun; procedure GDBRun;
procedure GDBPause; procedure GDBPause;
procedure GDBStart; procedure GDBStart;
@ -46,7 +55,7 @@ type
function SendCommand(const ACommand: String; Values: array of const): TStrings; // internally used by breakpoits and watches function SendCommand(const ACommand: String; Values: array of const): TStrings; // internally used by breakpoits and watches
procedure RunCommand(const ACommand: String); procedure RunCommand(const ACommand: String);
function GetLocation: TDBGLocationRec; function GetLocation: TDBGLocationRec;
function GetGDBState: TDBGState; function GetProgramInfo(const AHandleResult: Boolean): TGDBProgramInfo;
protected protected
function CreateBreakPoints: TDBGBreakPoints; override; function CreateBreakPoints: TDBGBreakPoints; override;
function CreateWatches: TDBGWatches; override; function CreateWatches: TDBGWatches; override;
@ -73,14 +82,17 @@ type
TGDBBreakPoint = class(TDBGBreakPoint) TGDBBreakPoint = class(TDBGBreakPoint)
private private
FBreakID: Integer; FBreakID: Integer;
procedure SetBreakPoint;
protected protected
procedure DoActionChange; override; procedure DoActionChange; override;
procedure DoEnableChange; override; procedure DoEnableChange; override;
procedure DoExpressionChange; override; procedure DoExpressionChange; override;
procedure DoStateChange; override;
procedure SetLocation(const ASource: String; const ALine: Integer); override; procedure SetLocation(const ASource: String; const ALine: Integer); override;
public public
constructor Create(ACollection: TCollection); override; constructor Create(ACollection: TCollection); override;
destructor Destroy; override; destructor Destroy; override;
procedure Hit;
end; end;
TGDBWatch = class(TDBGWatch) TGDBWatch = class(TDBGWatch)
@ -94,7 +106,9 @@ type
public public
end; end;
{ =========================================================================== }
{ TGDBDebugger } { TGDBDebugger }
{ =========================================================================== }
constructor TGDBDebugger.Create; constructor TGDBDebugger.Create;
begin begin
@ -123,6 +137,21 @@ begin
inherited Done; inherited Done;
end; end;
function TGDBDebugger.FindBreakpoint(const ABreakpoint: Integer): TDBGBreakPoint;
var
n: Integer;
begin
if ABreakpoint <> 0
then
for n := 0 to Breakpoints.Count - 1 do
begin
Result := Breakpoints[n];
if TGDBBreakpoint(Result).FBreakID = ABreakpoint
then Exit;
end;
Result := nil;
end;
procedure TGDBDebugger.GDBJumpTo(const ASource: String; const ALine: Integer); procedure TGDBDebugger.GDBJumpTo(const ASource: String; const ALine: Integer);
begin begin
end; end;
@ -139,7 +168,7 @@ begin
case State of case State of
dsIdle, dsStop: begin dsIdle, dsStop: begin
GDBStart; GDBStart;
dState := GetGDBState; dState := GetProgramInfo(False).State;
if dState = dsPause if dState = dsPause
then begin then begin
RunCommand('cont'); RunCommand('cont');
@ -212,7 +241,7 @@ begin
repeat repeat
SendCmdLn('cont', True); SendCmdLn('cont', True);
loc := GetLocation; loc := GetLocation;
dState := GetGDBState; dState := GetProgramInfo(False).State;
until (loc.FuncName = 'main') or (Integer(loc.Adress) = StopAdress) or (dState <> dsPause); until (loc.FuncName = 'main') or (Integer(loc.Adress) = StopAdress) or (dState <> dsPause);
end; end;
end; end;
@ -222,8 +251,7 @@ begin
case State of case State of
dsIdle, dsStop: begin dsIdle, dsStop: begin
GDBStart; GDBStart;
DoCurrent(GetLocation); GetProgramInfo(True);
SetState(GetGDBState);
end; end;
dsPause: begin dsPause: begin
RunCommand('step'); RunCommand('step');
@ -236,8 +264,7 @@ begin
case State of case State of
dsIdle, dsStop: begin dsIdle, dsStop: begin
GDBStart; GDBStart;
DoCurrent(GetLocation); GetProgramInfo(True);
SetState(GetGDBState);
end; end;
dsPause: begin dsPause: begin
RunCommand('next'); RunCommand('next');
@ -256,31 +283,18 @@ begin
SendCmdLn('', True); SendCmdLn('', True);
end; end;
dState := GetGDBState; dState := GetProgramInfo(False).State;
if dState <> dsPause if dState = dsPause
then Exit; then begin
SendCmdLn('kill', True); SendCmdLn('kill', True);
dState := GetGDBState; dState := GetProgramInfo(False).State;
end;
if dState = dsStop if dState = dsStop
then KillTargetProcess; then KillTargetProcess;
SetState(dState); SetState(dState);
end; end;
function TGDBDebugger.GetGDBState: TDBGState;
var
S: String;
begin
SendCmdLn('info program', True);
S := OutputLines.Text;
if Pos('stopped', S) > 0
then Result := dsPause
else if Pos('not being run', S) > 0
then Result := dsStop
else Result := dsNone;
end;
function TGDBDebugger.GetLocation: TDBGLocationRec; function TGDBDebugger.GetLocation: TDBGLocationRec;
var var
n, idx: Integer; n, idx: Integer;
@ -326,6 +340,64 @@ begin
end; end;
end; end;
function TGDBDebugger.GetProgramInfo(const AHandleResult: Boolean): TGDBProgramInfo;
var
S, Signal: String;
BreakPoint: TGDBBreakPoint;
begin
// Loop since we might have hit a non-break breakpoint
while True do
begin
Result.Breakpoint := 0;
Result.Signal := 0;
Result.SignalText := '';
Result.State := dsNone;
SendCmdLn('info program', True);
S := OutputLines.Text;
if Pos('stopped', S) > 0
then begin
Result.State := dsPause;
if Pos('breakpoint ', S) > 0
then begin
Result.Breakpoint := StrToIntDef(GetPart('breakpoint ', '.', S), 0);
end
else if Pos('signal ', S) > 0
then begin
Signal := GetPart('signal ', ',', S);
// TODO: translate to id
Result.SignalText := GetPart(' ', '.', S);
end;
end
else if Pos('not being run', S) > 0
then Result.State := dsStop;
if AHandleResult
then begin
if Result.Breakpoint <> 0
then begin
BreakPoint := TGDBBreakPoint(FindBreakPoint(Result.Breakpoint));
if BreakPoint <> nil
then begin
BreakPoint.Hit;
if not (bpaStop in BreakPoint.Actions)
then begin
SendCmdLn('cont', True);
Continue;
end;
end;
end;
SetState(Result.State);
DoCurrent(GetLocation);
if Result.SignalText <> ''
then DoException(Result.Signal, Result.SignalText);
end;
Break;
end;
end;
function TGDBDebugger.GetSupportedCommands: TDBGCommands; function TGDBDebugger.GetSupportedCommands: TDBGCommands;
begin begin
Result := [dcRun, dcPause, dcStop, dcStepOver, dcStepInto, dcRunTo, dcJumpto, dcBreak{, dcWatch}] Result := [dcRun, dcPause, dcStop, dcStepOver, dcStepInto, dcRunTo, dcJumpto, dcBreak{, dcWatch}]
@ -361,8 +433,7 @@ procedure TGDBDebugger.RunCommand(const ACommand: String);
begin begin
SetState(dsRun); SetState(dsRun);
SendCmdLn(ACommand, True); SendCmdLn(ACommand, True);
DoCurrent(GetLocation); GetProgramInfo(True);
SetState(GetGDBState);
end; end;
function TGDBDebugger.SendCommand(const ACommand: String; Values: array of const): TStrings; function TGDBDebugger.SendCommand(const ACommand: String; Values: array of const): TStrings;
@ -376,14 +447,14 @@ begin
if AValue <> FileName if AValue <> FileName
then begin then begin
GDBStop; GDBStop;
inherited; if AValue <> ''
if FileName <> ''
then begin then begin
SendCmdLn('file %s', [FileName], True); SendCmdLn('file %s', [AValue], True);
FHasSymbols := Pos('no debugging symbols', OutputLines.Text) = 0; FHasSymbols := Pos('no debugging symbols', OutputLines.Text) = 0;
if not FHasSymbols if not FHasSymbols
then WriteLN('WARNING: File ''',FileName, ''' has no debug symbols'); then WriteLN('WARNING: File ''',AValue, ''' has no debug symbols');
end; end;
inherited;
end; end;
end; end;
@ -392,11 +463,12 @@ procedure TGDBDebugger.TestCmd(const ACommand: String);
begin begin
SetState(dsRun); SetState(dsRun);
inherited TestCmd(ACommand); inherited TestCmd(ACommand);
DoCurrent(GetLocation); GetProgramInfo(True);
SetState(GetGDBState);
end; end;
{ =========================================================================== }
{ TGDBBreakPoint } { TGDBBreakPoint }
{ =========================================================================== }
constructor TGDBBreakPoint.Create(ACollection: TCollection); constructor TGDBBreakPoint.Create(ACollection: TCollection);
begin begin
@ -431,14 +503,30 @@ procedure TGDBBreakPoint.DoExpressionChange;
begin begin
end; end;
procedure TGDBBreakPoint.SetLocation(const ASource: String; const ALine: Integer); procedure TGDBBreakPoint.DoStateChange;
begin
inherited;
if (Debugger.State = dsStop)
and (FBreakID = 0)
then SetBreakpoint;
end;
procedure TGDBBreakPoint.Hit;
begin
SetHitCount(HitCount + 1);
if bpaEnableGroup in Actions
then; //TODO
if bpaDisableGroup in Actions
then; //TODO
end;
procedure TGDBBreakPoint.SetBreakpoint;
var var
idx: Integer; idx: Integer;
S: String; S: String;
begin begin
if TGDBDebugger(Debugger).State in [dsStop, dsPause, dsIdle] S := TGDBDebugger(Debugger).SendCommand('break %s:%d', [Source, Line])[0];
then begin
S := TGDBDebugger(Debugger).SendCommand('break %s:%d', [ASource, ALine])[0];
idx := Pos(' at', S); idx := Pos(' at', S);
if idx >0 if idx >0
then begin then begin
@ -447,9 +535,18 @@ begin
SetValid(FBreakID <> 0); SetValid(FBreakID <> 0);
DoEnableChange; DoEnableChange;
end; end;
procedure TGDBBreakPoint.SetLocation(const ASource: String; const ALine: Integer);
begin
inherited;
if TGDBDebugger(Debugger).State in [dsStop, dsPause, dsIdle]
then SetBreakpoint;
end; end;
{ =========================================================================== }
{ TGDBWatch } { TGDBWatch }
{ =========================================================================== }
procedure TGDBWatch.DoEnableChange; procedure TGDBWatch.DoEnableChange;
begin begin
@ -457,7 +554,7 @@ end;
function TGDBWatch.GetValue: String; function TGDBWatch.GetValue: String;
begin begin
if (TGDBDebugger(Debugger).State in [dsStop, dsPause, dsIdle]) if (Debugger.State in [dsStop, dsPause, dsIdle])
and Valid and Valid
then begin then begin
end end
@ -472,7 +569,7 @@ end;
procedure TGDBWatch.SetExpression(const AValue: String); procedure TGDBWatch.SetExpression(const AValue: String);
begin begin
if (AValue <> Expression) if (AValue <> Expression)
and (TGDBDebugger(Debugger).State in [dsStop, dsPause, dsIdle]) and (Debugger.State in [dsStop, dsPause, dsIdle])
then begin then begin
//TGDBDebugger(Debugger).SendCmdLn('', True); //TGDBDebugger(Debugger).SendCmdLn('', True);
end; end;
@ -485,6 +582,14 @@ end;
end. end.
{ ============================================================================= { =============================================================================
$Log$ $Log$
Revision 1.6 2002/02/20 23:33:24 lazarus
MWE:
+ Published OnClick for TMenuItem
+ Published PopupMenu property for TEdit and TMemo (Doesn't work yet)
* Fixed debugger running twice
+ Added Debugger output form
* Enabled breakpoints
Revision 1.5 2002/02/06 08:58:29 lazarus Revision 1.5 2002/02/06 08:58:29 lazarus
MG: fixed compiler warnings and asking to create non existing files MG: fixed compiler warnings and asking to create non existing files

View File

@ -1,16 +1,26 @@
object DbgOutputForm1: TDbgOutputForm object DbgOutputForm1: TDbgOutputForm
CAPTION = 'Debug output' CAPTION = 'Debug output'
OnClose = FormClose
OnCreate = FormCreate OnCreate = FormCreate
OnDestroy = FormDestroy OnDestroy = FormDestroy
TOP = 10 TOP = 10
LEFT = 10 LEFT = 10
HEIGHT = 150 HEIGHT = 200
WIDTH = 301 WIDTH = 400
object txtOutput: TMemo object txtOutput: TMemo
Left = 8 Left = 8
Top = 104 Top = 104
Width = 600 Width = 600
Height = 150 Height = 150
Align = alClient Align = alClient
PopupMenu = mnuPopup
end
object mnuPopup: TPopupMenu
Left = 400
Top = 96
object popClear: TMenuItem
Caption = '&Clear'
OnClick = popClearClick
end
end end
end end

View File

@ -38,8 +38,8 @@ uses
MsgView, NewProjectDlg, IDEComp, AbstractFormEditor, FormEditor, MsgView, NewProjectDlg, IDEComp, AbstractFormEditor, FormEditor,
CustomFormEditor, ObjectInspector, PropEdits, ControlSelection, UnitEditor, CustomFormEditor, ObjectInspector, PropEdits, ControlSelection, UnitEditor,
CompilerOptions, EditorOptions, EnvironmentOpts, TransferMacros, KeyMapping, CompilerOptions, EditorOptions, EnvironmentOpts, TransferMacros, KeyMapping,
ProjectOpts, IDEProcs, Process, UnitInfoDlg, Debugger, DBGBreakpoint, ProjectOpts, IDEProcs, Process, UnitInfoDlg, Debugger, DBGOutputForm,
DBGWatch, GDBDebugger, RunParamsOpts, ExtToolDialog, MacroPromptDlg, GDBDebugger, RunParamsOpts, ExtToolDialog, MacroPromptDlg,
LMessages, ProjectDefs, Watchesdlg, BreakPointsdlg, ColumnDlg, OutputFilter, LMessages, ProjectDefs, Watchesdlg, BreakPointsdlg, ColumnDlg, OutputFilter,
BuildLazDialog, MiscOptions, EditDefineTree, CodeToolsOptions, TypInfo; BuildLazDialog, MiscOptions, EditDefineTree, CodeToolsOptions, TypInfo;
@ -126,6 +126,7 @@ type
itmViewMessage : TMenuItem; itmViewMessage : TMenuItem;
itmViewwatches : TMenuItem; itmViewwatches : TMenuItem;
itmViewBreakpoints : TMenuItem; itmViewBreakpoints : TMenuItem;
itmViewDebugOutput: TMenuItem;
itmProjectNew: TMenuItem; itmProjectNew: TMenuItem;
itmProjectOpen: TMenuItem; itmProjectOpen: TMenuItem;
@ -194,6 +195,7 @@ type
procedure mnuViewMessagesClick(Sender : TObject); procedure mnuViewMessagesClick(Sender : TObject);
procedure mnuViewWatchesClick(Sender : TObject); procedure mnuViewWatchesClick(Sender : TObject);
procedure mnuViewBreakPointsClick(Sender : TObject); procedure mnuViewBreakPointsClick(Sender : TObject);
procedure mnuViewDebugOutputClick(Sender : TObject);
procedure MessageViewDblClick(Sender : TObject); procedure MessageViewDblClick(Sender : TObject);
procedure mnuToggleFormUnitClicked(Sender : TObject); procedure mnuToggleFormUnitClicked(Sender : TObject);
@ -295,9 +297,10 @@ type
// Debugger events // Debugger events
procedure OnDebuggerChangeState(Sender: TObject); procedure OnDebuggerChangeState(Sender: TObject);
procedure OnDebuggerCurrentLine(Sender: TObject; procedure OnDebuggerCurrentLine(Sender: TObject; const ALocation: TDBGLocationRec);
const ALocation: TDBGLocationRec); procedure OnDebuggerWatchChanged(Sender: TObject);
Procedure OnDebuggerWatchChanged(Sender : TObject); procedure OnDebuggerOutput(Sender: TObject; const AText: String);
procedure OnDebuggerException(Sender: TObject; const AExceptionID: Integer; const AExceptionText: String);
// MessagesView events // MessagesView events
procedure MessagesViewSelectionChanged(sender : TObject); procedure MessagesViewSelectionChanged(sender : TObject);
@ -325,13 +328,15 @@ type
FOpenEditorsOnCodeToolChange: boolean; FOpenEditorsOnCodeToolChange: boolean;
FBreakPoints: TDBGBreakPoints; // Points to debugger breakpoints if available FBreakPoints: TDBGBreakPoints; // Points to debugger breakpoints if available
// Else to own objet // Else to own objet
FDebugOutputDlg: TDBGOutputForm;
FDebugger: TDebugger; FDebugger: TDebugger;
FRunProcess: TProcess; // temp solution, will be replaced by dummydebugger FRunProcess: TProcess; // temp solution, will be replaced by dummydebugger
TheCompiler: TCompiler; TheCompiler: TCompiler;
TheOutputFilter: TOutputFilter; TheOutputFilter: TOutputFilter;
Function CreateSeperator : TMenuItem; function CreateSeperator : TMenuItem;
Procedure SetDefaultsForForm(aForm : TCustomForm); procedure SetDefaultsForForm(aForm : TCustomForm);
procedure OutputFormDestroy(Sender: TObject);
protected protected
procedure ToolButtonClick(Sender : TObject); procedure ToolButtonClick(Sender : TObject);
@ -1364,6 +1369,13 @@ begin
itmViewBreakPoints.Shortcut := VK_B or scCtrl or scAlt; itmViewBreakPoints.Shortcut := VK_B or scCtrl or scAlt;
itmViewBreakPoints.OnClick := @mnuViewBreakPointsClick; itmViewBreakPoints.OnClick := @mnuViewBreakPointsClick;
mnuView.Add(itmViewBreakPoints); mnuView.Add(itmViewBreakPoints);
itmViewDebugOutput := TMenuItem.Create(Self);
itmViewDebugOutput.Name:='itmViewDebugOutput';
itmViewDebugOutput.Caption := 'Debug output';
itmViewDebugOutput.OnClick := @mnuViewDebugOutputClick;
mnuView.Add(itmViewDebugOutput);
//-------------- //--------------
// Project // Project
//-------------- //--------------
@ -4117,7 +4129,6 @@ begin
then Exit; then Exit;
FDebugger.FileName := ProgramFilename; FDebugger.FileName := ProgramFilename;
FDebugger.Arguments := ''; //TODO: get arguments FDebugger.Arguments := ''; //TODO: get arguments
FDebugger.Run;
end; end;
else else
// Temp solution, in futer it will be run by dummy debugger // Temp solution, in futer it will be run by dummy debugger
@ -4127,7 +4138,6 @@ begin
FRunProcess.CommandLine := ProgramFilename; FRunProcess.CommandLine := ProgramFilename;
FRunProcess.Options:= [poUsePipes, poNoConsole]; FRunProcess.Options:= [poUsePipes, poNoConsole];
FRunProcess.ShowWindow := swoNone; FRunProcess.ShowWindow := swoNone;
FRunProcess.Execute;
except except
on e: Exception do on e: Exception do
MessageDlg(Format('Error initializing program'#13 + MessageDlg(Format('Error initializing program'#13 +
@ -4136,6 +4146,9 @@ begin
end; end;
end; end;
if FDebugOutputDlg <> nil
then FDebugOutputDlg.Clear;
Result := mrOK; Result := mrOK;
ToolStatus := itDebugger; ToolStatus := itDebugger;
end; end;
@ -4309,6 +4322,8 @@ begin
//MainUnitInfo:=Project.Units[Project.MainUnit]; //MainUnitInfo:=Project.Units[Project.MainUnit];
FDebugger.OnState:=@OnDebuggerChangeState; FDebugger.OnState:=@OnDebuggerChangeState;
FDebugger.OnCurrent:=@OnDebuggerCurrentLine; FDebugger.OnCurrent:=@OnDebuggerCurrentLine;
FDebugger.OnDbgOutput := @OnDebuggerOutput;
FDebugger.OnException := @OnDebuggerException;
if FDebugger.State = dsNone if FDebugger.State = dsNone
then FDebugger.Init; then FDebugger.Init;
@ -5760,10 +5775,19 @@ Writeln('DONE showing breakpoints');
// CreateLFM(Insertwatch); // CreateLFM(Insertwatch);
end; end;
Procedure TMainIDE.OnDebuggerWatchChanged(Sender : TObject); procedure TMainIDE.mnuViewDebugOutputClick(Sender : TObject);
begin begin
Writeln('OnDebuggerWatchChanged'); if FDebugOutputDlg = nil
//watch changed. then begin
FDebugOutputDlg := TDBGOutputForm.Create(Self);
FDebugOutputDlg.OnDestroy := @OutputFormDestroy;
end;
FDebugOutputDlg.Show;
end;
procedure TMainIDE.OutputFormDestroy(Sender: TObject);
begin
FDebugOutputDlg := nil;
end; end;
//This adds the watch to the TWatches TCollection and to the watches dialog //This adds the watch to the TWatches TCollection and to the watches dialog
@ -5785,8 +5809,27 @@ begin
Watches_Dlg.AddWatch(NewWatch.Expression+':'+NewWatch.Value); Watches_Dlg.AddWatch(NewWatch.Expression+':'+NewWatch.Value);
end; end;
procedure TMainIDE.OnDebuggerException(Sender: TObject; const AExceptionID: Integer; const AExceptionText: String);
begin
MessageDlg('Error',
Format('Project %s raised exception class %d with message ''%s''.', [Project.Title, AExceptionID, AExceptionText]),
mtError,[mbOk],0);
end;
Procedure TMainIDE.OnWatchAdded(Sender : TObject; AnExpression : String); procedure TMainIDE.OnDebuggerOutput(Sender: TObject; const AText: String);
begin
if FDebugOutputDlg <> nil
then FDebugOutputDlg.AddText(AText);
end;
procedure TMainIDE.OnDebuggerWatchChanged(Sender : TObject);
begin
Writeln('OnDebuggerWatchChanged');
//watch changed.
end;
procedure TMainIDE.OnWatchAdded(Sender : TObject; AnExpression : String);
Var Var
NewWatch : TdbgWatch; NewWatch : TdbgWatch;
begin begin
@ -5817,13 +5860,16 @@ begin
SaveSpeedBtn.Enabled := SourceNotebook.GetActiveSE.Modified; SaveSpeedBtn.Enabled := SourceNotebook.GetActiveSE.Modified;
end; end;
Procedure TMainIDE.OnSrcNotebookCreateBreakPoint(Sender : TObject; procedure TMainIDE.OnSrcNotebookCreateBreakPoint(Sender : TObject; Line : Integer);
Line : Integer); var
NewBreak: TDBGBreakPoint;
begin begin
if SourceNotebook.Notebook = nil then Exit; if SourceNotebook.Notebook = nil then Exit;
Breakpoints_Dlg.AddBreakPoint(TSourceNotebook(sender).GetActiveSe.FileName,Line); Breakpoints_Dlg.AddBreakPoint(TSourceNotebook(sender).GetActiveSe.FileName,Line);
FBreakPoints.Add(TSourceNotebook(sender).GetActiveSe.FileName, Line);
NewBreak := FBreakPoints.Add(TSourceNotebook(sender).GetActiveSe.FileName, Line);
NewBreak.Enabled := True;
end; end;
Procedure TMainIDE.OnSrcNotebookDeleteBreakPoint(Sender : TObject; Procedure TMainIDE.OnSrcNotebookDeleteBreakPoint(Sender : TObject;
@ -6002,6 +6048,14 @@ end.
{ ============================================================================= { =============================================================================
$Log$ $Log$
Revision 1.227 2002/02/20 23:33:23 lazarus
MWE:
+ Published OnClick for TMenuItem
+ Published PopupMenu property for TEdit and TMemo (Doesn't work yet)
* Fixed debugger running twice
+ Added Debugger output form
* Enabled breakpoints
Revision 1.226 2002/02/20 16:01:43 lazarus Revision 1.226 2002/02/20 16:01:43 lazarus
MG: fixed editor opts general flags MG: fixed editor opts general flags

View File

@ -101,7 +101,6 @@ type
property Handle: HMenu read GetHandle write FHandle; property Handle: HMenu read GetHandle write FHandle;
property Items[Index: Integer]: TMenuItem read GetItem; default; property Items[Index: Integer]: TMenuItem read GetItem; default;
property Parent: TMenuItem read GetParent; property Parent: TMenuItem read GetParent;
property OnClick: TNotifyEvent read FOnClick write FOnclick;
published published
property Caption: String read FCaption write SetCaption {stored IsCaptionStored}; property Caption: String read FCaption write SetCaption {stored IsCaptionStored};
property Checked: Boolean read FChecked write SetChecked {stored IsCheckedStored} default False; property Checked: Boolean read FChecked write SetChecked {stored IsCheckedStored} default False;
@ -111,6 +110,7 @@ type
property ImageIndex : Integer read FImageIndex write SetImageIndex; property ImageIndex : Integer read FImageIndex write SetImageIndex;
property ShortCut: TShortCut read FShortCut write SetShortCut {stored IsShortCutStored} default 0; property ShortCut: TShortCut read FShortCut write SetShortCut {stored IsShortCutStored} default 0;
property Visible: Boolean read FVisible write SetVisible {stored IsVisibleStored} default True; property Visible: Boolean read FVisible write SetVisible {stored IsVisibleStored} default True;
property OnClick: TNotifyEvent read FOnClick write FOnclick;
end; end;
TFindItemKind = (fkCommand, fkHandle, fkShortCut); TFindItemKind = (fkCommand, fkHandle, fkShortCut);
@ -203,6 +203,14 @@ end.
{ {
$Log$ $Log$
Revision 1.7 2002/02/20 23:33:24 lazarus
MWE:
+ Published OnClick for TMenuItem
+ Published PopupMenu property for TEdit and TMemo (Doesn't work yet)
* Fixed debugger running twice
+ Added Debugger output form
* Enabled breakpoints
Revision 1.6 2002/02/18 22:46:11 lazarus Revision 1.6 2002/02/18 22:46:11 lazarus
Implented TMenuItem.ShortCut (not much tested). Implented TMenuItem.ShortCut (not much tested).

View File

@ -308,6 +308,7 @@ type
property CharCase; property CharCase;
property DragMode; property DragMode;
property MaxLength; property MaxLength;
property PopupMenu;
property ReadOnly; property ReadOnly;
property Text; property Text;
property Visible; property Visible;
@ -321,8 +322,8 @@ type
property Align; property Align;
property Color; property Color;
property Font; property Font;
property Lines; property Lines;
property PopupMenu;
property ReadOnly; property ReadOnly;
property Tabstop; property Tabstop;
property Visible; property Visible;
@ -582,6 +583,14 @@ end.
{ ============================================================================= { =============================================================================
$Log$ $Log$
Revision 1.21 2002/02/20 23:33:24 lazarus
MWE:
+ Published OnClick for TMenuItem
+ Published PopupMenu property for TEdit and TMemo (Doesn't work yet)
* Fixed debugger running twice
+ Added Debugger output form
* Enabled breakpoints
Revision 1.20 2002/02/03 00:24:01 lazarus Revision 1.20 2002/02/03 00:24:01 lazarus
TPanel implemented. TPanel implemented.
Basic graphic primitives split into GraphType package, so that we can Basic graphic primitives split into GraphType package, so that we can