2013-10-25 4 views
1

У меня есть ошибка повреждения кучи для приложения, поэтому я включил кучу страниц из gflags и собрал файл дампа сбоев для этого приложения.Куча памяти с удвоением свободной памяти

Из файла дампа я узнал, что он должен удвоить объем памяти.

Вот пример, из стека вызовов я нашел этот

msvcr100!free(void * pBlock = "**Address**") 

Тогда я сделал это

!heap -p -a <address> 

address found in 
_HEAP @ 
    HEAP_ENTRY Size Prev Flags UserPtr UserSize - state 
    Address 000a 0000 [02] address 00003 - **(free)** 
Trace: <1> 
     <2> 
     <3> 

Таким образом, мы видим, что он пытается удвоить освободить память, и что привело к в аварии. Мой вопрос: можем ли мы увидеть стек вызовов, который изменил или освободил эту память до этой операции? Является ли это возможным?

Я вижу след под командой heap -p -a, это тот, который освободил память? Если это так, я вижу только некоторую часть стека вызовов. Есть ли способ увидеть общий стек вызовов или пройти через стек вызовов вручную, чтобы увидеть, какая операция освободила этот блок памяти.

+0

Вы просите машины времени, файл дампа не один. –

+0

Да, я знаю, что дамп-файл является моментальным снимком в этот момент времени, но просто любопытно, если включение полной кучи страниц может дать немного больше информации, чем тот, кто пытается освободить память, например, кто уже освободил память? – user2800803

+0

Вероятно, вы должны включить кучу страниц, чтобы начать работу - использовать кусочки бит для использования памяти, чтобы отметить память, так что повреждение (как двойное использование) легче поймать. Кроме того, эта ссылка должна быть полезна: http://code.msdn.microsoft.com/windowsdesktop/CppHeapCorruption-7a727b6a – deemok

ответ

1

Если у вас есть исходный код, вы можете заменить функции delete/free своими собственными функциями, которые могут захватывать стек непосредственно перед выпуском.

В окнах вы можете получить стек вызовов, используя функцию CaptureStackBackTrace, однако эти функции возвращают набор указателей, и вам нужно перевести их на имена символов. Для этого вы можете использовать SymInitialize, затем для каждого указателя вы можете использовать SymFromAddr, чтобы получить имя символа. Имена - это фактические функции, которые вы ищете.

Однако было бы проще использовать отладчик в окнах. Существует также Application Verifier, который является приложением от Microsoft, которое может помочь вам захватить повреждение кучи (при использовании с отладчиком визуальной студии).

Надеюсь, что это поможет Разван.

+0

Спасибо Raxvan, поэтому нет возможности проверить функцию, которая освободила память перед тем, как попытался стек в стеке вызовов освободить память в Windbg? – user2800803

+0

Да, вам нужно отслеживать освобожденный указатель. Вы можете сохранить команду указателей, которую вы освободили, и когда вы освободите указатель, повторите проверку с помощью набора, если указатель все еще присутствует. Внутри набора вы также можете сохранить столбец – Raxvan

0

Если вы запустите отладочную версию, есть вероятность, что вы увидите больше стека вызовов.

Смотрите также этот link