我发现我的测试应用程序在使用线程时没有生成正确的转储文件。我正在使用交叉编译器构建 Breadpad 库,然后将其与我的交叉编译器链接以在目标上运行。
我将首先解释我的设置:
基于:Ubuntu 12.04、i686
主机/目标:Vortex86DX,它是一个 i586 cpu,完全定制的 Linux 系统
构建工具:Buildroot、crosstool-ng、gcc 4.4.6、glibc 2.9
要构建 Breakpad,我这样做:
$ ./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
我的交叉编译器已集成到 Buildroot 中,我想构建在其上运行的二进制文件--host=i486-unknown-linux-gnu
我像这样交叉编译我的测试应用程序:
$ /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
测试应用程序是:
#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;
}
我只是在 main() 崩溃和线程崩溃之间创建了变化。
当我在目标上交叉编译和运行我的应用程序时的观察结果:
(1) 没有线程的测试应用程序将在目标上创建正确的转储文件。经过
(2) 带有崩溃线程的测试应用程序将在目标上创建一个非常小且不正确的转储文件(大部分为零)。失败
(3) 测试应用程序,其线程不崩溃,主线程崩溃,将在目标上创建一个中等大小且不正确的转储文件。失败
编辑:在情况(1)中,回调返回successed=true。在情况 (2) 和 (3) 中,succeded=false。所以图书馆知道它没有成功。我想我的工作就是找出为什么它在我的目标上失败了。
如果我编译相同的测试应用程序以在我的构建计算机上运行,它会在所有情况下运行并创建正确的转储文件。即我已经在我的构建计算机上成功运行了交叉编译的 Crashpad 库,并且它可以正常工作。由于 build 和 host 都是 x86,因此这是可能的。
例如,我使用非交叉编译 g++ 构建
g++ -g mytest.cpp client/linux/libbreakpad_client.a -I. -lrt -lpthread -lboost_thread -o mytest
我的问题是:
是Breakpad的问题吗?
我的交叉编译库有问题吗?
内核有什么不同吗?我需要启用任何特定功能吗?
如何使它起作用?即在我的目标上运行的多线程应用程序会生成正确的小型转储文件