[Глубокий вдох.] У нас есть приложение, которое выводит окно с использованием WxMotif 2.6.3 (библиотека GUI не была - и не является - моим выбором). Он отлично работает на 32-разрядных системах ix86. У меня была задача конвертировать его в 64-битное приложение. Это всегда seg-faults. Я нахожусь на 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, сборка "получить"
mov 0x1e0(%rax),%rax
В objdump, как get, так и set используют 0x1e0 в качестве смещения. Что происходит?
Я загрузил некоторую релевантную информацию здесь: GitHub
Я включил небольшую программу, которая реплицирует проблему в моей системе.
Изучая далее, я вижу в разборке wxFrame:: DoCreate, который далее использует m_mainWidget для получения значения с использованием 0x1e0 в качестве смещения (разборка выполняется в компиляции, где я использовал -O0, поэтому код должен вернуться назад в память каждый раз). "Just for Fun", я добавил новую переменную-член в wxFrame-m_myMainWidget и установил ее сразу после установки m_mainWidget. Затем я получил wxFrame:: GetMainWidget(), чтобы вернуть локальное значение (m_myMainWidget). Разве вы не знаете об этом: Сбой все еще происходит, и GetMainWidget содержит то же смещение +16, когда я разбираюсь изнутри gdb. (Смещение не там, где я использую objdump для демонтажа.)