Re: Gdb support for exceptions (Re: using backtrace() in exception throwing?)
On 05/31/2013 09:33 PM, Tom Tromey wrote: Tom I think it may be fixable in GCC. I filed a GCC bug: http://gcc.gnu.org/bugzilla/show_bug.cgi?id=57487 You can CC yourself on it if you want to see what happens. Great, thanks. (So your idea would be to, in a second step, teach ABRT to issue additional gdb commands besides backtrace in case the trace contains __gnu_cxx::__verbose_terminate_handler, right?) Stephan ___ LibreOffice mailing list LibreOffice@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/libreoffice
Re: Gdb support for exceptions (Re: using backtrace() in exception throwing?)
Stephan == Stephan Bergmann sberg...@redhat.com writes: Stephan Great, thanks. (So your idea would be to, in a second step, teach Stephan ABRT to issue additional gdb commands besides backtrace in case the Stephan trace contains __gnu_cxx::__verbose_terminate_handler, right?) If that GCC bug is fixed, then the existing bt full would capture the type information. The info would appear in a mangled form, but it is trivial to run that through c++filt. Like in my example: t = 0x601060 _ZTIi@@CXXABI_1.3 - $ c++filt _ZTIi typeinfo for int Tom ___ LibreOffice mailing list LibreOffice@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/libreoffice
Re: Gdb support for exceptions (Re: using backtrace() in exception throwing?)
On 06/03/2013 04:36 PM, Tom Tromey wrote: Stephan == Stephan Bergmann sberg...@redhat.com writes: Stephan Great, thanks. (So your idea would be to, in a second step, teach Stephan ABRT to issue additional gdb commands besides backtrace in case the Stephan trace contains __gnu_cxx::__verbose_terminate_handler, right?) If that GCC bug is fixed, then the existing bt full would capture the type information. The info would appear in a mangled form, but it is trivial to run that through c++filt. Ah, right; I'd failed to note how bt full also prints local vars, and how e.g. ABRT already uses that. Stephan ___ LibreOffice mailing list LibreOffice@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/libreoffice
Re: Gdb support for exceptions (Re: using backtrace() in exception throwing?)
Tom I think it may be fixable in GCC. I filed a GCC bug: http://gcc.gnu.org/bugzilla/show_bug.cgi?id=57487 You can CC yourself on it if you want to see what happens. Tom ___ LibreOffice mailing list LibreOffice@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/libreoffice
Re: Gdb support for exceptions (Re: using backtrace() in exception throwing?)
On 02/20/2013 10:28 PM, Tom Tromey wrote: 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. One related thing that struck me now is how __gnu_cxx::__verbose_terminate_handler prints out a helpful message to stderr, but if all you have is a gdb backtrace upon the resulting SIGABRT (like in thread 1 of https://bugzilla.redhat.com/attachment.cgi?id=754479 attached to https://bugzilla.redhat.com/show_bug.cgi?id=968424 ABRT report), you cannot see what that message was. It would be cool if there were a way to see that message in the gdb backtrace. Like __gnu_cxx::__verbose_terminate_handler assembling the message and then calling a not-optimized-away helper function with the message as argument, which in turn calls fputs and abort (though I notice that __verbose_terminate_handler currently assembles messages through multiple calls to fputs, which saves it from malloc hassles). Stephan ___ LibreOffice mailing list LibreOffice@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/libreoffice
Re: Gdb support for exceptions (Re: using backtrace() in exception throwing?)
Stephan == Stephan Bergmann sberg...@redhat.com writes: Stephan It would be cool if there were a way to see that message in the gdb Stephan backtrace. Like __gnu_cxx::__verbose_terminate_handler assembling the Stephan message and then calling a not-optimized-away helper function with the Stephan message as argument, which in turn calls fputs and abort (though I Stephan notice that __verbose_terminate_handler currently assembles messages Stephan through multiple calls to fputs, which saves it from malloc hassles). I think it may be fixable in GCC. Right now the issue is that 't' is optimized away; but in a local build I can see: (gdb) info local terminating = true t = 0x601060 _ZTIi@@CXXABI_1.3 ... which, while not completely readable, is at least transformable with c++filt or maint demangle. I pinged a local GCC hacker, I'll let you know if he thinks this is fixable. Tom ___ LibreOffice mailing list LibreOffice@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/libreoffice
Re: Gdb support for exceptions (Re: using backtrace() in exception throwing?)
Tom I think it isn't possible in general. When an exception is thrown, I Tom think all that can really be determined is the next catch point. Michael This would be perfect. Explicit rethrows are relatively rare in Michael our code, however it is completely normal to have code that we Michael simply don't understand and/or follow - whereby we do: Unfortunately, it is even worse than I made it out to be. The next catch point also includes the spots where unwinding pauses to invoke destructors. So, at the lowest level you can't easily associate a throw with a catch that you would see in the source. You can only see to spot that calls the next destructor. If you're interested you can see this in action by breaking at the libgcc:unwind probe point (or equivalently _Unwind_DebugHook but then you have to do argument decoding by hand), then disassem $_probe_arg1. That will show you the assembly for where you're about to unwind to. (catch catch and catch throw hook into somewhat higher-level exception functions in libstdc++, which is why they don't stop at destructors; but this code doesn't know about the details and just defers to the lower-level unwinder.) I thought a bit about whether we could fix the lower levels to expose the information we'd like, but I couldn't think of a good way. Tom catch catch [REGEXP] Tom catch throw [REGEXP] Tom catch rethrow [REGEXP] Michael This is really nice; the ability to hide many of the two Michael dozen+ expected exceptions in some way be really Michael useful. Unfortunately these are often of quite generic types Michael :-) Yeah, that makes it harder. If they carry any identifying markers, you can use two of the features in tandem to filter. For example: catch throw TheExceptionType if $_exception.field == 23 This would filter by type and then do some additional checking of the identity of the exception. If they don't carry identifying markers -- if it were me, I guess I would add something to make debugging simpler. Michael Tor suggested on IRC some way of ignoring specific exception throwing Michael sites which tend to creep into the code over time and need tackling. Michael Being able to say: catch throw ignore - which would ignore the last Michael thrown exception site would be really lovely ;-) This sort of thing is reasonably easy to do in Python. Fedora has had a $_caller_is function in its gdb for a while (not sure why we haven't upstreamed this yet, probably just nobody got around to it yet). This function was actually my motivation for getting into gdb hacking and working on Python in gdb -- I wanted to be able to filter breakpoints according to caller, without a lot of hassle. I've appended it for convenience. I'll file a bug to remind us to upstream this. You would use it like: catch throw if !$_caller_is('some_thrower_to_ignore') You could wrap this up in a Python command to add !$_caller_is... to existing breakpoint conditions, or a LibreOffice-specific catch throw-like command which pre-ignores uninteresting call sites, or etc. Michael Is any of that useful ? - really looking forward to getting a Michael new libstdc++ etc. with your fixes in a few months :-) An optimist, I see :) Actually, I assume all the patches will go in reasonably soon, but there's a pretty long lag until the new stuff is deployed all over, unless you're willing to build your gcc. Please feel free to CC me on gdb questions and suggestions. I'm very interested in your feedback. Tom # Caller-is functions. # Copyright (C) 2008 Free Software Foundation, Inc. # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 3 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see http://www.gnu.org/licenses/. import gdb import re class CallerIs (gdb.Function): Return True if the calling function's name is equal to a string. This function takes one or two arguments. The first argument is the name of a function; if the calling function's name is equal to this argument, this function returns True. The optional second argument tells this function how many stack frames to traverse to find the calling function. The default is 1. def __init__ (self): super (CallerIs, self).__init__ (caller_is) def invoke (self, name, nframes = 1): frame = gdb.selected_frame () while nframes 0: frame = frame.older () nframes = nframes - 1 return frame.name () == name.string () class CallerMatches (gdb.Function): Return True if
Re: Gdb support for exceptions (Re: using backtrace() in exception throwing?)
Hi Tom, On Tue, 2013-02-26 at 14:23 +0100, Jan Holesovsky wrote: Michael Even better than this would (perhaps) be a break inside thrower that Michael is caught here type breakpoint - that we could invoke to land us in Michael whatever code is going to throw as it does that [ and before it started Michael all the magic cleanup / unwinding work ]. That is - assuming that it's Michael possible for the code to know (at that point) where it will ultimately Michael end up (? ;-) I think it isn't possible in general. When an exception is thrown, I think all that can really be determined is the next catch point. This would be perfect. Explicit rethrows are relatively rare in our code, however it is completely normal to have code that we simply don't understand and/or follow - whereby we do: A: try { B: do_incredibly_complex_thing(); } catch (const uno::Exception e) { C: ... flow eventually ends up here ... } Where by do_incredibly_complex_thing - it is expected that this method dlopens a dozen separate shared libraries, does 1bn instructions or so - and (somewhere in the middle) fails in some odd way - that we're trying to find. Oh - of course, about two dozen+ 'expected' exceptions will get thrown and caught during that process. Current approaches to trying to find: what inside B threw to C involve: putting a break-point in 'A', then putting a breakpoint in __cxa_throw - continuing, and typing 'continue N' several times to work out what value of 'two dozen+' we have today, manually counting / trying to binary chop towards that number: and finally we get near enough that breaking on and carefully examining every exception in a plausible range that may cause this issue. That flow as you can see is pretty hideous :-) what we really want to do is: catch thrower-to-C or somesuch :-) being able to handle rethrows simply by re-starting gdb and the app, doing a 'catch thrower-to-rethrow-catch' would be blissful in comparison - walking up the chain one by one ;-) In other words - I'd love if gdb were able to do this even with the re-throw limitation :-) As kendy says this would really help us read, understand, unwind and improve complex code. Tom wrote: I also implemented a way to filter exception catches by name: catch catch [REGEXP] catch throw [REGEXP] catch rethrow [REGEXP] This is really nice; the ability to hide many of the two dozen+ expected exceptions in some way be really useful. Unfortunately these are often of quite generic types :-) Tor suggested on IRC some way of ignoring specific exception throwing sites which tend to creep into the code over time and need tackling. Some low-level technology will decide it's better to fire an Exception than return an undefined value of some kind - and suddenly two-dozen+ turns into 100's - (I just got this today) ;-) Being able to say: catch throw ignore - which would ignore the last thrown exception site would be really lovely ;-) Is any of that useful ? - really looking forward to getting a new libstdc++ etc. with your fixes in a few months :-) Thanks ! Michael. -- michael.me...@suse.com , Pseudo Engineer, itinerant idiot ___ LibreOffice mailing list LibreOffice@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/libreoffice
Re: Gdb support for exceptions (Re: using backtrace() in exception throwing?)
Tom == Tom Tromey tro...@redhat.com writes: Tom The various low-level exception-related functions, like __cxa_throw, Tom treat the exception object as a void *. However, the value of this Tom seems to change depending on the throw point. It's clear that this Tom can't always be the argument to throw, due to scalar and object throws. Tom So I wonder what exactly it refers to. I'll have to dig a bit deeper to Tom see how all this code really works. [...] Tom It seems like it would be nice if gdb exposed some kind of convenience Tom variable so that catch catch and catch throw could be conditional on Tom the thrown object without needing the libstdc++ debuginfo. [...] Tom This may require some libstdc++ change, perhaps a probe point. I did some more digging here and wrote a few patches. When throwing an exception, the compiler arranges to allocate an internal exception object with enough extra space for the exception passed to throw. Then it copy-constructs from the thrown object into this space and it records the object's type_info into the internal exception object. I added some SDT probes to libstdc++ to expose this information more nicely (there's really no good way to do it in all cases right now, even with debuginfo installed, as a couple of the probes are mid-function). So now I can: (gdb) catch throw Catchpoint 1 (throw) (gdb) r Starting program: /home/tromey/Space/SecondArcher/build/gdb/testsuite/gdb.cp/exception [... loads of gunk ...] Catchpoint 1 (exception thrown), __cxxabiv1::__cxa_throw (obj=0x601090, tinfo=0x600e60 typeinfo for int@@CXXABI_1.3, dest=0x0) at ../../../../gcc/libstdc++-v3/libsupc++/eh_throw.cc:63 63PROBE2 (throw, obj, tinfo); (gdb) p $_exception $1 = 13 Note that the exception variable automatically has the right type: (gdb) up #1 0x00400873 in foo (i=20) at ../../../archer/gdb/testsuite/gdb.cp/exception.cc:28 28 throw (int) 13; So, cool. The bad news is, since this requires a libstdc++ patch, even once I get everything tidied up and approved and committed, it is going to be a while before you can use it, unless you're willing to build your own gcc and gdb. Tom If we had the convenience variable mentioned above, and if LibreOffice Tom has a relatively simple exception identity measure (e.g., if you only Tom throw pointers, you can just compare them with ==), then it could Tom perhaps be done by: break at the losing catch, make a conditional catch Tom throw, then re-run. This does turn out to be a tricky bit. gdb generally mimics the source language, so things like: cond 5 $_exception == 23 ... will fail if some exception thrown is not actually comparable to 23. I'm investigating some options here. Maybe a more-magical === operator, or maybe a Python convenience function like: cond 5 $_dwim_equals ($_exception, 23) I also implemented a way to filter exception catches by name: catch catch [REGEXP] catch throw [REGEXP] catch rethrow [REGEXP] That will help the above problem a bit, you can do: catch catch int if $_exception == 23 I think all this should help with the problems that started this thread. Insight, advice, ideas -- send them my way. thanks, Tom ___ LibreOffice mailing list LibreOffice@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/libreoffice
Re: Gdb support for exceptions (Re: using backtrace() in exception throwing?)
On 02/22/2013 07:14 PM, Tom Tromey wrote: I'm curious what types of exceptions are actually thrown in LibreOffice. Does it throw -- scalars? Objects? Just pointers (Java style)? LibreOffice's UNO component system has a large exception hierarchy, which is modeled as a hierarchy of classes in C++. So what is thrown is typically (copies of) stack-allocated class instances, of specific sub-classes of com::sun::star::uno::Exception. If we had the convenience variable mentioned above, and if LibreOffice has a relatively simple exception identity measure (e.g., if you only throw pointers, you can just compare them with ==), then it could perhaps be done by: break at the losing catch, make a conditional catch throw, then re-run. Overall execution in LibreOffice is likely dynamic enough that the relevant exception class instance has different addresses in different runs. Stephan ___ LibreOffice mailing list LibreOffice@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/libreoffice
Re: Gdb support for exceptions (Re: using backtrace() in exception throwing?)
Hi Tom, Tom Tromey píše v Pá 22. 02. 2013 v 11:14 -0700: Michael Even better than this would (perhaps) be a break inside thrower that Michael is caught here type breakpoint - that we could invoke to land us in Michael whatever code is going to throw as it does that [ and before it started Michael all the magic cleanup / unwinding work ]. That is - assuming that it's Michael possible for the code to know (at that point) where it will ultimately Michael end up (? ;-) I think it isn't possible in general. When an exception is thrown, I think all that can really be determined is the next catch point. What this means is that if you have a series of throws and re-throws, winding up at some catch, then the best you could do is stop at the re-throw that leads to that catch. Even if this is not solving everything / the general case, I think this would still be pretty useful for LibreOffice - I don't remember being bitten by rethrows when debugging LO problems. And always one could set this thing [how to call it, actually? ;-)] where the re-throw happens, and try again - still it would save quite some time compared to first setting a breakpoint to get to the relevant piece of code + catch throw + catch catch + hope that they are the right ones. Here, suppose the comment marks the catch you are concerned with. You want to find the throw that leads to this point. The original throw in doit can only see as far as the catchpoint in dd2. That is because arbitrary code can be run there -- for example it may swallow the exception and no more throwing is even done. So this hypothetical breakpoint would only trigger at the re-throw in dd2. In other words - I'd love if gdb were able to do this even with the re-throw limitation :-) All the best, Kendy ___ LibreOffice mailing list LibreOffice@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/libreoffice
Re: Gdb support for exceptions (Re: using backtrace() in exception throwing?)
Hi Tom, On Wed, 2013-02-20 at 14:28 -0700, Tom Tromey wrote: 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. Oh wow :-) so Lubos' feedback here is really great; personally I feel like rather an inadequate gdb user myself ;-) 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 debugging experience in these an exception broke something flows is that we get an exception thrown that ultimately ends up in a pathalogical situation - an abort, or some similar horrible badness. At that point the most interesting thing is not the catcher - which usually ends up being utterly random - but the last guy that threw the exception. So then as Lubos says comes the knotty job of trying to put a breakpoint on the -one- exception that ends up being caught where we are now [ and that of course requires re-running, and inevitably we throw dozens of exceptions in the normal case ]. 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. This of course goes a huge way to solving the above problem :-) Really nice ! though of course - having a full stack trace would make that very substantially more useful. Even better than this would (perhaps) be a break inside thrower that is caught here type breakpoint - that we could invoke to land us in whatever code is going to throw as it does that [ and before it started all the magic cleanup / unwinding work ]. That is - assuming that it's possible for the code to know (at that point) where it will ultimately end up (? ;-) Anyhow - it's great to have some python help here; I guess we could bundle that into our existing grab-bag of nice python fixes today :-) Thanks ! Michael. -- michael.me...@suse.com , Pseudo Engineer, itinerant idiot ___ LibreOffice mailing list LibreOffice@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/libreoffice
Re: Gdb support for exceptions (Re: using backtrace() in exception throwing?)
Michael == Michael Meeks michael.me...@suse.com writes: Michael The basic debugging experience in these an exception broke Michael something flows is that we get an exception thrown that Michael ultimately ends up in a pathalogical situation - an abort, or Michael some similar horrible badness. At that point the most Michael interesting thing is not the catcher - which usually ends up Michael being utterly random - but the last guy that threw the Michael exception. So then as Lubos says comes the knotty job of trying Michael to put a breakpoint on the -one- exception that ends up being Michael caught where we are now [ and that of course requires Michael re-running, and inevitably we throw dozens of exceptions in the Michael normal case ]. Thanks. This kind of discussion is very helpful to me. This problem is a bit tricky. The various low-level exception-related functions, like __cxa_throw, treat the exception object as a void *. However, the value of this seems to change depending on the throw point. It's clear that this can't always be the argument to throw, due to scalar and object throws. So I wonder what exactly it refers to. I'll have to dig a bit deeper to see how all this code really works. Anyway, this makes tracking backward from std::terminate to the original throw point more difficult. It helps a bit to install the libstdc++ debuginfo. Then at least you can dig into some of the details. However, due to optimization, even with the improvements in newer version of gcc, this turns out to be less than perfect. I tried this out to see what it was like. It is kind of awful! At least, I had to dig around through several frames of libstdc++ to find the object that lead to std::terminate being called: terminate called after throwing an instance of 'char const*' Program received signal SIGABRT, Aborted. 0x003be3036285 in __GI_raise (sig=6) at ../nptl/sysdeps/unix/sysv/linux/raise.c:64 64return INLINE_SYSCALL (tgkill, 3, pid, selftid, sig); (gdb) up #1 0x003be3037b9b in __GI_abort () at abort.c:91 91raise (SIGABRT); (gdb) up #2 0x003be80bbc5d in __gnu_cxx::__verbose_terminate_handler () at ../../../../libstdc++-v3/libsupc++/vterminate.cc:95 95 abort(); (gdb) up #3 0x003be80b9e16 in __cxxabiv1::__terminate (handler=optimized out) at ../../../../libstdc++-v3/libsupc++/eh_terminate.cc:40 40handler (); (gdb) up #4 0x003be80b9e43 in std::terminate () at ../../../../libstdc++-v3/libsupc++/eh_terminate.cc:50 50__terminate (__terminate_handler); (gdb) up #5 0x003be80b9f3e in __cxxabiv1::__cxa_throw (obj=0x601090, tinfo=optimized out, dest=optimized out) at ../../../../libstdc++-v3/libsupc++/eh_throw.cc:83 83std::terminate (); At this point I can do: (gdb) catch throw Catchpoint 1 (throw) (gdb) cond 1 obj == 0x601090 (gdb) r The program being debugged has been started already. Start it from the beginning? (y or n) y [Inferior 25299 exited] Starting program: /tmp/r warning: failed to reevaluate condition for breakpoint 1: No symbol obj in current context. warning: failed to reevaluate condition for breakpoint 1: No symbol obj in current context. warning: failed to reevaluate condition for breakpoint 1: No symbol obj in current context. Catchpoint 1 (exception thrown), __cxxabiv1::__cxa_throw (obj=0x601090, tinfo= 0x600a60, dest=0) at ../../../../libstdc++-v3/libsupc++/eh_throw.cc:70 70header-exc.unexpectedHandler = __unexpected_handler; Ignore the warnings; I'm not sure what they are about, but I will file a bug. ... but all this still fails if you insert a manual re-throw like throw x; into the call chain. At that point it gets really messy :( Michael Really nice ! though of course - having a full stack trace Michael would make that very substantially more useful. This is reasonably easy to implement. It may be expensive. I've appended a version that does this... well, it lists file name and line number for all the frames. If you want to get a really full stack trace, capturing the arguments and locals, then you would have to do more work. Michael Even better than this would (perhaps) be a break inside thrower that Michael is caught here type breakpoint - that we could invoke to land us in Michael whatever code is going to throw as it does that [ and before it started Michael all the magic cleanup / unwinding work ]. That is - assuming that it's Michael possible for the code to know (at that point) where it will ultimately Michael end up (? ;-) I think it isn't possible in general. When an exception is thrown, I think all that can really be determined is the next catch point. What this means is that if you have a series of throws and re-throws, winding up at some catch, then the best you could do is stop at the re-throw that leads to that catch. Does that make sense? Like: void doit() { throw hi; } void dd2() { try {
Re: Gdb support for exceptions (Re: using backtrace() in exception throwing?)
Lubos == Lubos Lunak l.lu...@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() ___ LibreOffice mailing list LibreOffice@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/libreoffice
Gdb support for exceptions (Re: using backtrace() in exception throwing?)
On Monday 18 of February 2013, Tom Tromey wrote: Lubos == Lubos Lunak l.lu...@suse.cz writes: Lubos This could be very useful ('catch throw' is so cumbersome in Lubos gdb), Is there something we could do to improve it? I don't know how much control gdb over exception handling has, so I don't know :). What I was refering to was the problem that if a catch block catches an exception, it's often difficult to find out where it actually came from. Using 'catch catch' doesn't show where it originated (unless I missed a non-obvious way). And if the exception propagated out of complex nesting of function calls, then 'catch throw' may trigger a number of times for exceptions that will be handled elsewhere. So it would be useful to have some kind of 'catch throw-for-this-catch', or at least some 'show exception' (mentioned in 'help catch') that would show where the currently propagating exception started. -- Lubos Lunak l.lu...@suse.cz ___ LibreOffice mailing list LibreOffice@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/libreoffice