I've found that my test application does not generate a correct dump file when I use threads. I am using a cross-compiler to build the Breadpad library which is then linked with my cross-compiler to run on the target.
I'll start by explaining my set up:
Building on: Ubuntu 12.04, i686
Host/Target: Vortex86DX which is an i586 cpu, fully custom Linux system
Build tools: Buildroot, crosstool-ng, gcc 4.4.6, glibc 2.9
To build Breakpad I do this:
$ ./configure CC=/opt/br/output/host/usr/bin/i486-unknown-linux-gnu-gcc CXX=/opt/br/output/host/usr/bin/i486-unknown-linux-gnu-g++ --host=i486-unknown-linux-gnu
$ make
My cross-compiler is integrated into Buildroot, and I want to build binaries that run on --host=i486-unknown-linux-gnu
I cross-compile my test app like so:
$ /opt/br/output/host/usr/bin/i486-unknown-linux-gnu-g++ -g mytest.cpp client/linux/libbreakpad_client.a -I. -lrt -lpthread -lboost_thread -o mytest
The test app is:
#include <boost/thread/thread.hpp>
#include "./client/linux/handler/exception_handler.h"
#include <unistd.h>
static bool dumpCallback( const google_breakpad::MinidumpDescriptor &md,
void *context, bool succeeded)
{
printf( "dump path: %s\n", md.path());
return succeeded;
}
void crash1()
{
volatile int* a = (int*)(NULL);
*a = 1;
}
void crash2()
{
volatile int x, y;
y = 0;
x/=y;
}
void t1()
{
sleep(1);
crash1();
}
void t2()
{
while(1) sleep(10);
}
int main()
{
google_breakpad::MinidumpDescriptor md("/tmp");
google_breakpad::ExceptionHandler eh(md, NULL, dumpCallback, NULL, true, -1);
// comment out to select between thread crash, main crash, main crash with non-crashing thread
boost::thread thread1(t2);
sleep(1);
crash1();
sleep(3);
return 0;
}
I simply create variations between crashing from main() and crashing from a thread.
Observations when I cross compile and run my app on the target:
(1) the test app, with no threads, will create a correct dump file on the target. PASS
(2) the test app, with a thread that crashes, will create a very small and incorrect dump file (mostly zeroes) on the target. FAIL
(3) the test app, with a thread that doesn't crash, and a main that crashes, will create a medium sized and incorrect dump file on the target. FAIL
EDIT: In case (1), the callback returns succeeded=true. In cases (2) and (3), succeeded=false. So the library knows that it did not succeed. I guess it's my job to find out why it fails on my target.
If I compile the same test app to run on my build computer, it runs and creates a correct dump file in all circumstances. i.e. I have successfully run the cross-compiled Crashpad library on my build computer and it works as it should. Since both build and host are x86, this is possible.
e.g. I build using the non cross compile g++
g++ -g mytest.cpp client/linux/libbreakpad_client.a -I. -lrt -lpthread -lboost_thread -o mytest
My questions are:
is the problem with Breakpad?
is the problem with my cross compilation libraries?
does the kernel make a difference? Do I need to enable any particular functionality?
how can this be made to work? i.e. a multi-threaded app, running on my target, produces a correct minidump file
Google Breakpad will fail to create a minidump on a pre-Pentium III x86 processor.
Pentium III and above contain 8 extra floating point registers that are requested by a sys_ptrace call in Breakpad.
On a pre-Pentium III processor this call will fail and this causes the entire minidump to fail.