Segfault: и разборка между objdump и gdb отличается

[Глубокий вдох.] У нас есть приложение, которое открывает окно с помощью WxMotif 2.6.3 (библиотека GUI не была и не будет моим выбором).
Он отлично работает на 32-битных системах ix86. У меня была задача преобразовать его в 64-битное приложение. Это всегда ошибки.
Я на RHEL 6, поэтому я скомпилировал с помощью gcc 4.4.7. После большого скрежета зубов проблема кажется очевидной: в wxFrame :: DoCreate m_mainWidget установлен (правильно); в wxFrame :: GetMainWidget возвращается как нулевой указатель. Нулевой указатель приводит к падению.
Используя gdb, инструкция, которая устанавливает m_mainWidget:

mov    %rax,0x1e0(%rdx) # $rdx = 0x68b2f0

тогда как код, который получает m_mainWidget

mov    0x1f0(%rax),%rax # $rax = 0x68b2f0

В gdb я могу проверить память и убедиться, что указатель на 0x68b4d0 правильный. Почему смещение неверно?

Чтобы запутать вещи еще больше, когда я использую objdump для дизассемблирования libwx_motifd_core-2.6.so.0.3.1, сборка «get»

  mov    0x1e0(%rax),%rax

В objdump и get, и set используют 0x1e0 в качестве смещения. Что здесь происходит?

Я загрузил соответствующую информацию здесь:
GitHub

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

Дальнейшее изучение я вижу в разборке wxFrame :: DoCreate, что дальнейшее использование m_mainWidget извлекает значение, используя 0x1e0 в качестве смещения (Разборка находится на компиляции, где я использовал -O0, поэтому код должен возвращаться в память каждый раз).
«Просто для удовольствия», я добавил новую переменную-член в wxFrame — m_myMainWidget — и установил ее сразу после установки m_mainWidget. Затем я должен был wxFrame :: GetMainWidget () вернуть локальное значение (m_myMainWidget). Разве вы не знаете это: сбой все еще происходит, и GetMainWidget содержит то же самое смещение +16, когда я разбираю изнутри gdb. (Смещение не там, где я использую objdump, чтобы разобрать.)

10

Решение

Основываясь на комментарии @ Игоря, я посмотрел на макеты классов, используя -fdump-class-hierarchy опция компилятора. Оказывается, что действительно есть несоответствие размещения vtable, из-за этого условного блока в include/wx/app.h:

#ifdef __WXDEBUG__
virtual void OnAssert(const wxChar *file,
int line,
const wxChar *cond,
const wxChar *msg);
#endif // __WXDEBUG__

Вы должны убедиться, что вы компилируете свой код с тем же __WXDEBUG__ установка.

2

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


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