1 {  $Id$  }
2 {
3  /***************************************************************************
4                          basedebugmanager.pp
5                          -------------------
6  TBaseDebugManager is the base class for TDebugManager, which controls all
7  debugging related stuff in the IDE. The base class is mostly abstract.
8 
9 
10  ***************************************************************************/
11 
12  ***************************************************************************
13  *                                                                         *
14  *   This source is free software; you can redistribute it and/or modify   *
15  *   it under the terms of the GNU General Public License as published by  *
16  *   the Free Software Foundation; either version 2 of the License, or     *
17  *   (at your option) any later version.                                   *
18  *                                                                         *
19  *   This code is distributed in the hope that it will be useful, but      *
20  *   WITHOUT ANY WARRANTY; without even the implied warranty of            *
21  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU     *
22  *   General Public License for more details.                              *
23  *                                                                         *
24  *   A copy of the GNU General Public License is available on the World    *
25  *   Wide Web at <http://www.gnu.org/copyleft/gpl.html>. You can also      *
26  *   obtain it by writing to the Free Software Foundation,                 *
27  *   Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1335, USA.   *
28  *                                                                         *
29  ***************************************************************************
30 }
31 unit BaseDebugManager;
32 
33 {$mode objfpc}{$H+}
34 
35 interface
36 
37 {$I ide.inc}
38 
39 uses
40 {$IFDEF IDE_MEM_CHECK}
41   MemCheck,
42 {$ENDIF}
43   Classes, SysUtils,
44   // LCL
45   Forms,
46   // LazUtils
47   Laz2_XMLCfg,
48   // IdeIntf
49   IDEOptionsIntf, IDEOptEditorIntf,
50   // DebuggerIntf
51   DbgIntfBaseTypes, DbgIntfDebuggerBase, DbgIntfPseudoTerminal,
52   // IDE
53   Debugger, SourceMarks, Project, ProjectDefs, LazarusIDEStrConsts;
54 
55 type
56   TDebugDialogType = (
57     ddtOutput,
58     ddtEvents,
59     ddtBreakpoints,
60     ddtWatches,
61     ddtLocals,
62     ddtCallStack,
63     ddtEvaluate,
64     ddtRegisters,
65     ddtAssembler,
66     ddtInspect,
67     ddtPseudoTerminal,
68     ddtThreads,
69     ddtHistory
70     );
71 
72 const
73   // used as ID for layout storage.
74   // Do not change. Do not translate
75   DebugDialogNames: array [TDebugDialogType] of string = (
76     'DbgOutput',
77     'DbgEvents',
78     'BreakPoints',
79     'Watches',
80     'Locals',
81     'CallStack',
82     'EvaluateModify',
83     'Registers',
84     'Assembler',
85     'Inspect',
86     'PseudoTerminal',
87     'Threads',
88     'DbgHistory'
89     );
90 
91 type
92 
93   { TBaseDebugManager }
94 
95   TDebugManagerState = (
96     dmsInitializingDebuggerObject,
97     dmsInitializingDebuggerObjectFailed,
98     dmsDebuggerObjectBroken,  // the debugger entered the error state
99     dmsWaitForRun, // waiting for call to RunDebugger, set by StartDebugging
100     dmsWaitForAttach,
101     dmsRunning  // set by RunDebugger
102     );
103   TDebugManagerStates = set of TDebugManagerState;
104 
105   TDbgInitFlag = (difInitForAttach);
106   TDbgInitFlags = set of TDbgInitFlag;
107 
108   { TDebuggerOptions }
109 
110   TDebuggerOptions = class(TAbstractIDEEnvironmentOptions)
111   public
GetGroupCaptionnull112     class function GetGroupCaption:string; override;
GetInstancenull113     class function GetInstance: TAbstractIDEOptions; override;
114   end;
115 
116   TBaseDebugManager = class(TBaseDebugManagerIntf)
117   protected
118     FDestroying: boolean;
119     FCallStack: TIdeCallStackMonitor;
120     FDisassembler: TIDEDisassembler;
121     FExceptions: TIDEExceptions;
122     FSignals: TIDESignals;
123     FBreakPoints: TIDEBreakPoints;
124     FBreakPointGroups: TIDEBreakPointGroups;
125     FLocals: TIdeLocalsMonitor;
126     FLineInfo: TIDELineInfo;
127     FWatches: TIdeWatchesMonitor;
128     FThreads: TIdeThreadsMonitor;
129     FRegisters: TIdeRegistersMonitor;
130     FSnapshots: TSnapshotManager;
131     FManagerStates: TDebugManagerStates;
GetStatenull132     function  GetState: TDBGState; virtual; abstract;
GetCommandsnull133     function  GetCommands: TDBGCommands; virtual; abstract;
GetPseudoTerminalnull134     function GetPseudoTerminal: TPseudoTerminal; virtual; abstract;
135     {$IFDEF DBG_WITH_DEBUGGER_DEBUG}
GetDebuggernull136     function GetDebugger: TDebuggerIntf; virtual; abstract;
137     {$ENDIF}
GetCurrentDebuggerClassnull138     function GetCurrentDebuggerClass: TDebuggerClass; virtual; abstract;    (* TODO: workaround for http://bugs.freepascal.org/view.php?id=21834   *)
139   public
140     procedure Reset; virtual; abstract;
141 
142     procedure ConnectMainBarEvents; virtual; abstract;
143     procedure ConnectSourceNotebookEvents; virtual; abstract;
144     procedure SetupMainBarShortCuts; virtual; abstract;
145     procedure SetupSourceMenuShortCuts; virtual; abstract;
146     procedure UpdateButtonsAndMenuItems; virtual; abstract;
147     procedure UpdateToolStatus; virtual; abstract;
148     procedure EnvironmentOptsChanged; virtual; abstract;
149 
150     procedure LoadProjectSpecificInfo(XMLConfig: TXMLConfig;
151                                       Merge: boolean); virtual; abstract;
152     procedure SaveProjectSpecificInfo(XMLConfig: TXMLConfig;
153                                       Flags: TProjectWriteFlags); virtual; abstract;
154 
155 
156     procedure DoRestoreDebuggerMarks(AnUnitInfo: TUnitInfo); virtual; abstract;
157 
RequiredCompilerOptsnull158     function RequiredCompilerOpts(ATargetCPU, ATargetOS: String): TDebugCompilerRequirements; virtual; abstract;
InitDebuggernull159     function InitDebugger(AFlags: TDbgInitFlags = []): Boolean; virtual; abstract;
160 
DoPauseProjectnull161     function DoPauseProject: TModalResult; virtual; abstract;
DoShowExecutionPointnull162     function DoShowExecutionPoint: TModalResult; virtual; abstract;
DoStepIntoProjectnull163     function DoStepIntoProject: TModalResult; virtual; abstract;
DoStepOverProjectnull164     function DoStepOverProject: TModalResult; virtual; abstract;
DoStepOutProjectnull165     function DoStepOutProject: TModalResult; virtual; abstract;
DoStepIntoInstrProjectnull166     function DoStepIntoInstrProject: TModalResult; virtual; abstract;
DoStepOverInstrProjectnull167     function DoStepOverInstrProject: TModalResult; virtual; abstract;
DoStepToCursornull168     function DoStepToCursor: TModalResult; virtual; abstract;
DoRunToCursornull169     function DoRunToCursor: TModalResult; virtual; abstract;
DoStopProjectnull170     function DoStopProject: TModalResult; virtual; abstract;
171     procedure DoToggleCallStack; virtual; abstract;
172     procedure DoSendConsoleInput(AText: String); virtual; abstract;
173     procedure ProcessCommand(Command: word; var Handled: boolean); virtual; abstract;
174 
175     procedure LockCommandProcessing; virtual; abstract;
176     procedure UnLockCommandProcessing; virtual; abstract;
177 
StartDebuggingnull178     function StartDebugging: TModalResult; virtual; abstract; // set ToolStatus to itDebugger, but do not run debugger yet
RunDebuggernull179     function RunDebugger: TModalResult; virtual; abstract; // run program, wait until program ends
180     procedure EndDebugging; virtual; abstract;
181 
182     procedure Attach(AProcessID: String); virtual; abstract;
183     procedure Detach; virtual; abstract;
FillProcessListnull184     function FillProcessList(AList: TRunningProcessInfoList): boolean; virtual; abstract;
185 
Evaluatenull186     function Evaluate(const AExpression: String; ACallback: TDBGEvaluateResultCallback;
187                       EvalFlags: TDBGEvaluateFlags = []): Boolean; virtual; abstract; // Evaluates the given expression, returns true if valid
Modifynull188     function Modify(const AExpression: String; const ANewValue: String): Boolean; virtual; abstract; // Modify the given expression, returns true if valid
189 
GetFullFilenamenull190     function GetFullFilename(const AUnitinfo: TDebuggerUnitInfo;
191                              out Filename: string; AskUserIfNotFound: Boolean): Boolean; virtual; abstract;
GetFullFilenamenull192     function GetFullFilename(var Filename: string; AskUserIfNotFound: Boolean): Boolean; virtual; abstract;
193 
194     procedure EvaluateModify(const AExpression: String); virtual; abstract;
195     procedure Inspect(const AExpression: String); virtual; abstract;
196 
DoCreateBreakPointnull197     function DoCreateBreakPoint(const AFilename: string; ALine: integer;
198                                 WarnIfNoDebugger: boolean): TModalResult; virtual; abstract;
DoCreateBreakPointnull199     function DoCreateBreakPoint(const AFilename: string; ALine: integer;
200                                 WarnIfNoDebugger: boolean;
201                                 out ABrkPoint: TIDEBreakPoint;
202                                 AnUpdating: Boolean = False): TModalResult; virtual; abstract;
DoCreateBreakPointnull203     function DoCreateBreakPoint(const AnAddr: TDBGPtr;
204                                 WarnIfNoDebugger: boolean;
205                                 out ABrkPoint: TIDEBreakPoint;
206                                 AnUpdating: Boolean = False): TModalResult; virtual; abstract;
DoDeleteBreakPointnull207     function DoDeleteBreakPoint(const AFilename: string; ALine: integer
208                                 ): TModalResult; virtual; abstract;
DoDeleteBreakPointAtMarknull209     function DoDeleteBreakPointAtMark(const ASourceMark: TSourceMark
210                                      ): TModalResult; virtual; abstract;
211 
ShowBreakPointPropertiesnull212     function ShowBreakPointProperties(const ABreakpoint: TIDEBreakPoint): TModalresult; virtual; abstract;
ShowWatchPropertiesnull213     function ShowWatchProperties(const AWatch: TCurrentWatch; AWatchExpression: String = ''): TModalresult; virtual; abstract;
214 
215     // Dialog routines
216     procedure CreateDebugDialog(Sender: TObject; aFormName: string;
217                           var AForm: TCustomForm; DoDisableAutoSizing: boolean); virtual; abstract;
218     procedure ViewDebugDialog(const ADialogType: TDebugDialogType;
219                               BringToFront: Boolean = True; Show: Boolean = true;
220                               DoDisableAutoSizing: boolean = false); virtual; abstract;
221     procedure ViewDisassembler(AnAddr: TDBGPtr;
222                               BringToFront: Boolean = True; Show: Boolean = true;
223                               DoDisableAutoSizing: boolean = false); virtual; abstract;
224   public
225     property Commands: TDBGCommands read GetCommands;  // All current available commands of the debugger
226     property Destroying: boolean read FDestroying;
227     property State: TDBGState read GetState;           // The current state of the debugger
228 
229     property BreakPoints: TIDEBreakPoints read FBreakpoints;   // A list of breakpoints for the current project
230     property BreakPointGroups: TIDEBreakPointGroups read FBreakPointGroups;
231     property Exceptions: TIDEExceptions read FExceptions;      // A list of exceptions we should ignore
232     property CallStack: TIdeCallStackMonitor read FCallStack;
233     property Disassembler: TIDEDisassembler read FDisassembler;
234     property Locals: TIdeLocalsMonitor read FLocals;
235     property LineInfo: TIDELineInfo read FLineInfo;
236     property Registers: TIdeRegistersMonitor read FRegisters;
237     property Signals: TIDESignals read FSignals;               // A list of actions for signals we know of
238     property Watches: TIdeWatchesMonitor read FWatches;
239     property Threads: TIdeThreadsMonitor read FThreads;
240     property Snapshots: TSnapshotManager read FSnapshots;
241     property PseudoTerminal: TPseudoTerminal read GetPseudoTerminal; experimental; // 'may be replaced with a more general API';
242     (* TODO: workaround for http://bugs.freepascal.org/view.php?id=21834   *)
243     property DebuggerClass: TDebuggerClass read GetCurrentDebuggerClass;
244     {$IFDEF DBG_WITH_DEBUGGER_DEBUG}
245     property Debugger: TDebuggerIntf read GetDebugger;
246     {$ENDIF}
247   end;
248 
249 
250 var
251   DebugBoss: TBaseDebugManager;
252   DebuggerOptions: TDebuggerOptions = nil;
253 
254 implementation
255 
256 { TDebuggerOptions }
257 
TDebuggerOptions.GetGroupCaptionnull258 class function TDebuggerOptions.GetGroupCaption: string;
259 begin
260   Result := dlgGroupDebugger;
261 end;
262 
TDebuggerOptions.GetInstancenull263 class function TDebuggerOptions.GetInstance: TAbstractIDEOptions;
264 begin
265   Result := DebuggerOptions;
266 end;
267 
268 initialization
269   RegisterIDEOptionsGroup(GroupDebugger, TDebuggerOptions);
270   DebugBoss := nil;
271 
272 end.
273 
274 
275 
276