151
152
function SetUnhandledExceptionFilter(lpTopLevelExceptionFilter : LPTOP_LEVEL_EXCEPTION_FILTER)
152
153
: LPTOP_LEVEL_EXCEPTION_FILTER;
153
external 'kernel32' name 'SetUnhandledExceptionFilter';
154
stdcall; external 'kernel32' name 'SetUnhandledExceptionFilter';
156
157
signal_list : Array[SIGABRT..SIGMAX] of SignalHandler;
158
159
{ value of the stack segment
159
160
to check if the call stack can be written on exceptions }
163
164
fpucw : word = $1332;
167
function Signals_exception_handler(excep :PEXCEPTION_POINTERS) : longint;stdcall;
165
Exception_handler_installed : boolean = false;
167
except_level : byte = 0;
169
except_eip : array[0..Max_level-1] of longint;
170
except_signal : array[0..Max_level-1] of longint;
171
reset_fpu : array[0..max_level-1] of boolean;
173
procedure JumpToHandleSignal;
175
res, eip, _ebp, sigtype : longint;
181
Writeln('In start of JumpToHandleSignal');
182
if except_level>0 then
186
eip:=except_eip[except_level];
188
sigtype:=except_signal[except_level];
189
if reset_fpu[except_level] then
194
if assigned(System_exception_frame) then
195
{ get the handler in front again }
197
movl System_exception_frame,%eax
200
if (sigtype>=SIGABRT) and (sigtype<=SIGMAX) and
201
(signal_list[sigtype]<>@SIG_DFL) then
203
res:=signal_list[sigtype](sigtype);
210
Writeln('In JumpToHandleSignal');
214
{ jump back to old code }
227
function Signals_exception_handler
228
(excep_exceptionrecord :PEXCEPTION_RECORD;
229
excep_frame : PEXCEPTION_FRAME;
230
excep_contextrecord : PCONTEXT;
231
dispatch : pointer) : longint;stdcall;
168
232
var frame,res : longint;
169
function CallSignal(error,frame : longint;must_reset_fpu : boolean) : longint;
233
function CallSignal(sigtype,frame : longint;must_reset_fpu : boolean) : longint;
171
CallSignal:=Exception_Continue_Search;
173
if must_reset_fpu then
235
writeln(stderr,'CallSignal called');
239
writeln(stderr,'CallSignal frame is zero');
243
if except_level >= Max_level then
245
except_eip[except_level]:=excep_ContextRecord^.Eip;
246
except_signal[except_level]:=sigtype;
247
reset_fpu[except_level]:=must_reset_fpu;
249
{dec(excep^.ContextRecord^.Esp,4);
250
plongint (excep^.ContextRecord^.Esp)^ := longint(excep^.ContextRecord^.Eip);}
251
excep_ContextRecord^.Eip:=longint(@JumpToHandleSignal);
252
excep_ExceptionRecord^.ExceptionCode:=0;
254
writeln(stderr,'Exception_Continue_Execution set');
179
if (error>=SIGABRT) and (error<=SIGMAX) and (signal_list[error]<>@SIG_DFL) then
180
res:=signal_list[error](error);
182
CallSignal:=Exception_Continue_Execution;
187
if excep^.ContextRecord^.SegSs=_SS then
188
frame:=excep^.ContextRecord^.Ebp
259
if excep_ContextRecord^.SegSs=_SS then
260
frame:=excep_ContextRecord^.Ebp
192
263
{ default : unhandled !}
193
res:=Exception_Continue_Search;
194
265
{$ifdef SYSTEMEXCEPTIONDEBUG}
195
266
if IsConsole then
196
writeln(stderr,'Exception ',
197
hexstr(excep^.ExceptionRecord^.ExceptionCode,8));
267
writeln(stderr,'Signals exception ',
268
hexstr(excep_ExceptionRecord^.ExceptionCode,8));
198
269
{$endif SYSTEMEXCEPTIONDEBUG}
199
case excep^.ExceptionRecord^.ExceptionCode of
270
case excep_ExceptionRecord^.ExceptionCode of
200
271
EXCEPTION_ACCESS_VIOLATION :
201
272
res:=CallSignal(SIGSEGV,frame,false);
202
273
{ EXCEPTION_BREAKPOINT = $80000003;
245
316
EXCEPTION_PRIV_INSTRUCTION,
246
317
EXCEPTION_IN_PAGE_ERROR,
247
318
EXCEPTION_SINGLE_STEP : res:=CallSignal(SIGSEGV,frame,false);
319
{ Ignore EXCEPTION_INVALID_HANDLE exceptions }
320
EXCEPTION_INVALID_HANDLE : res:=0;
249
322
Signals_exception_handler:=res;
326
function API_signals_exception_handler(except : PEXCEPTION_POINTERS) : longint; stdcall;
328
API_signals_exception_handler:=Signals_exception_handler(
329
@except^.ExceptionRecord,
331
@except^.ContextRecord,
337
PreviousHandler : LPTOP_LEVEL_EXCEPTION_FILTER = nil;
338
Prev_Handler : pointer = nil;
339
Prev_fpc_handler : pointer = nil;
253
341
procedure install_exception_handler;
254
342
{$ifdef SYSTEMEXCEPTIONDEBUG}
256
344
oldexceptaddr,newexceptaddr : longint;
257
345
{$endif SYSTEMEXCEPTIONDEBUG}
347
if Exception_handler_installed then
349
if assigned(System_exception_frame) then
351
prev_fpc_handler:=System_exception_frame^.handler;
352
System_exception_frame^.handler:=@Signals_exception_handler;
353
{ get the handler in front again }
356
movl %eax,prev_handler
357
movl System_exception_frame,%eax
360
Exception_handler_installed:=true;
259
363
{$ifdef SYSTEMEXCEPTIONDEBUG}
271
375
movl %eax,newexceptaddr
273
377
if IsConsole then
274
writeln(stderr,'Old exception ',hexstr(oldexceptaddr,8),
275
' new exception ',hexstr(newexceptaddr,8));
379
writeln(stderr,'Old exception ',hexstr(oldexceptaddr,8),
380
' new exception ',hexstr(newexceptaddr,8));
381
writeln('SetUnhandledExceptionFilter returned ',hexstr(longint(PreviousHandler),8));
276
383
{$endif SYSTEMEXCEPTIONDEBUG}
384
Exception_handler_installed := true;
279
387
procedure remove_exception_handler;
281
SetUnhandledExceptionFilter(nil);
389
if not Exception_handler_installed then
391
if assigned(System_exception_frame) then
393
if assigned(prev_fpc_handler) then
394
System_exception_frame^.handler:=prev_fpc_handler;
395
prev_fpc_handler:=nil;
396
{ restore old handler order again }
397
if assigned(prev_handler) then
399
movl prev_handler,%eax
403
Exception_handler_installed:=false;
406
SetUnhandledExceptionFilter(PreviousHandler);
407
PreviousHandler:=nil;
408
Exception_handler_installed:=false;
285
function SIG_ERR(x:longint):longint;
412
function SIG_ERR(x:longint):longint; cdecl;
291
function SIG_IGN(x:longint):longint;
418
function SIG_IGN(x:longint):longint; cdecl;
297
function SIG_DFL(x:longint):longint;
424
function SIG_DFL(x:longint):longint; cdecl;