gdbcon.pp 6.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345
  1. {
  2. $Id$
  3. Copyright (c) 1998 by Peter Vreman
  4. Lowlevel GDB interface which communicates directly with libgdb
  5. See the file COPYING.FPC, included in this distribution,
  6. for details about the copyright.
  7. This program is distributed in the hope that it will be useful,
  8. but WITHOUT ANY WARRANTY; without even the implied warranty of
  9. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  10. **********************************************************************}
  11. unit GDBCon;
  12. interface
  13. uses
  14. GDBInt;
  15. type
  16. PGDBController=^TGDBController;
  17. TGDBController=object(TGDBInterface)
  18. progname : pchar;
  19. progargs : pchar;
  20. in_command,
  21. init_count : longint;
  22. constructor Init;
  23. destructor Done;
  24. procedure CommandBegin(const s:string);virtual;
  25. procedure Command(const s:string);
  26. procedure CommandEnd(const s:string);virtual;
  27. procedure Reset;virtual;
  28. { tracing }
  29. procedure StartTrace;
  30. procedure Run;virtual;
  31. procedure TraceStep;virtual;
  32. procedure TraceNext;virtual;
  33. procedure TraceStepI;virtual;
  34. procedure TraceNextI;virtual;
  35. procedure Continue;virtual;
  36. { needed for dos because newlines are only #10 (PM) }
  37. procedure WriteErrorBuf;
  38. procedure WriteOutputBuf;
  39. function GetOutput : Pchar;
  40. function GetError : Pchar;
  41. function LoadFile(var fn:string):boolean;
  42. procedure SetArgs(const s : string);
  43. procedure ClearSymbols;
  44. end;
  45. procedure UnixDir(var s : string);
  46. implementation
  47. uses
  48. {$ifdef win32}
  49. windows,
  50. {$endif win32}
  51. strings;
  52. {$ifdef win32}
  53. const
  54. CygDrivePrefixKey1 = 'Software';
  55. CygDrivePrefixKey2 = 'Cygnus Solutions';
  56. CygDrivePrefixKey3 = 'Cygwin';
  57. CygDrivePrefixKey4 = 'mounts v2';
  58. CygDrivePrefixKey = 'cygdrive prefix';
  59. function CygDrivePrefix : string;
  60. var
  61. i : longint;
  62. length : dword;
  63. Value : pchar;
  64. _type : dword;
  65. Key,NKey : HKey;
  66. begin
  67. Length:=0;
  68. Key:=HKEY_CURRENT_USER;
  69. i := RegOpenKeyEx(Key, CygDrivePrefixKey1, 0, KEY_ENUMERATE_SUB_KEYS, @NKey);
  70. if i=ERROR_SUCCESS then
  71. begin
  72. Key:=NKey;
  73. i := RegOpenKeyEx(Key, CygDrivePrefixKey2, 0, KEY_ENUMERATE_SUB_KEYS, @NKey);
  74. end;
  75. if i=ERROR_SUCCESS then
  76. begin
  77. RegCloseKey(Key);
  78. Key:=NKey;
  79. i := RegOpenKeyEx(Key, CygDrivePrefixKey3, 0, KEY_ENUMERATE_SUB_KEYS, @NKey);
  80. end;
  81. if i=ERROR_SUCCESS then
  82. begin
  83. RegCloseKey(Key);
  84. Key:=NKey;
  85. i := RegOpenKeyEx(Key, CygDrivePrefixKey4, 0, KEY_ENUMERATE_SUB_KEYS, @NKey);
  86. end;
  87. if i=ERROR_SUCCESS then
  88. begin
  89. RegCloseKey(Key);
  90. Key:=NKey;
  91. i := RegQueryValueEx( Key, CygDrivePrefixKey, nil, @_type, nil, @length);
  92. end;
  93. if i<>ERROR_SUCCESS then
  94. CygDrivePrefix:='/cygdrive'
  95. else
  96. Begin
  97. GetMem(Value,Length);
  98. i := RegQueryValueEx( Key, CygDrivePrefixKey, nil, @_type, LPByte(Value), @length);
  99. if i<>ERROR_SUCCESS then
  100. CygDrivePrefix:='/cygdrive'
  101. else
  102. CygDrivePrefix:=StrPas(Value);
  103. FreeMem(Value,Length);
  104. End;
  105. if Key<>HKEY_CURRENT_USER then
  106. RegCloseKey(Key);
  107. end;
  108. {$endif win32}
  109. procedure UnixDir(var s : string);
  110. var i : longint;
  111. begin
  112. for i:=1 to length(s) do
  113. if s[i]='\' then
  114. {$ifdef win32}
  115. { Don't touch at '\ ' used to escapes spaces in windows file names PM }
  116. if (i=length(s)) or (s[i+1]<>' ') then
  117. {$endif win32}
  118. s[i]:='/';
  119. {$ifdef win32}
  120. { for win32 we should convert e:\ into //e/ PM }
  121. if (length(s)>2) and (s[2]=':') and (s[3]='/') then
  122. s:=CygDrivePrefix+'/'+s[1]+copy(s,3,length(s));
  123. {$endif win32}
  124. end;
  125. constructor TGDBController.Init;
  126. begin
  127. inherited init;
  128. end;
  129. destructor TGDBController.Done;
  130. begin
  131. if assigned(progname) then
  132. strdispose(progname);
  133. if assigned(progargs) then
  134. strdispose(progargs);
  135. inherited done;
  136. end;
  137. procedure TGDBController.Command(const s:string);
  138. begin
  139. CommandBegin(s);
  140. gdboutputbuf.reset;
  141. gdberrorbuf.reset;
  142. inc(in_command);
  143. gdb_command(s);
  144. dec(in_command);
  145. {
  146. What is that for ?? PM
  147. I had to comment it because
  148. it resets the debuggere after each command !!
  149. Maybe it can happen on errors ??
  150. if in_command<0 then
  151. begin
  152. in_command:=0;
  153. inc(in_command);
  154. Reset;
  155. dec(in_command);
  156. end; }
  157. CommandEnd(s);
  158. end;
  159. procedure TGDBController.CommandBegin(const s:string);
  160. begin
  161. end;
  162. procedure TGDBController.CommandEnd(const s:string);
  163. begin
  164. end;
  165. function TGDBController.LoadFile(var fn:string):boolean;
  166. var
  167. cmd : string;
  168. begin
  169. getdir(0,cmd);
  170. UnixDir(cmd);
  171. cmd:='cd '+cmd;
  172. Command(cmd);
  173. GDB__Init;
  174. UnixDir(fn);
  175. if assigned(progname) then
  176. strdispose(progname);
  177. getmem(progname,length(fn)+1);
  178. strpcopy(progname,fn);
  179. if fn<>'' then
  180. Command('file '+fn);
  181. LoadFile:=true;
  182. end;
  183. procedure TGDBController.SetArgs(const s : string);
  184. begin
  185. if assigned(progargs) then
  186. strdispose(progargs);
  187. getmem(progargs,length(s)+1);
  188. strpcopy(progargs,s);
  189. command('set args '+s);
  190. end;
  191. procedure TGDBController.Reset;
  192. begin
  193. call_reset:=false;
  194. { DeleteBreakPoints(); }
  195. if debuggee_started then
  196. begin
  197. reset_command:=true;
  198. BreakSession;
  199. Command('kill');
  200. reset_command:=false;
  201. debuggee_started:=false;
  202. end;
  203. end;
  204. procedure TGDBController.StartTrace;
  205. begin
  206. Command('tbreak PASCALMAIN');
  207. Run;
  208. end;
  209. procedure TGDBController.Run;
  210. begin
  211. Command('run');
  212. inc(init_count);
  213. end;
  214. procedure TGDBController.TraceStep;
  215. begin
  216. Command('step');
  217. end;
  218. procedure TGDBController.TraceNext;
  219. begin
  220. Command('next');
  221. end;
  222. procedure TGDBController.TraceStepI;
  223. begin
  224. Command('stepi');
  225. end;
  226. procedure TGDBController.TraceNextI;
  227. begin
  228. Command('nexti');
  229. end;
  230. procedure TGDBController.Continue;
  231. begin
  232. Command('continue');
  233. end;
  234. procedure TGDBController.ClearSymbols;
  235. begin
  236. if debuggee_started then
  237. Reset;
  238. if init_count>0 then
  239. Command('file');
  240. end;
  241. procedure BufWrite(Buf : pchar);
  242. var p,pe : pchar;
  243. begin
  244. p:=buf;
  245. While assigned(p) do
  246. begin
  247. pe:=strscan(p,#10);
  248. if pe<>nil then
  249. pe^:=#0;
  250. Writeln(p);
  251. { restore for dispose }
  252. if pe<>nil then
  253. pe^:=#10;
  254. if pe=nil then
  255. p:=nil
  256. else
  257. begin
  258. p:=pe;
  259. inc(p);
  260. end;
  261. end;
  262. end;
  263. function TGDBController.GetOutput : Pchar;
  264. begin
  265. GetOutput:=gdboutputbuf.buf;
  266. end;
  267. function TGDBController.GetError : Pchar;
  268. var p : pchar;
  269. begin
  270. p:=gdberrorbuf.buf;
  271. if (p^=#0) and got_error then
  272. GetError:=pchar(longint(gdboutputbuf.buf)+gdboutputbuf.idx)
  273. else
  274. GetError:=p;
  275. end;
  276. procedure TGDBController.WriteErrorBuf;
  277. begin
  278. BufWrite(gdberrorbuf.buf);
  279. end;
  280. procedure TGDBController.WriteOutputBuf;
  281. begin
  282. BufWrite(gdboutputbuf.buf);
  283. end;
  284. end.
  285. {
  286. $Log$
  287. Revision 1.4 2002-09-07 15:42:51 peter
  288. * old logs removed and tabs fixed
  289. Revision 1.3 2002/04/03 09:09:22 pierre
  290. * fix UniwDir for win32 gdbcon.pp
  291. Revision 1.2 2002/03/26 16:23:14 pierre
  292. * get IDE to work with dirs containing spaces for win32
  293. Revision 1.1 2002/01/29 17:54:49 peter
  294. * splitted to base and extra
  295. }