Последние несколько дней были потрачены на отладку очень странной проблемы. Приложение, созданное для i386, работающее в Windows, аварийно завершает работу, верхняя часть стека вызовов полностью повреждена, а указатель инструкций находится в бессмысленном месте.
После некоторых усилий я перестроил стек вызовов и смог определить, как IP-адрес оказался в бессмысленном месте. Инструкция в коде общего указателя boost пытается вызвать функцию, определенную в моей таблице адресов импорта DLL, используя неправильное смещение. Инструкция выглядит так:
call dword ptr [nonsense offset into import address table]
В результате выполнение оказалось в плохом месте, которое, к сожалению, было исполняемым. Затем выполнение продолжилось, поглощая вершину стека, пока в конечном итоге не завершилось сбоем.
Запустив идентичное приложение на моем ПК и вступив в проблемный код, я могу найти ту же инструкцию вызова и увидеть, что она должна выполняться, вызывая «новый» оператор msvc100.
Далее, сравнивая минидамп с ПК клиента на свой ПК, я обнаружил, что мой ПК вызывает функцию со смещением 0x0254 в адресной таблице. На клиентском ПК код пытается вызвать функцию со смещением 0x8254.
Что еще больше сбивает с толку, так это то, что это смещение исходит не из регистра или другого места в памяти. Смещение является константой в дизассемблировании. Итак, разборка выглядит так:
call dword ptr [ 0x50018254 ]
не как:
call dword ptr [ edx ]
Кто-нибудь знает, как это может произойти?