У нас есть тестовый пример, который приводит к сбою нашего большого приложения на основе MFC с ошибкой повреждения кучи.
Я включил кучу страниц, используя App Verifier для рассматриваемой DLL (к сожалению, включение кучи для всего процесса не работает по другим причинам.) Верификатор не дал нам больше информации, чем мы уже имел; он сработал в той же точке, что и исходный сбой.
Прямо сейчас у меня есть две конкурирующие теории. Какая теория, по вашему мнению, с большей вероятностью будет правильной, и какими будут ваши следующие шаги?
- Это действительно кучная коррупция. Верификатор не улавливает исходное повреждение, потому что это происходит в другой DLL. Мы должны попытаться активировать верификатор для большего количества библиотек DLL и определить, какой код повреждает кучу.
- Куча в порядке; проблема в том, что мы рассматриваем адрес стека как адрес кучи. Мы должны изучить код в этом стеке вызовов дальше, чтобы выяснить, что происходит не так.
Я склоняюсь к # 2, потому что параметр free () выглядит как адрес стека, но до сих пор никто не предложил объяснение того, как это возможно.
Вот фрагмент стека вызовов. MyString - это простая оболочка для CString. MyAppDll - это библиотека DLL, которая настроена на использование кучи страниц.
msvcr90.dll!free(void * pBlock=0x000000000012d6e8) Line 110
mfc90u.dll!ATL::CStringT > >::~CStringT > >() Line 1011 + 0x1e bytes
MyStringDll.dll!MyString::~MyString() Line 59
MyAppDll.dll!doStuffWithLotsOfStringInlining(MyClass* input=0x000000000012d6d0) Line 863 + 0x26 bytes
Вот регистры внутри фрейма стека free ():
RAX = 0000000000000000 RBX = 000000000012D6E8 RCX = 0000000000000000
RDX = 0000000000000000 RSI = 000000000012D6D0 RDI = 00000000253C1090
R8 = 0000000000000000 R9 = 0000000000000000 R10 = 0000000000000000
R11 = 0000000000000000 R12 = 000000000012D7D0 R13 = 000007FFFFC04CE0
R14 = 0000000025196600 R15 = 0000000000000000 RIP = 00000000725BC7BC
RSP = 000000000012D570 RBP = 000007FFF3670900 EFL = 00000000
А вот и сообщение о проверке приложения:
VERIFIER STOP 0000000000000010: pid 0x1778: Corrupted start stamp for heap block.
00000000083B1000 : Heap handle used in the call.
000000006DD394E8 : Heap block involved in the operation.
54D32858A8747589 : Size of the heap block.
000000005E33BA8D : Corrupted stamp value.