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, чтобы разобрать.)
Основываясь на комментарии @ Игоря, я посмотрел на макеты классов, используя -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__
установка.