简体   繁体   中英

Debugging memory corruption

Earlier I encountered a problem with dynamic memory in C (visual studio) . I had a more or less working program that threw a run-time error when freeing one of the buffers. It was a clear memory corruption, the program wrote over the end of the buffer.

My problem is, that it was very time consuming to track down. The error was thrown way down after the corruption, and i had to manually debug the entire run to find when is the buffer end overwritten.

Is there any tool\\ way to assist in tracking down this issue? if the program would have crashed immediately i would have found the problem a lot faster...

an example of the issue:

int *pNum = malloc(10 * sizeof(int));

//                 ||
//                 \/    
for(int i = 0; i < 13; i++)
{
pNum[i] = 3;
}

// error....
free(pNum);

I use "data breakpoints" for that. In your case, when the program crashes, it might first complain like this:

Heap block at 00397848 modified at 0039789C past requested size of 4c

Then, start your program again, and set a data breakpoint at address 0039789C . When the code writes to that address, the execution will stop. It often happens that i find the bug immediately at this point.

If your program allocates and deallocates memory repeatedly, and it happens to be at this exact address, just disable deallocations:

_CrtSetDbgFlag(_CrtSetDbgFlag(_CRTDBG_REPORT_FLAG) | _CRTDBG_DELAY_FREE_MEM_DF);

I use pageheap . This is a tool from Microsoft that changes how the allocator works. With pageheap on, when you call malloc, the allocation is rounded up to the nearest page(a block of memory), and an additional page of virtual memory that is set to no-read/no-write is placed after it. The dynamic memory you allocate is aligned so that the end of your buffer is just before the end of the page before the virtual page. This way, if you go over the edge of your buffer, often by a single byte, the debugger can catch it easily.

Is there any tool\\ way to assist in tracking down this issue?

Yes, that's precisely the type of error which static code analysers try to locate. eg splint / PC-Lint

Here's a list of such tools: http://en.wikipedia.org/wiki/List_of_tools_for_static_code_analysis

Edit: In trying out splint on your code snippet I get the following warning:

main.c:9:2: Possible out-of-bounds store: pnum[i]

Presumably this warning would have assisted you.

Our CheckPointer tool can help find memory management errors. It works with GCC 3/4 and Microsoft dialects of C.

Many dynamic checkers only catch accesses outside of an object, and then only if the object is heap allocated. CheckPointer will find memory access errors inside a heap-allocated object; it is illegal to access off the end of a field in a struct regardless of the field type; most dynamic checkers cannot detect such errors. It will also find accesses off the edge of locals.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM