dbugintf.pp 5.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282
  1. {
  2. This file is part of the Free Pascal run time library.
  3. Copyright (c) 2003 by the Free Pascal development team
  4. User interface for debug server.
  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. {$ifdef fpc}
  12. {$mode objfpc}
  13. {$h+}
  14. {$endif}
  15. unit dbugintf;
  16. interface
  17. uses
  18. {$ifdef fpc}
  19. baseunix,
  20. {$else}
  21. Libc,
  22. {$endif}
  23. msgintf,
  24. classes,
  25. ssockets;
  26. Type
  27. TDebugLevel = (dlInformation,dlWarning,dlError);
  28. {$ifdef fpc}
  29. pid_t = longint;
  30. {$endif}
  31. procedure SendBoolean(const Identifier: string; const Value: Boolean);
  32. procedure SendDateTime(const Identifier: string; const Value: TDateTime);
  33. procedure SendDebugEx(const Msg: string; MType: TDebugLevel);
  34. procedure SendDebug(const Msg: string);
  35. procedure SendInteger(const Identifier: string; const Value: Integer);
  36. procedure SendMethodEnter(const MethodName: string);
  37. procedure SendMethodExit(const MethodName: string);
  38. procedure SendSeparator;
  39. procedure SendDebugFmt(const Msg: string; const Args: array of const);
  40. procedure SendDebugFmtEx(const Msg: string; const Args: array of const; MType: TDebugLevel);
  41. { low-level routines }
  42. procedure SendDebugMessage(Const Msg : TDebugMessage);
  43. function CreateDebugStream : TStream;
  44. function StartDebugServer : pid_t;
  45. Procedure InitDebugStream;
  46. Const
  47. SendError : String = '';
  48. ResourceString
  49. SProcessID = 'Process %d: %s';
  50. SEntering = '> Entering ';
  51. SExiting = '< Exiting ';
  52. SSeparator = '>-=-=-=-=-=-=-=-=-=-=-=-=-=-=-<';
  53. implementation
  54. Uses SysUtils,process;
  55. // UnixProcessUtils;
  56. Const
  57. DmtInformation = lctInformation;
  58. DmtWarning = lctWarning;
  59. DmtError = lctError;
  60. ErrorLevel : Array[TDebugLevel] of integer
  61. = (dmtInformation,dmtWarning,dmtError);
  62. Const
  63. DebugStream : TStream = nil;
  64. Procedure WriteMessage(S : TStream; Const Msg : TDebugMessage);
  65. Var
  66. MsgSize : Integer;
  67. begin
  68. S.WriteBuffer(Msg.MsgType,SizeOf(Integer));
  69. S.WriteBuffer(Msg.MsgTimeStamp,SizeOf(TDateTime));
  70. MsgSize:=Length(Msg.Msg);
  71. S.WriteBuffer(MsgSize,SizeOf(Integer));
  72. S.WriteBuffer(Msg.msg[1],MsgSize);
  73. end;
  74. procedure SendDebugMessage(Const Msg : TDebugMessage);
  75. begin
  76. try
  77. If DebugStream=Nil then
  78. begin
  79. InitDebugStream;
  80. end;
  81. WriteMessage(debugStream,Msg);
  82. except
  83. On E : Exception do
  84. SendError:=E.Message;
  85. end;
  86. end;
  87. procedure SendBoolean(const Identifier: string; const Value: Boolean);
  88. Const
  89. Booleans : Array[Boolean] of string = ('False','True');
  90. begin
  91. SendDebugFmt('%s = %s',[Identifier,Booleans[value]]);
  92. end;
  93. procedure SendDateTime(const Identifier: string; const Value: TDateTime);
  94. begin
  95. SendDebugFmt('%s = %s',[Identifier,DateTimeToStr(Value)]);
  96. end;
  97. procedure SendDebugEx(const Msg: string; MType: TDebugLevel);
  98. Var
  99. Mesg : TDebugMessage;
  100. begin
  101. Mesg.MsgTimeStamp:=Now;
  102. Mesg.MsgType:=ErrorLevel[MTYpe];
  103. Mesg.Msg:=Msg;
  104. SendDebugMessage(Mesg);
  105. end;
  106. procedure SendDebug(const Msg: string);
  107. Var
  108. Mesg : TDebugMessage;
  109. begin
  110. Mesg.MsgTimeStamp:=Now;
  111. Mesg.MsgType:=dmtInformation;
  112. Mesg.Msg:=Msg;
  113. SendDebugMessage(Mesg);
  114. end;
  115. procedure SendInteger(const Identifier: string; const Value: Integer);
  116. begin
  117. SendDebugFmt('%s = %d',[identifier,Value]);
  118. end;
  119. procedure SendMethodEnter(const MethodName: string);
  120. begin
  121. SendDebug(SEntering+MethodName);
  122. end;
  123. procedure SendMethodExit(const MethodName: string);
  124. begin
  125. SendDebug(SExiting+MethodName);
  126. end;
  127. procedure SendSeparator;
  128. begin
  129. SendDebug(SSeparator);
  130. end;
  131. procedure SendDebugFmt(const Msg: string; const Args: array of const);
  132. Var
  133. Mesg : TDebugMessage;
  134. begin
  135. Mesg.MsgTimeStamp:=Now;
  136. Mesg.MsgType:=dmtInformation;
  137. Mesg.Msg:=Format(Msg,Args);
  138. SendDebugMessage(Mesg);
  139. end;
  140. procedure SendDebugFmtEx(const Msg: string; const Args: array of const; MType: TDebugLevel);
  141. Var
  142. Mesg : TDebugMessage;
  143. begin
  144. Mesg.MsgTimeStamp:=Now;
  145. Mesg.MsgType:=ErrorLevel[mType];
  146. Mesg.Msg:=Format(Msg,Args);
  147. SendDebugMessage(Mesg);
  148. end;
  149. function StartDebugServer : pid_t;
  150. begin
  151. With TProcess.Create(Nil) do
  152. Try
  153. CommandLine:='debugserver';
  154. Execute;
  155. Finally
  156. Free;
  157. end;
  158. end;
  159. function CreateUnixDebugStream(SocketFile : String) : TStream;
  160. {$ifdef fpc}
  161. Var
  162. tv,tr : timespec;
  163. {$endif}
  164. begin
  165. If Not FileExists(DebugSocket) then
  166. begin
  167. StartDebugServer;
  168. {$ifndef fpc}
  169. sleep(1000);
  170. {$else}
  171. tv.tv_sec:=1;
  172. tv.tv_nsec:=0;
  173. fpnanosleep(@tv,@tr);
  174. {$endif}
  175. end;
  176. {$ifdef fpc}
  177. Result:=TUnixSocket.Create(SocketFile);
  178. {$else}
  179. Result:=TUnixSocket.CreateFromFile(SocketFile);
  180. {$endif}
  181. end;
  182. Function CreateInetDebugStream (HostName : String; Port : Word) : TStream;
  183. begin
  184. Result:=TInetSocket.Create(HostName,Port);
  185. end;
  186. function CreateDebugStream : TStream;
  187. Var
  188. Msg : TDebugMessage;
  189. begin
  190. Case DebugConnection of
  191. dcUnix : Result:=CreateUnixDebugStream(DebugSocket);
  192. dcInet : Result:=CreateInetDebugStream(DebugHostName,DebugPort);
  193. end;
  194. Msg.MsgType:=lctIdentify;
  195. Msg.MsgTimeStamp:=Now;
  196. Msg.Msg:=Format(SProcessID,[fpgetPID,ExtractFileName(Paramstr(0))]);
  197. WriteMessage(REsult,Msg);
  198. end;
  199. procedure FreeDebugStream;
  200. Var i : Integer;
  201. begin
  202. If (DebugStream<>Nil) then
  203. try
  204. i:=-1;
  205. DebugStream.WriteBuffer(I,SizeOf(I));
  206. DebugStream.Free;
  207. except
  208. end;
  209. end;
  210. Procedure InitDebugStream;
  211. begin
  212. debugstream:=CreateDebugStream;
  213. end;
  214. Initialization
  215. Finalization
  216. FreeDebugStream;
  217. end.