Интерпретация результатов проверки приложений: повреждение кучи или неверный перевод адреса стека как адреса кучи? - PullRequest
2 голосов
/ 18 февраля 2011

У нас есть тестовый пример, который приводит к сбою нашего большого приложения на основе MFC с ошибкой повреждения кучи.

Я включил кучу страниц, используя App Verifier для рассматриваемой DLL (к сожалению, включение кучи для всего процесса не работает по другим причинам.) Верификатор не дал нам больше информации, чем мы уже имел; он сработал в той же точке, что и исходный сбой.

Прямо сейчас у меня есть две конкурирующие теории. Какая теория, по вашему мнению, с большей вероятностью будет правильной, и какими будут ваши следующие шаги?

  1. Это действительно кучная коррупция. Верификатор не улавливает исходное повреждение, потому что это происходит в другой DLL. Мы должны попытаться активировать верификатор для большего количества библиотек DLL и определить, какой код повреждает кучу.
  2. Куча в порядке; проблема в том, что мы рассматриваем адрес стека как адрес кучи. Мы должны изучить код в этом стеке вызовов дальше, чтобы выяснить, что происходит не так.

Я склоняюсь к # 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.

1 Ответ

1 голос
/ 18 февраля 2011

Я думаю, что ваша строка или ее пользователи переполняют / переполняют буфер строки где-то, вероятно, напротив поля, которое находится рядом с указателем строки, которое вы затем пытаетесь освободить.

Ваш RSP12D570, который находится на расстоянии 94 квадратов (дюймов) от того, что вы пытаетесь освободить, поэтому где-то между ними происходит что-то плохое с буферами.

Убедитесь, что вы не делаете небезопасных операций с строками и чтоправильно читать документацию для передачи буферов / строк в используемые вами DLL.

Возможно, вам понадобится больше кода в вашем вопросе, если вы хотите более точный ответ.

...