gdbmicon.pas 5.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232
  1. {
  2. Copyright (c) 2015 by Nikolay Nikolov
  3. Copyright (c) 1998 by Peter Vreman
  4. This is a replacement for GDBCon, implemented on top of GDB/MI,
  5. instead of LibGDB. This allows integration of GDB/MI support in the
  6. text mode IDE.
  7. See the file COPYING.FPC, included in this distribution,
  8. for details about the copyright.
  9. This program is distributed in the hope that it will be useful,
  10. but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  12. **********************************************************************}
  13. unit gdbmicon;
  14. {$MODE fpc}{$H-}
  15. interface
  16. uses
  17. gdbmiint, gdbmiwrap;
  18. type
  19. TGDBController = object(TGDBInterface)
  20. private
  21. procedure RunExecCommand(const Cmd: string);
  22. protected
  23. TBreakNumber,
  24. start_break_number: LongInt;
  25. in_command: LongInt;
  26. procedure CommandBegin(const s: string); virtual;
  27. procedure CommandEnd(const s: string); virtual;
  28. public
  29. constructor Init;
  30. destructor Done;
  31. procedure Command(const s: string);
  32. procedure Reset; virtual;
  33. { tracing }
  34. procedure StartTrace;
  35. procedure Run; virtual;
  36. procedure TraceStep;
  37. procedure TraceNext;
  38. procedure TraceStepI;
  39. procedure TraceNextI;
  40. procedure Continue; virtual;
  41. procedure UntilReturn; virtual;
  42. procedure SetTBreak(tbreakstring : string);
  43. procedure Backtrace;
  44. function LoadFile(var fn: string): Boolean;
  45. procedure SetDir(const s: string);
  46. procedure SetArgs(const s: string);
  47. end;
  48. implementation
  49. uses
  50. {$ifdef Windows}
  51. Windebug,
  52. {$endif Windows}
  53. strings;
  54. procedure UnixDir(var s : string);
  55. var i : longint;
  56. begin
  57. for i:=1 to length(s) do
  58. if s[i]='\' then
  59. {$ifdef windows}
  60. { Don't touch at '\ ' used to escapes spaces in windows file names PM }
  61. if (i=length(s)) or (s[i+1]<>' ') then
  62. {$endif windows}
  63. s[i]:='/';
  64. {$ifdef windows}
  65. { if we are using cygwin, we need to convert e:\ into /cygdriveprefix/e/ PM }
  66. if using_cygwin_gdb and (length(s)>2) and (s[2]=':') and (s[3]='/') then
  67. s:=CygDrivePrefix+'/'+s[1]+copy(s,3,length(s));
  68. {$endif windows}
  69. end;
  70. constructor TGDBController.Init;
  71. begin
  72. inherited Init;
  73. end;
  74. destructor TGDBController.Done;
  75. begin
  76. inherited Done;
  77. end;
  78. procedure TGDBController.CommandBegin(const s: string);
  79. begin
  80. end;
  81. procedure TGDBController.Command(const s: string);
  82. begin
  83. Inc(in_command);
  84. CommandBegin(s);
  85. GDBOutputBuf.Reset;
  86. GDBErrorBuf.Reset;
  87. i_gdb_command(s);
  88. CommandEnd(s);
  89. Dec(in_command);
  90. end;
  91. procedure TGDBController.CommandEnd(const s: string);
  92. begin
  93. end;
  94. procedure TGDBController.Reset;
  95. begin
  96. end;
  97. procedure TGDBController.StartTrace;
  98. begin
  99. Command('-break-insert -t PASCALMAIN');
  100. start_break_number := GDB.ResultRecord.Parameters['bkpt'].AsTuple['number'].AsLongInt;
  101. Run;
  102. end;
  103. procedure TGDBController.RunExecCommand(const Cmd: string);
  104. begin
  105. UserScreen;
  106. Command(Cmd);
  107. WaitForProgramStop;
  108. end;
  109. procedure TGDBController.Run;
  110. begin
  111. RunExecCommand('-exec-run');
  112. end;
  113. procedure TGDBController.TraceStep;
  114. begin
  115. RunExecCommand('-exec-step');
  116. end;
  117. procedure TGDBController.TraceNext;
  118. begin
  119. RunExecCommand('-exec-next');
  120. end;
  121. procedure TGDBController.TraceStepI;
  122. begin
  123. RunExecCommand('-exec-step-instruction');
  124. end;
  125. procedure TGDBController.TraceNextI;
  126. begin
  127. RunExecCommand('-exec-next-instruction');
  128. end;
  129. procedure TGDBController.Continue;
  130. begin
  131. RunExecCommand('-exec-continue');
  132. end;
  133. procedure TGDBController.UntilReturn;
  134. begin
  135. RunExecCommand('-exec-finish');
  136. end;
  137. procedure TGDBController.SetTBreak(tbreakstring : string);
  138. begin
  139. Command('-break-insert -t ' + tbreakstring);
  140. TBreakNumber := GDB.ResultRecord.Parameters['bkpt'].AsTuple['number'].AsLongInt;
  141. end;
  142. procedure TGDBController.Backtrace;
  143. var
  144. FrameList: TGDBMI_ListValue;
  145. I: LongInt;
  146. begin
  147. { forget all old frames }
  148. clear_frames;
  149. Command('-stack-list-frames');
  150. if not GDB.ResultRecord.Success then
  151. exit;
  152. FrameList := GDB.ResultRecord.Parameters['stack'].AsList;
  153. frame_count := FrameList.Count;
  154. frames := AllocMem(SizeOf(PFrameEntry) * frame_count);
  155. for I := 0 to frame_count - 1 do
  156. frames[I] := New(PFrameEntry, Init);
  157. for I := 0 to FrameList.Count - 1 do
  158. begin
  159. frames[I]^.address := FrameList.ValueAt[I].AsTuple['addr'].AsPtrInt;
  160. frames[I]^.level := FrameList.ValueAt[I].AsTuple['level'].AsLongInt;
  161. if Assigned(FrameList.ValueAt[I].AsTuple['line']) then
  162. frames[I]^.line_number := FrameList.ValueAt[I].AsTuple['line'].AsLongInt;
  163. if Assigned(FrameList.ValueAt[I].AsTuple['func']) then
  164. frames[I]^.function_name := StrNew(PChar(FrameList.ValueAt[I].AsTuple['func'].AsString));
  165. if Assigned(FrameList.ValueAt[I].AsTuple['fullname']) then
  166. frames[I]^.file_name := StrNew(PChar(FrameList.ValueAt[I].AsTuple['fullname'].AsString));
  167. end;
  168. end;
  169. function TGDBController.LoadFile(var fn: string): Boolean;
  170. var
  171. cmd: string;
  172. begin
  173. getdir(0,cmd);
  174. UnixDir(cmd);
  175. Command('-environment-cd ' + cmd);
  176. GDBOutputBuf.Reset;
  177. GDBErrorBuf.Reset;
  178. UnixDir(fn);
  179. Command('-file-exec-and-symbols ' + fn);
  180. LoadFile := True;
  181. end;
  182. procedure TGDBController.SetDir(const s: string);
  183. var
  184. hs: string;
  185. begin
  186. hs:=s;
  187. UnixDir(hs);
  188. Command('-environment-cd ' + hs);
  189. end;
  190. procedure TGDBController.SetArgs(const s: string);
  191. begin
  192. Command('-exec-arguments ' + s);
  193. end;
  194. end.