fpdebug.pas 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407
  1. {
  2. $Id$
  3. This file is part of the Free Pascal Integrated Development Environment
  4. Copyright (c) 1998 by Berczi Gabor
  5. Debugger call routines for the IDE
  6. See the file COPYING.FPC, included in this distribution,
  7. for details about the copyright.
  8. This program is distributed in the hope that it will be useful,
  9. but WITHOUT ANY WARRANTY; without even the implied warranty of
  10. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  11. **********************************************************************}
  12. unit FPDebug;
  13. interface
  14. uses
  15. Views,Objects,GDBCon,GDBInt;
  16. type
  17. PDebugController=^TDebugController;
  18. TDebugController=object(TGDBController)
  19. Invalid_line : boolean;
  20. LastFileName : string;
  21. LastSource : PView; {PsourceWindow !! }
  22. constructor Init(const exefn:string);
  23. destructor Done;
  24. procedure DoSelectSourceline(const fn:string;line:longint);virtual;
  25. { procedure DoStartSession;virtual;
  26. procedure DoBreakSession;virtual;}
  27. procedure DoEndSession(code:longint);virtual;
  28. procedure AnnotateError;
  29. procedure InsertBreakpoints;
  30. procedure RemoveBreakpoints;
  31. procedure DoDebuggerScreen;virtual;
  32. procedure DoUserScreen;virtual;
  33. end;
  34. BreakpointType = (bt_function,bt_file_line,bt_invalid);
  35. BreakpointState = (bs_enabled,bs_disabled,bs_deleted);
  36. PBreakpointCollection=^TBreakpointCollection;
  37. PBreakpoint=^TBreakpoint;
  38. TBreakpoint=object(TObject)
  39. typ : BreakpointType;
  40. state : BreakpointState;
  41. owner : PBreakpointCollection;
  42. Name : PString; { either function name or file name }
  43. Line : Longint; { only used for bt_file_line type }
  44. Conditions : PString; { conditions relative to that breakpoint }
  45. GDBIndex : longint;
  46. GDBState : BreakpointState;
  47. constructor Init_function(Const AFunc : String);
  48. constructor Init_file_line(Const AFile : String; ALine : longint);
  49. procedure Insert;
  50. procedure Remove;
  51. procedure Enable;
  52. procedure Disable;
  53. destructor Done;virtual;
  54. end;
  55. TBreakpointCollection=object(TCollection)
  56. function At(Index: Integer): PBreakpoint;
  57. function ToggleFileLine(Const FileName: String;LineNr : Longint) : boolean;
  58. procedure FreeItem(Item: Pointer); virtual;
  59. end;
  60. var
  61. Debugger : PDebugController;
  62. BreakpointCollection : PBreakpointCollection;
  63. procedure InitDebugger;
  64. procedure DoneDebugger;
  65. implementation
  66. uses
  67. Dos,Mouse,Video,
  68. App,
  69. FPViews,FPVars,FPUtils,FPIntf,
  70. FPCompile,FPIde;
  71. {****************************************************************************
  72. TDebugController
  73. ****************************************************************************}
  74. constructor TDebugController.Init(const exefn:string);
  75. var f: string;
  76. begin
  77. inherited Init;
  78. f := exefn;
  79. LoadFile(f);
  80. InsertBreakpoints;
  81. end;
  82. procedure TDebugController.InsertBreakpoints;
  83. procedure DoInsert(PB : PBreakpoint);
  84. begin
  85. PB^.Insert;
  86. end;
  87. begin
  88. BreakpointCollection^.ForEach(@DoInsert);
  89. end;
  90. procedure TDebugController.RemoveBreakpoints;
  91. procedure DoDelete(PB : PBreakpoint);
  92. begin
  93. PB^.Remove;
  94. end;
  95. begin
  96. BreakpointCollection^.ForEach(@DoDelete);
  97. end;
  98. destructor TDebugController.Done;
  99. begin
  100. { kill the program if running }
  101. Reset;
  102. RemoveBreakpoints;
  103. inherited Done;
  104. end;
  105. procedure TDebugController.AnnotateError;
  106. var errornb : longint;
  107. begin
  108. if error then
  109. begin
  110. errornb:=error_num;
  111. ErrorBox(#3'Error within GDB'#13#3'Error code = %d',@errornb);
  112. end;
  113. end;
  114. procedure TDebugController.DoSelectSourceLine(const fn:string;line:longint);
  115. var
  116. W: PSourceWindow;
  117. begin
  118. Desktop^.Lock;
  119. if Line>0 then
  120. dec(Line);
  121. if (fn=LastFileName) then
  122. begin
  123. W:=PSourceWindow(LastSource);
  124. if assigned(W) then
  125. begin
  126. W^.Editor^.SetCurPtr(0,Line);
  127. W^.Editor^.SetHighlightRow(Line);
  128. W^.Select;
  129. Invalid_line:=false;
  130. end
  131. else
  132. Invalid_line:=true;
  133. end
  134. else
  135. begin
  136. W:=TryToOpenFile(nil,fn,0,Line);
  137. if assigned(W) then
  138. begin
  139. W^.Editor^.SetHighlightRow(Line);
  140. W^.Select;
  141. LastSource:=W;
  142. Invalid_line:=false;
  143. end
  144. { only search a file once }
  145. else
  146. begin
  147. if not MyApp.OpenSearch(fn+'*') then
  148. begin
  149. Invalid_line:=true;
  150. LastSource:=Nil;
  151. end
  152. else
  153. begin
  154. { should now be open }
  155. W:=TryToOpenFile(nil,fn,0,Line);
  156. W^.Editor^.SetHighlightRow(Line);
  157. W^.Select;
  158. LastSource:=W;
  159. Invalid_line:=false;
  160. end;
  161. end;
  162. end;
  163. LastFileName:=fn;
  164. Desktop^.UnLock;
  165. end;
  166. procedure TDebugController.DoEndSession(code:longint);
  167. begin
  168. InformationBox(#3'Program exited with '#13#3'exitcode = %d',@code);
  169. end;
  170. procedure TDebugController.DoDebuggerScreen;
  171. begin
  172. MyApp.ShowIDEScreen;
  173. end;
  174. procedure TDebugController.DoUserScreen;
  175. begin
  176. MyApp.ShowUserScreen;
  177. end;
  178. {****************************************************************************
  179. TBreakpoint
  180. ****************************************************************************}
  181. constructor TBreakpoint.Init_function(Const AFunc : String);
  182. begin
  183. typ:=bt_function;
  184. state:=bs_enabled;
  185. GDBState:=bs_deleted;
  186. GetMem(Name,Length(AFunc)+1);
  187. Name^:=AFunc;
  188. Conditions:=nil;
  189. end;
  190. constructor TBreakpoint.Init_file_line(Const AFile : String; ALine : longint);
  191. begin
  192. typ:=bt_file_line;
  193. state:=bs_enabled;
  194. GDBState:=bs_deleted;
  195. GetMem(Name,Length(AFile)+1);
  196. Name^:=AFile;
  197. Line:=ALine;
  198. Conditions:=nil;
  199. end;
  200. procedure TBreakpoint.Insert;
  201. begin
  202. If not assigned(Debugger) then Exit;
  203. Debugger^.last_breakpoint_number:=0;
  204. if (GDBState=bs_deleted) and (state=bs_enabled) then
  205. begin
  206. if (typ=bt_file_line) then
  207. Debugger^.Command('break '+name^+':'+IntToStr(Line))
  208. else if typ=bt_function then
  209. Debugger^.Command('break '+name^);
  210. if Debugger^.last_breakpoint_number<>0 then
  211. begin
  212. GDBIndex:=Debugger^.last_breakpoint_number;
  213. GDBState:=bs_enabled;
  214. if assigned(conditions) then
  215. Debugger^.Command('cond '+IntToStr(GDBIndex)+' '+Conditions^);
  216. end
  217. else
  218. { Here there was a problem !! }
  219. begin
  220. GDBIndex:=0;
  221. state:=bs_disabled;
  222. end;
  223. end
  224. else if (GDBState=bs_disabled) and (state=bs_enabled) then
  225. Enable
  226. else if (GDBState=bs_enabled) and (state=bs_disabled) then
  227. Disable;
  228. end;
  229. procedure TBreakpoint.Remove;
  230. begin
  231. If not assigned(Debugger) then Exit;
  232. if GDBIndex>0 then
  233. Debugger^.Command('delete '+IntToStr(GDBIndex));
  234. GDBIndex:=0;
  235. GDBState:=bs_deleted;
  236. end;
  237. procedure TBreakpoint.Enable;
  238. begin
  239. If not assigned(Debugger) then Exit;
  240. if GDBIndex>0 then
  241. Debugger^.Command('enable '+IntToStr(GDBIndex));
  242. GDBState:=bs_enabled;
  243. end;
  244. procedure TBreakpoint.Disable;
  245. begin
  246. If not assigned(Debugger) then Exit;
  247. if GDBIndex>0 then
  248. Debugger^.Command('disable '+IntToStr(GDBIndex));
  249. GDBState:=bs_disabled;
  250. end;
  251. destructor TBreakpoint.Done;
  252. begin
  253. if assigned(Name) then
  254. FreeMem(Name,Length(Name^)+1);
  255. if assigned(Conditions) then
  256. FreeMem(Conditions,Length(Conditions^)+1);
  257. inherited Done;
  258. end;
  259. {****************************************************************************
  260. TBreakpointCollection
  261. ****************************************************************************}
  262. function TBreakpointCollection.At(Index: Integer): PBreakpoint;
  263. begin
  264. At:=inherited At(Index);
  265. end;
  266. procedure TBreakpointCollection.FreeItem(Item: Pointer);
  267. begin
  268. if Item<>nil then Dispose(PBreakpoint(Item),Done);
  269. end;
  270. function TBreakpointCollection.ToggleFileLine(Const FileName: String;LineNr : Longint) : boolean;
  271. var PB : PBreakpoint;
  272. function IsThere(P : PBreakpoint) : boolean;
  273. begin
  274. IsThere:=(P^.typ=bt_file_line) and (P^.Name^=FileName) and (P^.Line=LineNr);
  275. end;
  276. begin
  277. PB:=FirstThat(@IsThere);
  278. ToggleFileLine:=false;
  279. If Assigned(PB) then
  280. if PB^.state=bs_disabled then
  281. begin
  282. PB^.state:=bs_enabled;
  283. ToggleFileLine:=true;
  284. end
  285. else if PB^.state=bs_enabled then
  286. PB^.state:=bs_disabled;
  287. If not assigned(PB) then
  288. begin
  289. PB:= New(PBreakpoint,Init_file_line(FileName,LineNr));
  290. if assigned(PB) then
  291. Begin
  292. Insert(PB);
  293. ToggleFileLine:=true;
  294. End;
  295. end;
  296. end;
  297. {****************************************************************************
  298. Initialize
  299. ****************************************************************************}
  300. procedure InitDebugger;
  301. begin
  302. Assign(gdb_file,'gdb$$$.out');
  303. Rewrite(gdb_file);
  304. Use_gdb_file:=true;
  305. if (not ExistsFile(ExeFile)) or (CompilationPhase<>cpDone) then
  306. DoCompile(cRun);
  307. if CompilationPhase<>cpDone then
  308. Exit;
  309. if (EXEFile='') then
  310. begin
  311. ErrorBox('Oooops, nothing to debug.',nil);
  312. Exit;
  313. end;
  314. { init debugcontroller }
  315. if assigned(Debugger) then
  316. dispose(Debugger,Done);
  317. new(Debugger,Init(ExeFile));
  318. end;
  319. procedure DoneDebugger;
  320. begin
  321. if assigned(Debugger) then
  322. dispose(Debugger,Done);
  323. Use_gdb_file:=false;
  324. Close(GDB_file);
  325. end;
  326. begin
  327. New(BreakpointCollection,init(10,10));
  328. end.
  329. {
  330. $Log$
  331. Revision 1.5 1999-02-04 17:54:22 pierre
  332. + several commands added
  333. Revision 1.4 1999/02/04 13:32:02 pierre
  334. * Several things added (I cannot commit them independently !)
  335. + added TBreakpoint and TBreakpointCollection
  336. + added cmResetDebugger,cmGrep,CmToggleBreakpoint
  337. + Breakpoint list in INIFile
  338. * Select items now also depend of SwitchMode
  339. * Reading of option '-g' was not possible !
  340. + added search for -Fu args pathes in TryToOpen
  341. + added code for automatic opening of FileDialog
  342. if source not found
  343. Revision 1.3 1999/02/02 16:41:38 peter
  344. + automatic .pas/.pp adding by opening of file
  345. * better debuggerscreen changes
  346. Revision 1.2 1999/01/22 18:14:09 pierre
  347. * adaptd to changes in gdbint and gdbcon for to /
  348. Revision 1.1 1999/01/22 10:24:03 peter
  349. * first debugger things
  350. }