2015-01-07 11 views
8

Я делаю трассировку стека в какой-то момент в моей программе. Однажды с libcbacktrace_symbols() функция и один раз с unw_get_proc_name() от libunwind.Различное смещение в libc backtrace_symbols() и libunwind's un_get_proc_name()

backtrace_symbols() Выход:

/home/jj/test/mylib.so(+0x97004)[0x7f6b47ce9004] 

unw_get_proc_name() Выход:

ip: 0x7f6b47ce9004, offset: 0x458e4 

Здесь вы видите, что инструкция указатель адрес (0x7f6b47ce9004) то же самое и правильно , Функция сдвига 0x97004 от backtrace_symbols() тоже правильно, но не один я получаю от unw_get_proc_name() (0x458e4).

Кто-нибудь знает, что здесь происходит и что может вызвать эту разницу в смещениях?

Оба метода используют подобный код, как в следующих примерах:

трассировку():

void *array[10]; 
size_t size; 

size = backtrace(array, 10); 
backtrace_symbols_fd(array, size, STDERR_FILENO); 

libunwind:

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); 
} 
+0

Вы не проверяете возвращаемое значение из un_get_proc_name. Возможно, это не удается и возвращает код ошибки?Кажется, это не так, но ИМО вам все равно. Кроме того, вы не показываете printf для backtrace(). Тот, который для libunwind может предположить, что у вас напечатаны ваши принты неверно. – Krzak

ответ

1

Я считаю unw_get_proc_name вычислить смещение от неназванный внутренний кадр.

Например:

void f() { 
    int i; 
    while (...) { 
    int j; 
    } 
} 

Примечание есть объявление переменной внутри блока цикла. В этом случае (и в зависимости от уровня оптимизации) компилятор может создать фрейм (и соответствующую информацию разматывания) для цикла. Следовательно, unw_get_proc_name вычисляет смещение от этого цикла вместо начала функции.

Это объясняется в unw_get_proc_name человека странице:

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

Вы можете попытаться проверить еще раз, но без зачистки ваш бинарный файл (С unw_get_proc_name не в состоянии найти имя функции, я думаю, что ваш бинарный файл раздели).

+0

Видите это предложение в документации, и это имеет смысл. Но почему backtrace() затем способен вычислять реальное смещение? Мне кажется, что моя проблема связана с другой причиной. – tur1ng

+0

Ну ... я наконец задаю себе тот же вопрос ... :-(Единственное, на что я уверен, находится на i386/x86_64, либо backtrace (используя 'libgcc_s.so'), так и' libunwind' полагается на информацию .eh_frame. Следовательно, эти различия возникают из-за реализации libunwind и libgcc_s. В то время как 'libunwind' явно обнаруживает проблему, я не нахожу ссылки на это в' libgcc_s.so'. – Jezz

 Смежные вопросы

  • Нет связанных вопросов^_^