В настоящее время я работаю над довольно большой (и старой, вздохующей) кодовой базой, недавно обновленной до VS2005 (SP1). Я и моя команда меняем / обновляем / заменяем модули в этом коде по ходу работы, но мы иногда сталкиваемся с проблемами, когда кажется, что vtables не работает. Я не эксперт по vtables, но они наверняка не работают. Ошибки проявляются с этой ошибкой:
Ошибка проверки времени выполнения # 0 - значение ESP не было должным образом сохранено при вызове функции. Обычно это является результатом вызова функции, объявленной с одним соглашением о вызовах с указателем функции, объявленным с другим соглашением о вызовах.
Конечно, для этой ошибки может быть множество других причин, но при отладке (сборка отладки) я могу убедиться, что виртуальные таблицы для объекта, над которым я хочу работать, выглядят странно:
Стек и куча, которые ссылаются на каждый vtable, выглядят нормально, а указатели на vtables идеально соответствуют файлу карты. Это указывает на то, что это не ошибка перезаписи памяти или что-то подобное, так как тогда это повлияет на стек и кучу, а не на то, где хранятся виртуальные таблицы. (Они хранятся в области только для чтения, верно?) В любом случае, пока все выглядит хорошо. Но, глядя на память vtable, я обнаружил, что все значения, если я интерпретирую их как указатели, хотя они находятся в одном диапазоне (например, 0x00f203db 0x00f0f9be 0x00ecdda7 0x00f171e1), не соответствуют ни одной записи в файле карты, и многие из них даже не выровнены до 4 байтов. Я не знаю всех деталей того, как VS2005 собирает vtables, но мне это кажется неправильным. Если это правильное поведение, возможно, кто-то может мне это объяснить?
Полагаю, мой вопрос сводится к тому, что может вызвать такое поведение? Есть ли какие-либо известные ошибки в компоновщике, например, при наличии слишком сложной иерархии классов? Кто-нибудь видел что-нибудь подобное раньше? В настоящее время мы можем обойти наши сбои, переместив функции из затронутого класса во встроенный (страшная штука!), Но очевидно, что это неосуществимое долгосрочное решение.
Спасибо за понимание!
Обновление: меня попросили более подробную информацию о проекте, и, конечно, я предоставлю это. Однако, во-первых, вопрос не полностью связан с ошибкой сохранения значения ESP. Больше всего меня интересует, почему я вижу странные значения в vtable. Тем не менее, вот некоторая дополнительная информация: Решение опирается на несколько внешних и внутренних проектов, но они не менялись в течение длительного времени, все используют одно и то же соглашение о вызовах. Код, в котором кажется, что он ломается, находится внутри одного довольно стандартного C ++ «основного» проекта решения. Весь код построен с использованием одного и того же компилятора. В решении также не используются библиотеки DLL, но есть ссылки на множество статических библиотек:
SHFolder.lib, python25.lib, dxguid.lib, d3d9.lib, d3dx9.lib, dinput8.lib, ddraw.lib, dxerr9.lib, ws2_32.lib, mss32.lib, Winmm.lib, vtuneapi.lib , vttriggers.lib, DbgHelp.lib, kernel32.lib, user32.lib, gdi32.lib, winspool.lib, comdlg32.lib, advapi32.lib, shell32.lib, ole32.lib, oleaut32.lib, uuid.lib, odbc32 .lib, odbccp32.lib