Использование libunwind в приложении-демоне ARMV7HF или ARMV5TE не имеет глубины трассировки стека

Я написал приложение на C ++ (deamon), у которого есть некоторые проблемы со сбоями приложений из-за ошибок сегментации.

Чтобы получить информацию о коде, где происходит сбой (я), я использую libunwind. Который очень хорошо работает в системах Linux x86_x64. Там я получаю хорошую трассировку стека.
Но в архитектурах ARM трассировка стека состоит только из стека до самого кода «Deamon-code», а не в разделяемые библиотеки, которые я использую

Я использую gcc 4.9 (для arm arm-linux-gnueabihf-g ++ 4.9)
Я собираю библиотеки и демон в режиме отладки (-g) со следующими параметрами, чтобы получить таблицы для трассировки стека

-funwind-tables -fasynchronous-unwind-tables -mapcs-frame -g

для компоновщика я использую для общих библиотек

-shared -pthread -static-libgcc -static-libstdc++ -rdynamic

Вот пример трассировки стека x86

1  0x0000000000403f68 sp=0x00007f0c2be8d630 crit_err_hdlr(int, siginfo_t*, void*) + 0x28
2  0x00007f0c2dfa33d0 sp=0x00007f0c2be8d680 __restore_rt + 0x0
3  0x00007f0c2dfa32a9 sp=0x00007f0c2be8dc18 raise + 0x29
4  0x00007f0c2e958bab sp=0x00007f0c2be8dc20 Raumserver::Request::RequestAction_Crash::crashLevel4() + 0x2b
5  0x00007f0c2e958d9c sp=0x00007f0c2be8dc60 Raumserver::Request::RequestAction_Crash::executeAction() + 0x12c
6  0x00007f0c2e96f045 sp=0x00007f0c2be8dce0 Raumserver::Request::RequestAction::execute() + 0x55
7  0x00007f0c2e940c83 sp=0x00007f0c2be8de00 Raumserver::Manager::RequestActionManager::requestProcessingWorkerThread()
+ 0x113
8  0x00007f0c2ee86380 sp=0x00007f0c2be8df00 execute_native_thread_routine + 0x20
9  0x00007f0c2df996fa sp=0x00007f0c2be8df20 start_thread + 0xca
10 0x00007f0c2dccfb5d sp=0x00007f0c2be8dfc0 clone + 0x6d
11 0x0000000000000000 sp=0x00007f0c2be8dfc8  + 0x6d

а вот и след от рычага устройства. Кажется, что информация о стеке
для общих библиотек нет ?!

1  0x0000000000013403 sp=0x00000000b49fe930 crit_err_hdlr(int, siginfo_t*, void*) + 0x1a
2  0x00000000b6a3b6a0 sp=0x00000000b49fe960 __default_rt_sa_restorer_v2 + 0x0
3  0x00000000b6b5774c sp=0x00000000b49fecd4 raise + 0x24

Вот сводка кода для построения трассировки стека, которая вызывается из обработчика сигнала:

#ifdef __arm__
#include <libunwind.h>
#include <libunwind-arm.h>
#else
#include <libunwind.h>
#include <libunwind-x86_64.h>
#endif

...

void backtrace()
{
unw_cursor_t cursor;
unw_context_t context;
unw_getcontext(&context);
unw_init_local(&cursor, &context);

int n=0;
int err = unw_step(&cursor);
while ( err )
{
unw_word_t ip, sp, off;

unw_get_reg(&cursor, UNW_REG_IP, &ip);
unw_get_reg(&cursor, UNW_REG_SP, &sp);

char symbol[256] = {"<unknown>"};
char buffer[256];
char *name = symbol;

if ( !unw_get_proc_name(&cursor, symbol, sizeof(symbol), &off) )
{
int status;
if ( (name = abi::__cxa_demangle(symbol, NULL, NULL, &status)) == 0 )
name = symbol;
}

sprintf(buffer, "#%-2d 0x%016" PRIxPTR " sp=0x%016" PRIxPTR " %s + 0x%" PRIxPTR "\n",
++n,
static_cast<uintptr_t>(ip),
static_cast<uintptr_t>(sp),
name,
static_cast<uintptr_t>(off));

if ( name != symbol )
free(name);

...

err = unw_step(&cursor);
}
}

А вот резюме для самого Деймона:

int main(int argc, char *argv[])
{
Raumserver::Raumserver  raumserverObject;

//Set our Logging Mask and open the Log
setlogmask(LOG_UPTO(LOG_NOTICE));
openlog(DAEMON_NAME, LOG_CONS | LOG_NDELAY | LOG_PERROR | LOG_PID, LOG_USER);

pid_t pid, sid;

//Fork the Parent Process
pid = fork();
if (pid < 0) {  syslog (LOG_NOTICE, "Error forking the parent process"); exit(EXIT_FAILURE); }
//We got a good pid, Close the Parent Process
if (pid > 0) {  syslog (LOG_NOTICE, "Got pid, closing parent process"); exit(EXIT_SUCCESS); }

//Change File Mask
umask(0);

//Create a new Signature Id for our child
sid = setsid();
if (sid < 0) {  syslog (LOG_NOTICE, "Signature ID for child process could not be created!"); exit(EXIT_FAILURE); }
// get the working directory of the executable
std::string workingDirectory = getWorkingDirectory();

//Change Directory
//If we cant find the directory we exit with failure.
if ((chdir("/")) < 0) { exit(EXIT_FAILURE); }

//Close Standard File Descriptors
close(STDIN_FILENO);
close(STDOUT_FILENO);
close(STDERR_FILENO);

// Add some system signal handlers for crash reporting
//raumserverObject.addSystemSignalHandlers();
AddSignalHandlers();

// set the log adapters we want to use (because we do not want to use the standard ones which includes console output)
std::vector<std::shared_ptr<Raumkernel::Log::LogAdapter>> adapters;
auto logAdapterFile = std::shared_ptr<Raumkernel::Log::LogAdapter_File>(new Raumkernel::Log::LogAdapter_File());
logAdapterFile->setLogFilePath(workingDirectory + "logs/");
adapters.push_back(logAdapterFile);

// create raumserver object and do init
raumserverObject.setSettingsFile(workingDirectory + "settings.xml");
raumserverObject.initLogObject(Raumkernel::Log::LogType::LOGTYPE_ERROR, workingDirectory + "logs/", adapters);
raumserverObject.init();

// go into an endless loop and wait until daemon is killed by the syste,
while(true)
{
sleep(60);    //Sleep for 60 seconds
}

//Close the log
closelog ();
}

Кто-нибудь идея, если я пропустил некоторые флаги компилятора? Чего-то не хватает?
Я нашел много постов, и все они ссылаются на упомянутые флаги компилятора или libunwind. Я пробовал несколько других кодов, которые я нашел, но они дают мне глубину стека 1
Спасибо!

РЕДАКТИРОВАТЬ 11.11.2016:
Для тестирования я создал статические библиотеки вместо общих и добавил их в приложение, чтобы больше не было динамических ссылок. К сожалению, трассировка стека такая же плохая.

Я даже попытался скомпилировать весь материал в режиме большого пальца и изменил компилятор arm на gcc5 / g ++ 5

-mthumb -mtpcs-frame -mtpcs-leaf-frame

Та же проблема 🙁

1

Решение

Задача ещё не решена.

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]