Отладчик 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 ответа

  1. Пожалуйста, восстановите и протестируйте его снова. (Я знаю, это звучит глупо:)

  2. Код скомпилирован в режиме отладки без каких-либо настроек, верно? Полагаю, что так. Но при разборке никакой символической информации не представлено. Я могу видеть только [ebp - offset]; это должно быть представлено в виде некоторого символического имени, такого как b, Обязательно включите "Показать имена символов" в режиме разборки.

  3. Я не уверен, что код разборки вы вставили код для b = &mDb, Это выглядит как [ebp-10h] или же [ebp-70h] было бы b, но mDb не похоже здесь. Весь код здесь просто вызывает инструментальную функцию. Не могли бы вы дать больше разборок с исходным кодом вокруг них?

  4. У меня есть опыт, когда отладочная информация генерируется неправильно, поэтому символическая отладка дала неверное значение. Мой обходной путь состоял в том, что я изменил расположение переменных-членов и поместил некоторые отступы в локальный стек. Но я не уверен, что это действительно ошибка компилятора. Я работал над 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, который соответствует вашему второму выводу ниже.

Другие вопросы по тегам