Backtrace_symbols() с и -статическим и -динамическим

Рассматривая этот вопрос и этот вопрос, я вижу, что для backtrace_symbols() для работы один должен компилироваться с флагом -rdynamic.

Я пробовал его в тестовую программу, и это работает, но я пишу программу, которая также скомпилирована с помощью -static и этой страницы говорит, что backtrace_symbols() не работает, когда -static передается компилятору/компоновщику.

Есть ли какое-нибудь быстрое обходное решение для этого, или у меня никогда не будет доступной для чтения функции backtrace в моей статически связанной программе?

Ответ 1

Ответ уже был под рукой: он был в той же странице, которую я связал в вопросе. В конце я успешно использовал libunwind.

#include <libunwind.h>
#include <stdio.h>

void do_backtrace()
{
    unw_cursor_t    cursor;
    unw_context_t   context;

    unw_getcontext(&context);
    unw_init_local(&cursor, &context);

    while (unw_step(&cursor) > 0)
    {
        unw_word_t  offset, pc;
        char        fname[64];

        unw_get_reg(&cursor, UNW_REG_IP, &pc);

        fname[0] = '\0';
        (void) unw_get_proc_name(&cursor, fname, sizeof(fname), &offset);

        printf ("%p : (%s+0x%x) [%p]\n", pc, fname, offset, pc);
    }
}

int main()
{
 do_backtrace();
 return 0;
}

Я получал ошибки связывания, потому что я (опять же) забыл разместить параметры компоновщика в конце командной строки. Я действительно не понимаю, почему g++/gcc не выдает хотя бы предупреждение при игнорировании параметров командной строки. Правильная командная строка для компиляции (-g не требуется):

g++ -static unwind.cpp -o unwind -lunwind -lunwind-x86

Ответ 2

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

Но это не простая задача, поэтому я предлагаю использовать флаг -rdynamic.