This is the mail archive of the
archer@sourceware.org
mailing list for the Archer project.
[RFC] Set unwindonsignal to on by default
- From: Phil Muldoon <pmuldoon at redhat dot com>
- To: Project Archer <archer at sourceware dot org>
- Date: Wed, 17 Sep 2008 18:55:40 +0100
- Subject: [RFC] Set unwindonsignal to on by default
I wonder if there a world record for the longest description of a one
line patch. I'll describe the problem....
For most systems GCC uses the exception handling strategy documented
here: http://www.codesourcery.com/public/cxx-abi/
This strategy tries to find an exception handler firstly "in frame"; if
none is found, it unwinds the stack until it finds a handler that can
handle the exception. If it cannot find an exception handler anywhere
in the stack, it calls std::terminate. This checks to see if there is a
custom "default handler" and if found, executes that. If it cannot find
a custom "default handler", or when a custom handler returns, std::abort
is called and the process exits subsequent to being delivered a SIGABRT.
That is a gross simplication of the sequence, but that is the basic
strategy. In the normal execution of a process, this is sane and correct
- if there is no handler for an exception anywhere in the stack, there
is little else than can be done. However in the artifically constructed
environment of the debugger controlling the inferior, it can become
problematic in some situations. Inferior function calls are one of the
situations where this becomes problematic.
In GDB inferior function calls are very common. For example:
(gdb) print foo()
Will print the result (return value) of that function. To do that GDB
must create an inferior function call that executes the function in a
dummy frame. This isolated and dummy frame is problematic as it cannot
be unwound (moving up the stack) beyond the dummy frame.
If an exception is generated by foo() when the function is being
executed in the inferior function call, and it does not happen to have
an in-frame exception handler, the whole inferior is (wrongly)
terminated. This is because any out-of-frame exception handler that
usually handles exceptions in function foo() and are normally "up" in
the stack will not be considered. The inferior is terminated as detailed
above, has to be restarted, and brought back to state by the (probably
frustrated) user. This is wrong in my opinion. It is perfectly legal to
have a function handler out-of-frame, and in normal execution it would
be found and handled; but the artificial environment constructed around
the frame for the purpose of the inferior function call "fools" the
unwinder and terminates the inferior.
There is a flag in GDB named: "unwindonsignal" that is currently set to
"off". This flag tells the inferior function call code that *if* a
signal is delivered to the inferior during an inferior function call, to
unwind the stack to the state before the dummy frame was completed. This
restores the state of the inferior as if the inferior function call (for
all intents and purposes,) did not happen. This does not fix the
exception issue - out-of-frame exception handlers are still not found
when a dummy frame is created. But it does fix the worst complications
and does not terminate the inferior.
I propose via this patch that we set the flag to "on" as default. It can
always be turned off if the user desires it. Defaulting to "on" will
improve the C++ user experience. A longer term approach would be as
Daniel suggested: a command to restore the frame and clears the signal
"after the fact" if the user wants to do so. This is longer term, but
equally valid. Another alternative would be to leave "unwindonsignal"
off, create an internal breakpoint in std::terminate, and if that
"triggers" unwind (perhaps with a flag "unwindonterminate" gating the
feature).
Regards
Phil
2008-09-17 Phil Muldoon <pmuldoon@redhat.com>
* infcall.c: Set unwind_on_signal_p to 1
by default.
diff --git a/gdb/infcall.c b/gdb/infcall.c
index a6371ea..4dd16e7 100644
--- a/gdb/infcall.c
+++ b/gdb/infcall.c
@@ -81,7 +81,7 @@ Coercion of floats to doubles when calling functions is %s.\n"),
The default is to stop in the frame where the signal was received. */
-int unwind_on_signal_p = 0;
+int unwind_on_signal_p = 1;
static void
show_unwind_on_signal_p (struct ui_file *file, int from_tty,
struct cmd_list_element *c, const char *value)