From: Yitzhak Sapir (yitzhaks_at_[hidden])
Date: 2002-06-19 09:31:58
> -----Original Message-----
> From: David Abrahams [mailto:david.abrahams_at_[hidden]]
> On systems where there's a built-in facility for that (Windows, Unix),
> anything you can do yourself is going to be vastly inferior
> to what the
> system can give you by default. On Windows you get JIT
> debugging, which
> invokes a debugger on the program with (if you know the right
> tricks) the
> entire program state preserved. On Unix, a core dump is a
> debuggable image
> of the program state.
> I would never trade what's supplied by the platform for a cumbersome
> intrusive facility that requires manual intervention.
I wouldn't trade either one for the other one. I would use both. More information has never been a problem if I want to debug.
I'm writing this with experience in assembly debugging of a complex C++ program in an optimized ("release mode") executable under Windows/Intel platform, using VC6.5 as the compiler.
Even if compiled under VC6 in release mode with "Debug Info: Line numbers only" (which at least by my experience proved to be the only useful information since local variables are optimized away), I often don't see the state of the program when I pause it and look at the "Debug - Threads" menu. Nor if I select a thread from this menu can I usually see its stack. If its in a kernel function, there is usually a skip of several functions between the kernel addresses and the last recorded address. Those last few addresses before it went into the kernel functions are usually the more important ones since they pinpoint the problem. (If there isn't a problem to begin with, I have no intention to try to trace the stack calls manually).
To get useful information, stack unwinding must not have taken place. At least, I have no idea yet how to trace back from a stack-unwind.
To get the information I place the stack register ("esp" in the intel case which is the case that applies to me) in the memory window and look back for typical return addresses of functions in my program (which are usually, in the Windows case, 0x400000 + to around 0xA00000, sometimes more sometimes less). A map file would be more exact, but just looking for addresses in the range is good and quick enough so I've never bothered with a mapfile for this purpose. Because I compiled and linked using debug info: line numbers only, displaying these in the disassembly window also shows me the C++ code around those lines. Sometimes I can also use the disassembly to figure out the this pointer or the parameters that the function was called with. All this information is vastly more than what I would have gotten by using the Debug window for Threads or Debug window for Call Stack, or both.
If I could run a function that simply inspected the stack for possible addresses and dumped all it could find, whether true pointers to return address locations or not, all the above would be much simpler. If I had a Windows-supplied function, I'm supposing the information I would get would not be much different from what I see using Debug-Call Stack. But maybe I'm wrong.
This mostly applies to release-mode debugging (ie, with aggressive optimizations). In Debug-mode (no optimizations), I usually don't get to this stage.
Given all this, a function that I had supplied which did all this would still be inferior in the respect that I using the JIT debugging could be more creative in looking at parameters and variables that the supplied-function didn't look at. It wouldn't be inferior in the respect that immediately available information such as available call stack in the JIT debugger would probably give me less information that a function that did just what I do manually.
My point in writing all this is to describe: The usefulness of a procedure to read return addresses from the stack directly. That this procedure could easily(?) be mechanized. That this procedure would be a useful addition to the normal debugging information I get from the Windows VC6 platform. That I would very much like this to be at least an optional implementation for a "call-stack-walkthrough" platform-independent interface.
Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk