Я обнаружил, что мое тестовое приложение не генерирует правильный файл дампа, когда я использую потоки. Я использую кросс-компилятор для создания библиотеки Breadpad, которая затем связывается с моим кросс-компилятором для запуска на цели.
Я начну с объяснения моей установки:
Сборка: Ubuntu 12.04, i686
Host / Target: Vortex86DX, представляющий собой i586, полностью настраиваемую систему 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) обратный вызов возвращает успешно = истина. В случаях (2) и (3) удалось = ложь. Таким образом, библиотека знает, что это не удалось. Я полагаю, что моя работа — выяснить, почему это не помогает моей цели.
Если я собираю одно и то же тестовое приложение для запуска на моем компьютере сборки, оно запускается и создает правильный файл дампа при любых обстоятельствах. Т.е. я успешно запустил кросс-скомпилированную библиотеку 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 дополнительных регистров с плавающей запятой, которые запрашиваются вызовом sys_ptrace в Breakpad.
src/client/linux/minidump_writer/linux_ptrace_dumper.cc:
if (sys_ptrace(PTRACE_GETFPXREGS, tid, NULL, &info->fpxregs) == -1)
return false;
На процессоре, предшествующем Pentium III, этот вызов не будет выполнен, и это приведет к сбою всего минидампа.
Других решений пока нет …