Печать трассировки стека из обработчика сигнала - PullRequest
6 голосов
/ 09 февраля 2012

Мне нужно распечатать трассировку стека из обработчика сигнала 64-битного многопоточного приложения C ++, работающего в Linux.Хотя я нашел несколько примеров кода, ни один из них не компилируется.Моя точка блокировки - получение адреса вызывающей стороны (точки, где был сгенерирован сигнал) из структуры ucontext_t.Вся информация, которую я смог найти, указывает на регистр EIP как ucontext.gregs [REG_EIP] или ucontext.eip.Похоже, они оба специфичны для x86.Мне нужен 64-битный совместимый код для процессоров Intel и AMD.Кто-нибудь может помочь?

Ответы [ 2 ]

4 голосов
/ 15 февраля 2012

есть функция glibc backtrace .На странице man приведен пример вызова:

#define SIZE 100
void myfunc3(void) {
       int j, nptrs;

       void *buffer[100];
       char **strings;

       nptrs = backtrace(buffer, SIZE);
       printf("backtrace() returned %d addresses\n", nptrs);

       /* The call backtrace_symbols_fd(buffer, nptrs, STDOUT_FILENO)
          would produce similar output to the following: */

       strings = backtrace_symbols(buffer, nptrs);
       if (strings == NULL) {
           perror("backtrace_symbols");
           exit(EXIT_FAILURE);
       }

       for (j = 0; j < nptrs; j++)
           printf("%s\n", strings[j]);

       free(strings);
   }

Для получения дополнительной информации см. Страницу руководства.

Трудно сказать, действительно ли это гарантированно работает из обработчика сигнала, посколькуPosix перечисляет только несколько реентерабельных функций, которые гарантированно будут работать.Помните: обработчик сигнала может быть вызван, в то время как остальная часть вашего процесса находится прямо в середине вызова malloc.

My думаю, в том, что это обычно работает, но может произойти сбой извремя от времени.Для отладки этого может быть достаточно.

1 голос
/ 09 февраля 2012

Обычный способ получения трассировки стека состоит в том, чтобы взять адрес локальной переменной, а затем добавить к нему некоторое магическое число в зависимости от того, как компилятор генерирует код (который может зависеть от параметров оптимизации, используемых для компиляции кода)и работать оттуда.Все очень зависит от системы, но выполнимо, если вы знаете, что делаете.

Работает ли это в обработчике сигналов - это другой вопрос.Я не знаю о платформе, которую вы описываете, но многие системы устанавливают отдельный стек для обработчиков сигналов без ссылки на прерванный стек в доступной для пользователя памяти.

...