c++ - 当我使用线程时,Breakpad 无法在目标上创建小型转储

标签 c++ linux cross-compiling google-breakpad

我发现当我使用线程时,我的测试应用程序没有生成正确的转储文件。我正在使用交叉编译器构建 Breadpad 库,然后将其链接到我的交叉编译器以在目标上运行。

我将从解释我的设置开始:

基于:Ubuntu 12.04,i686

Host/Target: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) 中,回调返回 succeeded=true。在情况 (2) 和 (3) 中,succeeded=false。所以图书馆知道它没有成功。我想找出它在我的目标上失败的原因是我的工作。

如果我编译相同的测试应用程序以在我的构建计算机上运行,​​它会在所有情况下运行并创建正确的转储文件。也就是说,我已经在我的构建计算机上成功运行了交叉编译的 Crashpad 库,它可以正常工作。由于构建和主机都是 x86,因此这是可能的。

例如我使用非交叉编译 g++ 构建

g++ -g  mytest.cpp client/linux/libbreakpad_client.a -I. -lrt -lpthread -lboost_thread -o mytest

我的问题是:

  • 是 Breakpad 的问题吗?

  • 我的交叉编译库有问题吗?

  • 内核有什么不同吗?我需要启用任何特定功能吗?

  • 如何让它发挥作用?即在我的目标上运行的多线程应用程序生成正确的小型转储文件

最佳答案

Google Breakpad 将无法在 Pentium III x86 处理器之前创建小型转储。

Pentium III 及更高版本包含 8 个额外的浮点寄存器,这些寄存器由 Breakpad 中的 sys_ptrace 调用请求。

src/client/linux/minidump_writer/linux_ptrace_dumper.cc:
if (sys_ptrace(PTRACE_GETFPXREGS, tid, NULL, &info->fpxregs) == -1)
    return false;

在奔腾 III 之前的处理器上,此调用将失败,这会导致整个小型转储失败。

关于c++ - 当我使用线程时,Breakpad 无法在目标上创建小型转储,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12299333/

相关文章:

c++ - HWLOC 链接错误

C++理解问题——链表和栈

linux - yum + 消息是什么 - 没有可用的包 ansible

mono - 为 MIPS 交叉编译 Mono 框架 3.0.6+

gcc - 交叉编译 : GCC ignores --sysroot

c++ - 替换我的 C++ 程序中对 "system"的调用

c++ - 为什么编译器会抛出 "expected a type specifier"?

php - 在 cron 作业中执行 PHP 脚本

java - 如何使用 Maven 管理项目依赖项?

gdb - 无法与 MinGW 交叉编译 gdb