The below patch adds --gpc-rts=-trap-on-error (aka --gpc-rts=-t) to the gpc runtime lib.
This is quite useful * when debugging with gdb * when debugging with visual front-ends to gdb * on systems where WriteStackDump does nothing * on systems that automatically report and log backtraces (like Darwin).
diff -ur gcc-3.4.5-orig/gcc/p/rts/error.pas gcc-3.4.5/gcc/p/rts/ error.pas --- gcc-3.4.5-orig/gcc/p/rts/error.pas 2005-12-15 17:41:59.000000000 +0100 +++ gcc-3.4.5/gcc/p/rts/error.pas 2005-12-19 17:09:15.000000000 +0100 @@ -95,6 +95,7 @@ RTSOptions: Integer = 0; attribute (name = '_p_RTSOptions'); RTSWarnFlag: Boolean = False; attribute (name = '_p_RTSWarnFlag'); AbortOnError: Boolean = False; attribute (name = '_p_AbortOnError'); + TrapOnError: Boolean = False; attribute (name = '_p_TrapOnError');
CurrentReturnAddr: Pointer = nil; attribute (name = '_p_CurrentReturnAddr'); CurrentReturnAddrCounter: Integer = 0; attribute (name = '_p_CurrentReturnAddrCounter'); @@ -890,6 +891,19 @@ {$endlocal} end;
+procedure TrapError; attribute (inline); +begin +{$ifdef __i386__} + asm("int3") +{$else} +{$ifdef __ppc__} + asm("trap") +{$else} + BuiltinTrap; +{$endif} +{$endif} +end; + procedure EndRuntimeError (n: Integer); attribute (noreturn, name = '_p_EndRuntimeError'); begin FinishErrorMessage (n); @@ -898,6 +912,8 @@ Finalize1; RestoreReturnAddress; if (RTSErrorFD >= 0) then Discard (CloseHandle (RTSErrorFD)); { just to be sure } + if TrapOnError then + TrapError; ExitProgram (RuntimeErrorExitValue, AbortOnError) end;
diff -ur gcc-3.4.5-orig/gcc/p/rts/init.pas gcc-3.4.5/gcc/p/rts/init.pas --- gcc-3.4.5-orig/gcc/p/rts/init.pas 2005-12-15 17:41:59.000000000 +0100 +++ gcc-3.4.5/gcc/p/rts/init.pas 2005-12-19 15:34:26.000000000 +0100 @@ -94,6 +94,7 @@ -h, --help Display this help and exit -v, --version Output RTS version information and exit -a, --abort-on-error Abort with SIGABRT on runtime error +-t, --trap-on-error Trap or break into debugger on runtime error -e, --eoln-hack Toggle EOLn hack right after Reset for terminals -i LINE, --input LINE Implicitly add LINE to the beginning of Input -n INTERNAL_NAME:EXTERNAL_NAME, --file-name[=] INTERNAL_NAME:EXTERNAL_NAME @@ -117,11 +118,12 @@
function DoOption: Boolean; const - LongOptions: array [1 .. 12] of OptionType = + LongOptions: array [1 .. 13] of OptionType = ((Prefix, NoArgument, nil, '='), ('help', NoArgument, nil, 'h'), ('version', NoArgument, nil, 'v'), ('abort-on-error', NoArgument, nil, 'a'), + ('trap-on-error', NoArgument, nil, 't'), ('eoln-hack', NoArgument, nil, 'e'), ('input', RequiredArgument, nil, 'i'), ('file-name', RequiredArgument, nil, 'n'), @@ -167,6 +169,7 @@ Halt end; 'a': AbortOnError := True; + 't': TrapOnError := True; 'e': EOLnResetHack := not EOLnResetHack; 'i': begin { Strings written to CurrentStdIn, given as first standard input to user program } diff -ur gcc-3.4.5-orig/gcc/p/rts/rts.c gcc-3.4.5/gcc/p/rts/rts.c --- gcc-3.4.5-orig/gcc/p/rts/rts.c 2005-12-15 17:41:59.000000000 +0100 +++ gcc-3.4.5/gcc/p/rts/rts.c 2005-12-19 17:02:50.000000000 +0100 @@ -2599,6 +2599,13 @@ #endif }
+GLOBAL (void _p_BuiltinTrap (void)) +{ +#if (__GNUC__ >= 3) + __builtin_trap(); +#endif +} + GLOBAL_ATTR (void _p_ExitProgram (int Status, Boolean AbortFlag UNUSED), noreturn) { #ifdef HAVE_ABORT diff -ur gcc-3.4.5-orig/gcc/p/rts/rtsc.pas gcc-3.4.5/gcc/p/rts/rtsc.pas --- gcc-3.4.5-orig/gcc/p/rts/rtsc.pas 2005-12-15 17:41:59.000000000 +0100 +++ gcc-3.4.5/gcc/p/rts/rtsc.pas 2005-12-19 17:11:07.000000000 +0100 @@ -414,6 +414,7 @@ function CGetPwEnt (var Entries: PCPasswordEntries): CInteger; external name '_p_CGetPwEnt'; procedure InitMisc; external name '_p_InitMisc'; procedure InitMalloc (procedure WarnProc (Msg: CString)); external name '_p_InitMalloc'; +procedure BuiltinTrap; external name '_p_BuiltinTrap'; procedure ExitProgram (Status: CInteger; AbortFlag: Boolean); attribute (noreturn); external name '_p_ExitProgram'; {@endinternal}
Note that the Linux kernel (in bug.h) works around problems with __builtin_trap for some versions of gcc in combination with sparc or ia-64. This is done by directly emitting assembly code, just like TrapError does in the diff. However, I can't test sparc and ia-64, so something similar has not (yet) been implemented. I did implement a workaround for __i386__ where __builtin_trap emits int5 instead of int3 (or at least that is what it does on i386-apple-darwin and that is what i386.md describes in gcc-3.4.5).
I hope this is useful.
Regards,
Adriaan van Os