Date: prev next · Thread: first prev next last
2013 Archives by date, by thread · List index


"Tom" == Tom Tromey <tromey@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
63        PROBE2 (throw, obj, tinfo);
(gdb) p $_exception
$1 = 13

Note that the exception variable automatically has the right type:

(gdb) up
#1  0x0000000000400873 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

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.