7

I have some code in MS VC++ 6.0 that I am debugging. For some reason, at this certain point where I am trying to delete some dynamically allocated memory, it breaks and I get a pop up message box saying "User Breakpoint called from code at blah blah".. then the Disassembly window pops up and I see

*memory address* int      3

The odd thing is, there is NOWHERE in the code that I am calling an assembly instruction like this (I think asm int 3 is a hardware break command for x86?)..

what could be causing this?

EDIT: ANSWER: My code was "walking off the end" of an array, but only in the locations marked by Visual Studio debug with 0xFDFDFDFD, which is called a NoMan'sLand fence.. I think its also called an Off-by-one error.. This array was unrelated to the point where i was freeing the memory when the error was occuring. Which made it harder to spot.. :(

EvilTeach
  • 28,120
  • 21
  • 85
  • 141
krebstar
  • 3,956
  • 8
  • 46
  • 64
  • Just curious - did you find this by single stepping the assembly instructions to find out what the debug heap didn't like or did some other tool/technique help out? – Michael Burr Dec 22 '08 at 19:24
  • I looked at this site http://www.highprogrammer.com/alan/windev/visualstudio.html which said: that 0xFDFDFDFD was a memory value that the MSVC++ debugger used to indicate a boundary in an array to detect off-by-one errors.. I checked my pointers and single stepped through the iterations in the.. – krebstar Dec 22 '08 at 23:11
  • source code and found that I hadn't bounded one of my arrays properly.. So I guess it was just a case of me needing to check my pointers properly :) – krebstar Dec 22 '08 at 23:12
  • Just an FYI - here's a post that details most of the special fill values the debug heap uses: http://stackoverflow.com/questions/370195/when-and-why-will-an-os-initialise-memory-to-0xcd-0xdd-etc-on-mallocfreenewdele#370362 – Michael Burr Dec 23 '08 at 00:33
  • Yes, I believe the link I gave above contained the same information under "Funny" memory values.. :) Can someone close this? I have not enough rep :P – krebstar Dec 23 '08 at 04:09

2 Answers2

8

You're probably hitting code in the debug heap routines that have found heap corruption.

What does the call stack look like when you've hit the Int 3?

Edit: Based on the stack trace in your comments, the routine _CrtIsValidHeapPointer() is saying that the pointer being freed is bad. Here's the snippet of code from MSVC's DBGHEAP.C source:

    /*
     * If this ASSERT fails, a bad pointer has been passed in. It may be
     * totally bogus, or it may have been allocated from another heap.
     * The pointer MUST come from the 'local' heap.
     */
    _ASSERTE(_CrtIsValidHeapPointer(pUserData));

pUserData would be the value of the pointer you're deleteing.

Michael Burr
  • 333,147
  • 50
  • 533
  • 760
  • NTDLL! 7c90120e() NTDLL! 7c95d454() NTDLL! 7c96c5cf() NTDLL! 7c9603b0() KERNEL32! 7c85f8d7() – krebstar Dec 22 '08 at 02:04
  • _CrtIsValidHeapPointer(const void * 0x04880068) line 1697 _free_dbg_lk(void * 0x04880068, int 1) line 1044 + 9 bytes _free_dbg(void * 0x04880068, int 1) line 1001 + 13 bytes operator delete(void * 0x04880068) line 351 + 11 bytes – krebstar Dec 22 '08 at 02:04
  • I think you need to get the Windows system DLL's symbols loaded. I don't think MSVC 6 supports that (but I may be wrong) - you might want to download Debugging Tools for Windows and use the WinDBG debugger: http://www.microsoft.com/whdc/devtools/debugging/installx86.mspx – Michael Burr Dec 22 '08 at 02:06
  • Since it's breaking in _CrtIsValidHeapPointer(), you're likely to be freeing a pointer with a bogus value. – Michael Burr Dec 22 '08 at 02:08
  • Thanks for the link.. What does bogus value mean? Garbage, like, the pointer wasn't initialized in the first place? I'm pretty sure it was :( – krebstar Dec 22 '08 at 02:10
  • BTW, before it breaks, I get a message in the output window that says First-chance exception in XXXXX.exe (NTDLL.DLL): 0xC0000005: Access Violation. However this does not break and a few lines down the code is where it breaks.. – krebstar Dec 22 '08 at 02:12
  • I'd say put a breakpoint on your delete call, then start tracing in the assembly - you can follow along with the runtime source in the VC98\CRT\SRC directory. – Michael Burr Dec 22 '08 at 02:17
  • I'm not too sure about tracing in assembly, I'm not too good with it yet.. But thanks :) I think I'll try to see if the pointer is valid.. :) – krebstar Dec 22 '08 at 02:30
  • Just make sure the value you're deleting is the same value you get from new. If so, make sure you're not deleting it more than once. – Michael Burr Dec 22 '08 at 02:40
  • I just checked it, and the pointer is valid. there is a memory address, and i can expound it to show its members.. The pointer in question is a pointer to a class.. There is only one created in my execution, and this is the only point where it is deleted :( – krebstar Dec 22 '08 at 02:44
  • Maybe show the code that creates the pointer - you're using the `new` operator to set the pointer? – Michael Burr Dec 22 '08 at 02:46
  • Is the memory the pointer is pointing to being allocated in one module (EXE or DLL) and freed in another? – Michael Burr Dec 22 '08 at 02:49
  • No, the memory is allocated and freed in the same module (DLL).. :( and yes, I am using "new".. it goes like.. pointer = new CustomClass(initializer); and is freed with delete pointer; – krebstar Dec 22 '08 at 03:02
  • Hmm - I think you're going to have to step into the x86 assembly instructions to see what the runtime doesn't like (or you could compile the runtime to get source access to it - but I think that might possibly be more painful than wading through the assembly). – Michael Burr Dec 22 '08 at 03:09
3

(I think asm int 3 is a hardware break command for x86?

It is. It's called "hardware breakpoint". If you're using the VS debugger with the project source code, it's just like a breakpoint (but in the code). Since vs2005, if your application is launched without any debugger, the application will simply crash, like if it launched an unmanaged exception.

In lot of company, there is a simple macro used to add that breakpoint in the code. That can replace asserts and exceptions in some (hard and rare) cases :

#define BREAKPOINT __asm { int 3; }

BREAKPOINT;

See :

So i suggest looking for some Macro or object doing this, or maybe it appen in a module (dll/lib) that you don't have the code of?

Klaim
  • 67,274
  • 36
  • 133
  • 188
  • Yes there is some dll/lib that is opened in the program, and I don't have source code for it. However I do not think this is the cause.. Michael Burr's seems more likely.. Thanks anyway :) – krebstar Dec 22 '08 at 02:29