Larry lindstro 2006-07-11 16:11:44
Developing on Win2K, VC6, WIN32, no MFC.
I’ve been hit with a tough problem.
The debugger is stopping and displaying a popup with these
(i) User breakpoint called from code at 0x77f9193c
These things are hitting me at unpredictable points in
the program, but I can consistently get this message to pop
up at a particular new operator.
If I push “OK” the program continues to execute, with
no apparent ill effects.
The actions that consistently trigger the problem in the
VC6 debugger don’t seem to phase the release version running
on a laptop with Windows XP. But I don’t want to release
this until I figure out what the problem is.
What tools, preferably free or inexpensive, should I use
to get to the bottom of this?
I’m suspecting heap corruption, and I found references
to PageHeap in Google’s archives and MSDN.
I tried PageHeap, I expanded Microsoft’s example of a
project, “pgh” that is supposed to demonstrate its use.
I Don’t know what I’m looking at with PGH, I can’t find a
WinMain, but PGH seems to work, and fail, as expected.
The instructions at
talk of starting this from the command line:
pageheap /enable pgh.exe 0x01
First, I build the project. The instructions say
“You must do a release build for PageHeap to work with
new/malloc.” That’s a bummer, how do I debug a release
build? The instructions say ” You must use a run-time DLL
library for PageHeap to work”. That’s OK, I use
Multithreaded DLL for the runtime library anyway.
So I build the sample app, pgh.
Pageheap.exe was expanded into the project’s directory,
the one with the source, and the VC build put the executable
in the release directory. So I run the sample with:
pageheap /enable release/pgh.exe 0x01
and Win2K responds with:
Error: Cannot open image registry key for release/pgh.exe
What’s this? The instructions say nothing about setting up
a registery entry.
I just run the project from VC6’s IDE, to see what will
The instructions explain how the user can make choices
on the test program’s dialog that will cause a problem
PageHeap can detect. Clicking “New” allocates 5 bytes
and overflows that by writing 6 bytes. This isn’t
detected until the memory is deleted. Then the following
message is supposed to pop up:
The exception Breakpoint A breakpoint has been
reached. (0x80000003) occurred in the application
at location 0x77f9f9df.
I’m not getting that error message on the first click.
The second click of the delete causes this to pop up:
(i) User breakpoint called from 0x77f913c
The instructions then say “If you have Visual C++
specified as JIT debugger, you can click on the “Cancel”
button and debug into the code.” How do I specify
Visual C++ as a JIT debugger? Isn’t it going to try to
debug a program that has no symbolic information for the
Moving on, to something called “Debugging Tools for
Windows”. What is this package. It contains a debugger,
can it be used with VC6? Is there any advantage in doing
Any other suggestions on how I can figure this heap
problem, if that’s what it is, are appreciated.
Alex fedotov 2006-07-11 16:11:57
Sounds like heap corruption. Try to see what happens to several _prior_
allocations. Check if you overwrite the allocated buffer or delete it twice.
The point is that at the moment this particular new operator is called the
heap is already corrupted, so you need to check the code that executes
Also, make sure you use CRT debug allocator in debug builds. Read on _CRTDBG_MAP_ALLOC and _CrtSetDbgFlag.
I always used PageHeap through gflags.exe, which is available in the
“Debugging Tools for Windows” package.
1) run gflags.exe
2) click Image File tab
3) type in your executable name without path (e.g. pgh.exe) and press TAB
4) select “Enable page heap” and all of the heap checks (“Enable heap tail
checking” and so on)
5) additionally you may want to enable the application verifier although it
detects different kinds of problems
6) click OK.
Now you can run your application as usual, under the debugger or not, it
will have the page heap enabled. Depending on the error encountered, the
application will either hit a breakpoint or just crash with an access
violation (for buffer overflows).
That’s true. In fact, it’s wise to always build release version with debug
information in a separate .pdb file. This way you can ship the executable to
the customer but retain the matching .pdb file for future troubleshooting.
To do so, in your Release configuration:
1) in C/C++ settings, choose Debug Information Format -> Program Database (/Zi)
2) in Linker settings, choose Debug -> Yes (/DEBUG)
3) in Linker settings, Optimizations, choose /OPT:REF and /OPT:ICF (I don’t
remember how they are presented in the UI).
With these settings you will receive an executable, which is identical to
what you had before (no debugging overhead whatsoever), and in addition you
will have a .pdb file with debug info. You can now step through your release
code, examine call stacks, and so on. However, take what you see in the
debugger with a grain of salt, sometimes it may display wrong variable
values or step through the code erratically. This is because you are debugging optimized code.
I don’t find WinDbg any beneficial to the Visual Studio IDE debugger for
user-mode debugging, although WinDbg does have many features not available
in the IDE debugger (e.g. the ability to interpret and display internal
Windows structures). I may have used it once or twice to debug difficult
synchronization problems, but that’s it. I install it to get gflags.exe and
the latest symsrv.dll so I can download debugging symbols for Windows system
— Alex Fedotov
Larry lindstro 2006-07-11 16:12:21
< Snip >
I found it, using this information. A delete function calls
DestroyWindow(), which deletes an instance of a class I contrived
to pass two pointers in the CreateDialogParam’s parameter, then I
attempt to NULL one of the pointers in the recently destroyed class instance.
Debug information for every release build that gets distributed
to customers? That sounds like a great idea.
I’ve done this once before, when a release blew up but the
debugger version ran fine. I posted the question on this
newsgroup late December 2003 and someone posting as Skywing
told me about setting debugger information. It was horrible,
I spent 6 hours finding the bug. But Skywing supplied the
first hints and that did eventually grow into a solution. So
I’m grateful for Skywing’s advice, as I am for yours.
I understand why I had to apply the debugging symbols to
that release. I don’t understand why Microsoft requires it
for this program that actually has a debug version ready to test.
Alex, I’m very grateful for your advice. I was starting
to get depressed after looking at this for two days.