How to break when a specific exception type is thrown in GDB?

后端 未结 9 1151
迷失自我
迷失自我 2020-12-02 07:40

According to the documentation I can break on specific exception type by using conditional breakpoints. However the syntax for the condition isn\'t very clear to me:

相关标签:
9条回答
  • 2020-12-02 08:10

    Another approach is to rely on the tinfo argument available when the catch point is triggered, which is a pointer to the object returned by typeid(type).

    So say if I want to catch exception std::bad_alloc being thrown, I could just do:

    > p &typeid(std::bad_alloc)
    > $1 = (__cxxabiv1::__si_class_type_info *) 0x8c6db60 <typeinfo for std::bad_alloc>
    > catch throw if tinfo == 0x8c6db60
    
    0 讨论(0)
  • 2020-12-02 08:15

    As others already mentioned this functionality doesn't work in practice. But as workaround you can put condition on catch throw. When exception is thrown we come to __cxa_throw function. It has several parameters pointing to exception class, so we can set condition on one of them. In the sample gdb session below, I put condition on dest parameter of __cxa_throw. The only problem is that value of dest (0x80486ec in this case) is unknown in advance. It can be known, for example, by first running gdb without condition on breakpoint.

    [root@localhost ~]#
    [root@localhost ~]# gdb ./a.out
    GNU gdb (GDB) 7.2
    Copyright (C) 2010 Free Software Foundation, Inc.
    License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
    This is free software: you are free to change and redistribute it.
    There is NO WARRANTY, to the extent permitted by law.  Type "show copying"
    and "show warranty" for details.
    This GDB was configured as "i686-pc-linux-gnu".
    For bug reporting instructions, please see:
    <http://www.gnu.org/software/gdb/bugs/>...
    Reading symbols from /root/a.out...done.
    (gdb) catch throw
    Catchpoint 1 (throw)
    (gdb) condition 1 dest==0x80486ec
    No symbol "dest" in current context.
    (gdb) r
    warning: failed to reevaluate condition for breakpoint 1: No symbol "dest" in current context.
    warning: failed to reevaluate condition for breakpoint 1: No symbol "dest" in current context.
    warning: failed to reevaluate condition for breakpoint 1: No symbol "dest" in current context.
    Catchpoint 1 (exception thrown), __cxxabiv1::__cxa_throw (obj=0x804a080, tinfo=0x8049ca0, dest=0x80486ec <_ZNSt13runtime_errorD1Ev@plt>) at ../../../../gcc-4.4.3/libstdc++-v3/libsupc++/eh_throw.cc:68
    68      ../../../../gcc-4.4.3/libstdc++-v3/libsupc++/eh_throw.cc: No such file or directory.
            in ../../../../gcc-4.4.3/libstdc++-v3/libsupc++/eh_throw.cc
    (gdb) bt
    #0  __cxxabiv1::__cxa_throw (obj=0x804a080, tinfo=0x8049ca0, dest=0x80486ec <_ZNSt13runtime_errorD1Ev@plt>) at ../../../../gcc-4.4.3/libstdc++-v3/libsupc++/eh_throw.cc:68
    #1  0x08048940 in main () at test.cpp:14
    (gdb) i b
    Num     Type           Disp Enb Address    What
    1       breakpoint     keep y   0x008d9ddb exception throw
            stop only if dest==0x80486ec
            breakpoint already hit 1 time
    (gdb)
    

    Update

    You must also load debug info for libstdc++ for this workaround to work.

    0 讨论(0)
  • 2020-12-02 08:21

    From what I have understood from the question here, you want to break when a specific exception boost::bad_function_call is thrown in your application.

    $> gdb /path/to/binary
    (gdb) break boost::bad_function_call::bad_function_call()
    (gdb) run --some-cli-options
    

    So when the temporary object boost::bad_function_call is constructed in preparation for the throw; gdb will break out!

    I have tested this and it does work. If you precisely know the way the exception object is being constructed then you can set breakpoint on the specific constructor, otherwise as shown in the example below, you can omit the arguments prototype list, and gdb will set break points on all different flavours of the constructor.

    $ gdb /path/to/binary
    
    (gdb) break boost::bad_function_call::bad_function_call
    Breakpoint 1 at 0x850f7bf: boost::bad_function_call::bad_function_call. (4 locations)
    
    (gdb) info breakpoints
    Num     Type           Disp Enb Address    What
    1       breakpoint     keep y   <MULTIPLE>
    1.1                         y     0x0850f7bf in boost::bad_function_call::bad_function_call() at /usr/include/boost/function/function_base.hpp:742
    1.2                         y     0x0850fdd5 in boost::bad_function_call::bad_function_call(boost::bad_function_call const&) at /usr/include/boost/function/function_base.hpp:739
    1.3                         y     0x0863b7d2 <boost::bad_function_call::bad_function_call()+4>
    1.4                         y     0x086490ee <boost::bad_function_call::bad_function_call(boost::bad_function_call const&)+6>
    
    0 讨论(0)
提交回复
热议问题