breakpad not generate minidump on erase iterator twice

831 views Asked by At

I find breakpad does not handle sigsegv sometimes. and i wrote a simple example to reproduce it:

#include <vector>
#include <breakpad/client/linux/handler/exception_handler.h>

int InitBreakpad()
{
    char core_file_folder[] = "/tmp/cores/";
    google_breakpad::MinidumpDescriptor descriptor(core_file_folder);
    auto exception_handler_ =
        new google_breakpad::ExceptionHandler(descriptor,
        nullptr,
        nullptr,
        nullptr,
        true,
        -1);
}
int main()
{
     InitBreakpad();

     // int* ptr = nullptr;
     // *ptr = 1;
     std::vector<int> sum;
     sum.push_back(1);
     auto it = sum.begin();
     sum.erase(it);
     sum.erase(it);

     return 0;
}

and gcc is 4.8.5 and my comiple cmd is

g++ test_breakpad.cpp -I./include -I./include/breakpad -L./lib -lbreakpad -lbreakpad_client -std=c++11 -lpthread

run a.out, get "Segmentation fault" but no minidump is generated.

if i uncomment nullptr write, breakpad works!

what should i do to correct it?

GDB debug output:

(gdb) b google_breakpad::ExceptionHandler::~ExceptionHandler()
Breakpoint 2 at 0x402ed0: file src/client/linux/handler/exception_handler.cc, line 264.
(gdb) c
The program is not being run.
(gdb) r
Starting program: /home/zen/tmp/a.out
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/lib64/libthread_db.so.1".

Breakpoint 1, google_breakpad::ExceptionHandler::ExceptionHandler (this=0x619040, descriptor=..., filter=0x0, callback=0x0, callback_context=0x0, install_handler=true, server_fd=-1) at src/client/linux/handler/exception_handler.cc:224
224     ExceptionHandler::ExceptionHandler(const MinidumpDescriptor& descriptor,
Missing separate debuginfos, use: debuginfo-install glibc-2.17-157.el7_3.1.x86_64 libgcc-4.8.5-11.el7.x86_64 libstdc++-4.8.5-11.el7.x86_64
(gdb) c
Continuing.

Program received signal SIGSEGV, Segmentation fault.
0x00007ffff712f19d in __memmove_ssse3_back () from /lib64/libc.so.6
(gdb) c
Continuing.

Program received signal SIGSEGV, Segmentation fault.
0x00007ffff712f19d in __memmove_ssse3_back () from /lib64/libc.so.6
(gdb) c
Continuing.

Program terminated with signal SIGSEGV, Segmentation fault.
The program no longer exists.

and i tried breakpad out of process dump, but still got nothing(nullptr write works).

1

There are 1 answers

13
moggi On

After some debugging I think that the reason that the sum.erase(it) does not create a minidump in your example is due to stack corruption.

While debugging you can see that the variable g_handler_stack_ in src/client/linux/handler/exception_handler.cc is correctly initialized and the google_breakpad::ExceptionHandler instance is correctly added to the vector. However when google_breakpad::ExceptionHandler::SignalHandler is called the vector is reported empty despite no calls to google_breakpad::ExceptionHandler::~ExceptionHandler or any of the std::vector methods that would change the vector.

Some further data points that point to stack corruption is that the code works with clang++. Additionally, as soon as we change the std::vector<int> sum; to a std::vector<int>* sum, which will ensure that we don't corrupt the stack, the minidump is written to disk.