fpcatch.pas 6.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287
  1. {
  2. $Id$
  3. Copyright (c) 1997-98 by Michael Van Canneyt
  4. Unit to catch segmentation faults and Ctrl-C and exit gracefully
  5. under linux and go32v2
  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 fpcatch;
  13. interface
  14. {$i globdir.inc}
  15. {$ifdef Unix}
  16. uses
  17. {$ifdef VER1_0}
  18. linux;
  19. {$else}
  20. unix;
  21. {$endif}
  22. {$endif}
  23. {$ifdef go32v2}
  24. uses
  25. dpmiexcp;
  26. {$endif}
  27. {$ifdef win32}
  28. uses
  29. windows, signals;
  30. {$endif}
  31. {$ifdef HasSignal}
  32. Var
  33. NewSignal,OldSigSegm,OldSigILL,
  34. OldSigInt,OldSigFPE : SignalHandler;
  35. {$endif}
  36. Const
  37. CtrlCPressed : Boolean = false;
  38. Procedure EnableCatchSignals;
  39. Procedure DisableCatchSignals;
  40. {$ifdef DEBUG}
  41. procedure Generate_SIGSEGV;
  42. procedure Generate_SIGFPE;
  43. {$endif DEBUG}
  44. {$ifndef GABOR}
  45. var
  46. StopJmp : Jmp_Buf;
  47. const
  48. StopJmpValid : boolean = false;
  49. {$endif}
  50. Implementation
  51. uses
  52. {$ifdef FPC}
  53. keyboard,
  54. drivers,
  55. {$endif FPC}
  56. {$ifdef FVISION}
  57. FVConsts,
  58. {$else}
  59. Commands,
  60. {$endif}
  61. dos,app,msgbox,
  62. FPString,FPCompil,FPIDE;
  63. Const
  64. LastCtrlC : longint = 0;
  65. {$ifdef DEBUG}
  66. procedure Generate_SIGSEGV;
  67. var
  68. l : plongint;
  69. begin
  70. { Force a SIGSEGV }
  71. l:=$ffffffff;
  72. l^:=1;
  73. end;
  74. procedure Generate_SIGFPE;
  75. var
  76. x,y : real;
  77. begin
  78. { Force a SIGFPE }
  79. y:=-5;
  80. x:=sqrt(y);
  81. end;
  82. {$endif DEBUG}
  83. {$ifdef HasSignal}
  84. {$ifdef Unix}
  85. Procedure CatchSignal(Sig : Integer);cdecl;
  86. {$else}
  87. Function CatchSignal(Sig : longint):longint;
  88. {$endif}
  89. var MustQuit: boolean;
  90. begin
  91. case Sig of
  92. SIGSEGV : begin
  93. if StopJmpValid then
  94. LongJmp(StopJmp,SIGSEGV);
  95. if Assigned(Application) then IDEApp.Done;
  96. Writeln('Internal SIGSEGV Error caught');
  97. {$ifndef DEBUG}
  98. Halt;
  99. {$else DEBUG}
  100. RunError(216);
  101. {$endif DEBUG}
  102. end;
  103. SIGFPE : begin
  104. if StopJmpValid then
  105. LongJmp(StopJmp,SIGFPE);
  106. if Assigned(Application) then IDEApp.Done;
  107. Writeln('Internal SIGFPE Error caught');
  108. {$ifndef DEBUG}
  109. Halt;
  110. {$else DEBUG}
  111. RunError(207);
  112. {$endif DEBUG}
  113. end;
  114. SIGILL : begin
  115. if StopJmpValid then
  116. LongJmp(StopJmp,SIGILL);
  117. if Assigned(Application) then IDEApp.Done;
  118. Writeln('Internal SIGILL Error caught');
  119. {$ifndef DEBUG}
  120. Halt;
  121. {$else DEBUG}
  122. RunError(216);
  123. {$endif DEBUG}
  124. end;
  125. SIGINT : begin
  126. if StopJmpValid then
  127. LongJmp(StopJmp,SIGINT);
  128. IF NOT CtrlCPressed and Assigned(Application) then
  129. begin
  130. MustQuit:=false;
  131. {$ifdef FPC}
  132. if GetDosTicks>LastCtrlC+10 then
  133. begin
  134. CtrlCPressed:=true;
  135. Keyboard.PutKeyEvent((kbCtrl shl 16) or kbCtrlC);
  136. LastCtrlC:=GetDosTicks;
  137. end;
  138. {$endif FPC}
  139. end
  140. else
  141. begin
  142. if Assigned(Application) then
  143. MustQuit:=MessageBox(#3+msg_QuitConfirm,nil,mferror+mfyesbutton+mfnobutton)=cmYes
  144. else
  145. MustQuit:=true;
  146. end;
  147. if MustQuit then
  148. begin
  149. if Assigned(Application) then IDEApp.Done;
  150. {$ifndef DEBUG}
  151. Halt;
  152. {$else DEBUG}
  153. RunError(216);
  154. {$endif DEBUG}
  155. end;
  156. end;
  157. end;
  158. {$ifndef Unix}
  159. CatchSignal:=0;
  160. {$endif}
  161. end;
  162. {$endif def HasSignal}
  163. Const
  164. CatchSignalsEnabled : boolean = false;
  165. Procedure EnableCatchSignals;
  166. {$ifdef win32}
  167. var Mode: DWORD;
  168. {$endif win32}
  169. begin
  170. if CatchSignalsEnabled then
  171. exit;
  172. {$ifdef win32}
  173. if GetConsoleMode(GetStdHandle(Std_Input_Handle), @Mode) then
  174. SetConsoleMode(GetStdHandle(Std_Input_Handle), (Mode or ENABLE_MOUSE_INPUT) and not ENABLE_PROCESSED_INPUT);
  175. {$endif win32}
  176. {$ifdef go32v2}
  177. djgpp_set_ctrl_c(false);
  178. {$endif go32v2}
  179. {$ifdef HasSignal}
  180. {$ifndef TP}
  181. NewSignal:=SignalHandler(@CatchSignal);
  182. {$else TP}
  183. NewSignal:=SignalHandler(CatchSignal);
  184. {$endif TP}
  185. OldSigSegm:=Signal (SIGSEGV,NewSignal);
  186. OldSigInt:=Signal (SIGINT,NewSignal);
  187. OldSigFPE:=Signal (SIGFPE,NewSignal);
  188. OldSigILL:=Signal (SIGILL,NewSignal);
  189. CatchSignalsEnabled:=true;
  190. {$endif}
  191. end;
  192. Procedure DisableCatchSignals;
  193. begin
  194. {$ifdef HasSignal}
  195. if not CatchSignalsEnabled then
  196. exit;
  197. Signal (SIGSEGV,OldSigSegm);
  198. Signal (SIGINT,OldSigInt);
  199. Signal (SIGFPE,OldSigFPE);
  200. Signal (SIGILL,OldSigILL);
  201. CatchSignalsEnabled:=false;
  202. {$endif}
  203. end;
  204. end.
  205. {
  206. $Log$
  207. Revision 1.4 2002-03-20 14:48:27 pierre
  208. * moved StopJmp buffer to fpcatch unit
  209. Revision 1.3 2001/10/24 14:17:27 pierre
  210. * try to fix the Win2000 mouse problem
  211. Revision 1.2 2001/08/05 02:01:47 peter
  212. * FVISION define to compile with fvision units
  213. Revision 1.1 2001/08/04 11:30:22 peter
  214. * ide works now with both compiler versions
  215. Revision 1.1.2.4 2000/11/30 13:04:01 pierre
  216. * fix for bug 1205
  217. Revision 1.1.2.3 2000/11/29 00:54:44 pierre
  218. + preserve window number and save special windows
  219. Revision 1.1.2.2 2000/11/14 09:23:55 marco
  220. * Second batch
  221. Revision 1.1.2.1 2000/10/31 07:52:55 pierre
  222. * recover gracefully if compiler generates a signal
  223. Revision 1.1 2000/07/13 09:48:34 michael
  224. + Initial import
  225. Revision 1.6 2000/06/22 09:07:11 pierre
  226. * Gabor changes: see fixes.txt
  227. Revision 1.5 2000/05/02 08:42:26 pierre
  228. * new set of Gabor changes: see fixes.txt
  229. Revision 1.4 2000/03/07 21:09:20 pierre
  230. * Use globdir.inc HasSignal conditional
  231. + Uses PutKeyEvent for CtrlC
  232. Revision 1.3 1999/12/20 14:23:16 pierre
  233. * MyApp renamed IDEApp
  234. * TDebugController.ResetDebuggerRows added to
  235. get resetting of debugger rows
  236. Revision 1.2 1999/04/07 21:55:42 peter
  237. + object support for browser
  238. * html help fixes
  239. * more desktop saving things
  240. * NODEBUG directive to exclude debugger
  241. Revision 1.1 1999/02/20 15:18:28 peter
  242. + ctrl-c capture with confirm dialog
  243. + ascii table in the tools menu
  244. + heapviewer
  245. * empty file fixed
  246. * fixed callback routines in fpdebug to have far for tp7
  247. }