Mendes
Mendes

Reputation: 18471

C++ How to identify SIGNAL 11 error location

I´m running a multi-threaded C++ program in a Linux system (Kernel 2.6.23). My code is compiled using G++ version 4.7.4.

I added the following code to catch segmentation faults:

void segFaultHandler(int sig)
{
  void *array[10];
  size_t size;

  size = backtrace(array, 10);
  fprintf(stderr, "Error: signal %d:\n", sig);
  backtrace_symbols_fd(array, size, STDERR_FILENO);
  exit(1);
}

And on main:

main()
{
    signal(SIGSEGV, segFaultHandler);

    try {

         program code here...

    catch(const std::exception& ex)
    {
        std::cerr << "Error occurred: " << ex.what() << std::endl;
    }
    catch(...)
    {
        std::cerr << "Unknown failure occurred. Possible memory corruption" << std::endl;
    }

    return 0;
}

When running, my program is crashing with the following output:

Error: signal 11:
/home/cross/bin/aeirtu[0x807406e]
[0xffffe420]
/lib/libc.so.6(memcpy+0x2f)[0xb7d9bcbf]
/usr/gcc-4.7.4/lib/libstdc++.so.6(_ZNSt15basic_streambufIcSt11char_traitsIcEE6xsputnEPKci+0x73)[0xb7f26933]

It is not a easy debug as my program crashes only sometimes, so I need a tool to get the crash source and fix it.

From the given output, how can I trace back the function and piece of code that caused the crash ?

Upvotes: 4

Views: 24515

Answers (2)

user1413793
user1413793

Reputation: 9347

You can use Address Sanitizer (ASAN) by google to detect segmentation faults as well as other common programming errors related to memory (including heap use after free, buffer overflow, buffer underflow, freeing memory twice, memory leaks, etc). If an error is detected, it will give a stack trace of exactly where the error occurred (and if you use -g to include debug symbols, the stack trace is fairly understandable).

ASAN gets linked into your binary at compile time and checks your heap at run time with very little overhead (code runs about 2x slower). This is significantly faster than valgrind and has the advantage that it can run in a live environment and give valuable messages if a 2x slow down is acceptable for your use case.

Furthermore, if your segmentation fault is caused by one of the aforementioned programming errors, it will be caught by ASAN before the code even seg faults. For example, let's say you buffer overflow, corrupting the state of the heap. When you go to malloc memory later, malloc seg faults because the heap is corrupted. Any signal handler would detect the corruption at this point, even though the real problem was a heap buffer overflow. ASAN would give you a stack trace at the time of heap buffer overflow.

Upvotes: 2

vitaut
vitaut

Reputation: 55605

You can use valgrind to locate the source of a segfault. If you binary is compiled with debug symbols it will give you the exact source location:

==12834== Invalid write of size 4
==12834==    at 0x4004FD: main (test.cc:3)
==12834==  Address 0x0 is not stack'd, malloc'd or (recently) free'd

Upvotes: 6

Related Questions