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