Отладчик Visual C++ и загадка BoundsChecker
Посмотрите на этот скриншот сеанса отладчика Visual C++:
http://yp.lviv.ua/philez/wtf.PNG
Точка выполнения теперь находится внутри виртуальной функции. "mDb" - это ссылка на объект, который является членом этого класса. "mDb" имеет тип CDbBackend &. Есть только одна нить. Значения в красных прямоугольниках должны быть равными, но это не так. Как это может быть возможным?
Отлаживаемый код был оснащен BoundsChecker (отладчик и профилировщик памяти). Несоответствие приводит к краху позже. Неинструментированный код не приводит ни к одному из этих эффектов. Я думаю, что рано обвинять BoundsChecker - это может быть скрытая ошибка в моей программе, которую BoundsChecker обнаружил, поэтому я очень склонен понимать ситуацию.
Сборка, сгенерированная для оператора "b = &mDb", выглядит следующим образом, на случай, если это уместно. Здесь описывается пошаговое выполнение этой сборки с видимыми часами и регистрами (avi-файл 500 КБ).
007AB7B0 push 4
007AB7B2 push 80000643h
007AB7B7 push 4
007AB7B9 push 0C0002643h
007AB7BE lea eax,[ebp-10h]
007AB7C1 push eax
007AB7C2 call dword ptr [_numega_finalcheck_C_110456 (8FA8A8h)]
007AB7C8 mov eax,dword ptr [eax]
007AB7CA add eax,1CCh
007AB7CF push eax
007AB7D0 call dword ptr [_numega_finalcheck_C_110456 (8FA8A8h)]
007AB7D6 mov dword ptr [ebp-70h],eax
007AB7D9 push dword ptr [ebp-70h]
007AB7DC push 4
007AB7DE push 50000643h
007AB7E3 lea eax,[ebp-20h]
007AB7E6 push eax
007AB7E7 call dword ptr [_numega_finalcheck_Y_110456 (8FA8ECh)]
007AB7ED mov ecx,dword ptr [ebp-70h]
007AB7F0 mov ecx,dword ptr [ecx]
007AB7F2 mov dword ptr [eax],ecx
2 ответа
Пожалуйста, восстановите и протестируйте его снова. (Я знаю, это звучит глупо:)
Код скомпилирован в режиме отладки без каких-либо настроек, верно? Полагаю, что так. Но при разборке никакой символической информации не представлено. Я могу видеть только
[ebp - offset]
; это должно быть представлено в виде некоторого символического имени, такого какb
, Обязательно включите "Показать имена символов" в режиме разборки.Я не уверен, что код разборки вы вставили код для
b = &mDb
, Это выглядит как[ebp-10h]
или же[ebp-70h]
было быb
, ноmDb
не похоже здесь. Весь код здесь просто вызывает инструментальную функцию. Не могли бы вы дать больше разборок с исходным кодом вокруг них?У меня есть опыт, когда отладочная информация генерируется неправильно, поэтому символическая отладка дала неверное значение. Мой обходной путь состоял в том, что я изменил расположение переменных-членов и поместил некоторые отступы в локальный стек. Но я не уверен, что это действительно ошибка компилятора. Я работал над Visual Studio 2008 с компилятором Intel C/C++, и проект был довольно сложным.
Информации недостаточно для решения этой проблемы. Было бы лучше, если вы дадите больше разборки.
Является ли mDb также типа CDbBackend? Если нет, то расхождение связано с кастингом.
Дано:
class A
{
// Stuff
};
class B : public A
{
// More stuff
};
B *b = new B;
A *a = (A *)&b;
тогда b и a могут или не могут быть эквивалентны в зависимости от того, что именно означает "Материал" и "Больше материала". Самые большие вещи, которые изменят приведение указателей, это виртуальные и множественное наследование. Если это так в вашем примере, то вывод вашего отладчика будет правильным и нормальным поведением. Если вы расширите представление класса для mDb, я не удивлюсь, если вы найдете в нем указатель CDbBackend, который соответствует вашему второму выводу ниже.