"Lubos" == Lubos Lunak <l.lunak@suse.cz> writes:
Tom> Is there something we could do to improve it?
Lubos> I don't know how much control gdb over exception handling has,
Lubos> so I don't know :).
:-)
FWIW we have the same problem in reverse: the gdb group at Red Hat is,
among other things, tasked with improving the C++ debugging experience.
However, most of us don't actually debug C++ programs on a regular
basis. We do know some issues, via bugzilla and other discussions, but
I feel sure we are also missing things.
Lubos> What I was refering to was the problem that if a catch block
Lubos> catches an exception, it's often difficult to find out where it
Lubos> actually came from. Using 'catch catch' doesn't show where it
Lubos> originated (unless I missed a non-obvious way). And if the
Lubos> exception propagated out of complex nesting of function calls,
Lubos> then 'catch throw' may trigger a number of times for exceptions
Lubos> that will be handled elsewhere.
Solving this in general looks tricky to me. I am not really sure how to
do it, but I will think about it some more.
The basic issue is that if 'catch throw' triggers multiple times for the
same exception, then it seems that there must be code that catches the
exception and then throws it again:
try { } catch (blah) { throw blah; }
As opposed to a true re-throw:
try { } catch (blah) { throw; }
AFAIK re-throws are currently not caught, see
http://sourceware.org/bugzilla/show_bug.cgi?id=12824
I'm not sure whether it is possible to easily detect whether "throw x"
is throwing some object which has already been thrown.
Hopefully I'm misunderstanding the problem :)
Meanwhile, I did whip up a quick-and-dirty Python-based approach. It
adds a new "track-throws" command. This command installs a breakpoint
that records the point of the most recent "throw". Then you can examine
the result with "info last-throw".
Here it is in action:
(gdb) source track_throw.py
(gdb) track-throws
Breakpoint 1 at 0x400910
(gdb) catch catch
Catchpoint 2 (catch)
(gdb) run
[...]
Catchpoint 2 (exception caught), __cxxabiv1::__cxa_begin_catch (
exc_obj_in=0x602070) at ../../../../libstdc++-v3/libsupc++/eh_catch.cc:41
41 {
(gdb) info last-throw
Last exception thrown at file ../../../archer/gdb/testsuite/gdb.cp/nextoverthrow.cc, line 36
"track-throws" makes the breakpoint it installs user-visible so you can
disable the feature simply by deleting the breakpoint.
I'm curious to know if this is useful to you.
Tom
import gdb
last_sal = None
throw_bp = None
class ThrowTracker(gdb.Breakpoint):
def __init__(self):
gdb.Breakpoint.__init__(self, '__cxa_throw')
def stop(self):
global last_sal
frame = gdb.newest_frame().older()
last_sal = frame.find_sal()
return False
class TrackThrows(gdb.Command):
def __init__(self):
gdb.Command.__init__(self, 'track-throws', gdb.COMMAND_BREAKPOINTS)
def invoke(self, arg, from_tty):
global throw_bp
if throw_bp is None or not throw_bp.is_valid():
# Still no good way to create a pending breakpoint from
# Python.
save = gdb.parameter('breakpoint pending')
gdb.execute('set breakpoint pending on', to_string = True)
throw_bp = ThrowTracker()
if save is None:
arg = 'auto'
elif save:
arg = 'on'
else:
arg = 'off'
gdb.execute('set breakpoint pending %s' % arg, to_string = True)
class InfoThrow(gdb.Command):
def __init__(self):
gdb.Command.__init__(self, 'info last-throw', gdb.COMMAND_BREAKPOINTS)
def invoke(self, arg, from_tty):
global last_sal
if last_sal is not None:
filename = last_sal.symtab.filename
line = last_sal.line
print "Last exception thrown at file %s, line %d" % (filename, line)
else:
print "No previous exception seen"
TrackThrows()
InfoThrow()
Context
Privacy Policy |
Impressum (Legal Info) |
Copyright information: Unless otherwise specified, all text and images
on this website are licensed under the
Creative Commons Attribution-Share Alike 3.0 License.
This does not include the source code of LibreOffice, which is
licensed under the Mozilla Public License (
MPLv2).
"LibreOffice" and "The Document Foundation" are
registered trademarks of their corresponding registered owners or are
in actual use as trademarks in one or more countries. Their respective
logos and icons are also subject to international copyright laws. Use
thereof is explained in our
trademark policy.