Bug List: (This bug is not in your last search results)   Show last search results      Search page      Enter new bug
Bug#: 33903
Product:  
Component:  
Status: RESOLVED
Resolution: WONTFIX
Assigned To: Not yet assigned to anyone <unassigned@gcc.gnu.org>
Host:
Reported against  
Priority:  
Severity:  
Target Milestone:  
 
 
Target:
Reporter: Diederik <djh@emss.co.za>
Add CC:
CC:
Remove selected CCs
Build:
URL:
Summary:
Keywords:
Known to work:
Known to fail:

Attachment Description Type Created Size Actions
Create a New Attachment (proposed patch, testcase, etc.) View All

Bug 33903 depends on: Show dependency tree
Show dependency graph
Bug 33903 blocks:

Additional Comments:






View Bug Activity   |   Format For Printing   |   Clone This Bug


Description:   Last confirmed: Opened: 2007-10-26 07:11
The adding of backtrace info to std::exception would be most helpful. 
Currently when a program throws an exception, the debug info is rather useless.
 Only the backtrace to the catch is shown.  Ideally symbol info and line
numbers should be available, so that the throw can be easily found.

execinfo.h already provides a way of obtaining runtime backtrace info, but
would it not be more appropriate to add this to debug info for the exception?

------- Comment #1 From Andrew Pinski 2007-10-26 10:22 -------
I would use a debugger if you want the backtrace info.

------- Comment #2 From Diederik 2007-11-02 06:08 -------
I am using debugger. After the exception is thrown, the program asserts.  So I
get a backtrace to the system fatal call, having no idea where the exception
was thrown.

I dont know about you guys but I find the .net/java exceptions with
backtraces built in to be a lot more useful.  Sure you can place a
breakpoint in the constructor of an exception but it has to be done and
can be very annoying in complicated debug sessions.  Especially since
GDB is not the fastest animal around and is being used used on larger
and larger projects (which take a _long_ time to load in gdb).

------- Comment #3 From Andrew Pinski 2007-11-02 06:27 -------
(In reply to comment #2)
> I am using debugger. After the exception is thrown, the program asserts.  So I
> get a backtrace to the system fatal call, having no idea where the exception
> was thrown.

Since GCC follows the IA64 C++ ABI, you can have a breakpoint at __cxa_throw
(the function which is called for throwing the exception).

------- Comment #4 From Diederik 2007-11-02 06:54 -------
This is a possible solution.  Not ideal though, because, then all exceptions
will be trigger the breakpoint at __cxa_throw.

If however, I put a breakpoint in the catch in question, then I know I will get
the exception that I was looking for, and if bakctrace info was part of this
exception, then I could find out exactly what happened where.

------- Comment #5 From Pawel Sikora 2007-11-05 15:44 -------
(In reply to comment #4)
> This is a possible solution.  Not ideal though, because, then all exceptions
> will be trigger the breakpoint at __cxa_throw.
> 
> If however, I put a breakpoint in the catch in question, then I know I will get
> the exception that I was looking for, and if bakctrace info was part of this
> exception, then I could find out exactly what happened where.

gnu/ld has a nice option called --wrap that you can use to hack
the g++/throw() and embbed stacktrace in way you like ;-)

$ cat u.cpp
#include <cstdio>
#include <unwind.h>
#include <dlfcn.h>

_Unwind_Reason_Code helper( struct _Unwind_Context* ctx, void* )
{
        void* p = reinterpret_cast< void* >( _Unwind_GetIP( ctx ) );
        Dl_info info;
        if ( dladdr( p, &info ) )
        {
                if ( info.dli_saddr )
                {
                        long d = reinterpret_cast< long >( p )
                                - reinterpret_cast< long >( info.dli_saddr );
                        printf( "%p %s+0x%lx\n", p, info.dli_sname, d );
                }
        }
        return _URC_NO_REASON;
}

extern "C" void __real___cxa_throw( void* thrown_exception,
        std::type_info* tinfo, void ( *dest )( void* ) )
        __attribute__(( noreturn ));

extern "C" void __wrap___cxa_throw( void* thrown_exception,
        std::type_info* tinfo, void ( *dest )( void* ) )
{
        _Unwind_Backtrace( helper, 0 );
        __real___cxa_throw( thrown_exception, tinfo, dest );
}

void __attribute__(( noinline )) zoo( void )
{
        try
        {
                std::puts( "ping!" );
                throw 1;
        }
        catch ( int )
        {
                std::puts( "pong!" );
        }
}

void __attribute__(( noinline )) bar( void ( *f )( /*void*/ ) )
{
        f();
}

void __attribute__(( noinline )) foo( void )
{
        bar( &zoo );
}

int main()
{
        foo();
        return 0;
}


$ g++ u.cpp -ldl -rdynamic -Wl,--wrap,__cxa_throw && ./a.out
ping!
0x80489c7 __wrap___cxa_throw+0x15
0x8048a16 _Z3zoov+0x3a
0x8048a7d _Z3barPFvvE+0xb
0x8048a93 _Z3foov+0x13
0x8048ab9 main+0x21
0x2e3e23 __libc_start_main+0xd3
pong!

------- Comment #6 From Andrew Pinski 2007-12-02 22:27 -------
Not really a good request as GCC support for this is hard and non standard. 
You can do it yourself as shown below.

Bug List: (This bug is not in your last search results)   Show last search results      Search page      Enter new bug