Re: Recursive SIGSEGV question

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Hi!
Just sharing the little backtrace sample I made using addr2line and libc backtrace_symbols().

The backtrace doesn't appear to be completely accurate, but it is something.

The file goes from 22KB (as you found Xi!) to 87KB on my 64bit ubuntu machine when I add -g.

So I'm pleased with this, better than Go's 1,997,502 byte backtrace then?



$ ./exception4
Unhandled C++ exception: [vector::_M_range_check: __n (which is 0) >= this->size() (which is 0)]

Backtrace:
0x00000000000014de: test() at exception4.cpp:75
[1]: ./exception4(+0x14de) [0x563bd5b804de]
0x0000000000001550: main at exception4.cpp:87
[2]: ./exception4(+0x1550) [0x563bd5b80550]
0x0000000000000000: ?? ??:0
[3]: /lib/x86_64-linux-gnu/libc.so.6(__libc_start_main+0xe7) [0x7f1d0c52bb97]
0x0000000000000fea: _start at ??:?
[4]: ./exception4(+0xfea) [0x563bd5b7ffea]


Could GCC insert something similar using libc backtrace_symbols() with an -fcrash-handler ?

Jonny
// g++-8 -Wall -g -o exception4 exception4.cpp
#include <vector>
#include <iostream>
#include <string>

#include <execinfo.h>
#include <stdio.h>
#include <stdlib.h>

int main2();

/* Obtain a backtrace and print it to stdout.
 https://www.gnu.org/software/libc/manual/html_node/Backtraces.html
 */
void print_trace(void)
{
    void *array[10];
    const size_t size = backtrace (array, 10);
    char **strings = backtrace_symbols (array, size);

    //printf ("Obtained %zd stack frames.\n", size);
    printf("\nBacktrace:\n");

    // skip first, as it is this handler
    for (size_t i = 1; i < size; i++)
    {
        // extract the exe name
        std::string exe(strings[i]);
        {
            const size_t s = exe.find("(");
            if(std::string::npos != s)
            {
                exe.erase(s, exe.length());
            }
        }

        // extract the address
        std::string addr(strings[i]);
        {
            size_t s = addr.find("(");
            if(std::string::npos != s)
            {
                ++s;
                addr.erase(0, s);

                s = addr.find(")");
                if(std::string::npos != s)
                {
                    addr.erase(s, addr.length());
                }
            }
        }

        //printf("exe '%s' addr '%s'\n", exe.c_str(), addr.c_str());

        char syscom[256];
        sprintf(syscom,"addr2line -s -a -p -f -C -e %s %s", exe.c_str(), addr.c_str());
        //printf("%s\n", syscom);
        system(syscom);

        printf ("[%zu]: %s\n", i, strings[i]);
    }

    free (strings);
}

void test()
{
    try
    {
        main2();
    }
    catch( const std::exception &e)
    {
        const std::string what(e.what());
        std::cout << "Unhandled C++ exception: [" << e.what() << "]\n";
        print_trace();
        //char * p = NULL;
        //*p = 1;
    }
}


int main(int argc, const char * argv[])
{
    test();
}


int main2()
{
    std::vector<int> v;
    return v.at(0);
}


[Index of Archives]     [Linux C Programming]     [Linux Kernel]     [eCos]     [Fedora Development]     [Fedora Announce]     [Autoconf]     [The DWARVES Debugging Tools]     [Yosemite Campsites]     [Yosemite News]     [Linux GCC]

  Powered by Linux