Callstack, map2dbg -------------------- (c) 2000 Lucian Wischik These two programs let you print a callstack from your debug routines in C++Builder programs. This is helpful for diagnosing bugs and crashes. This makes remote debugging easier (when a client a thousand kilometers away experiences erratic crashes in your program). The programs also allow the standard DrWatson utility to extract more information about your program after a crash. Technically, their main contribution is to bring MS-compatible debug files to Borland-generated executables, and to show you how you can manipulate this information in your own code. The files and their source code are completely free. You may do with them what you wish. However, if you make any useful changes, please let me know so I can incorporate them in future releases! The stackwalk routines owe a great deal to Felix Kasza's stackwalk example code at http://www.mvps.org/win32/misc/stackwalk.html He has a wide range of other example code there. Visit his site! You will benefit greatly! The DBG-writing routines owe a lot to Matt Pietrik's "Under the Hood" article in the March1999 Microsoft Systems Journal, at http://msdn.microsoft.com/library/periodic/period99/hood0399.htm QUICK START Run the program calldemo.exe and click the button. That shows you what can be achieved. Launch BCB, Components|InstallPackage, and install map2dbgexp.bpl. (That's because ms-dbg info is needed for the callstack to work. You can disable it by unchecking Help|Generate-msdbg.) Write your own program and add CALLDEMO\CALLSTACK.CPP and .H. Call AnsiString s = dcallstack(); inside your program to retrieve the current call-stack. The Help|Generate-MsDbg happens automatically upon compilation of your program. If you'd prefer, you can instead use the command-line program map2dbg.exe manually, every time after you've compiled. DISCUSSION Microsoft implemented a "imagehlp" library to provide call-stacks and symbol information. They use it in DrWatson, and you can use it in your own programs. It requires debug information, either in the executable or "stripped out" in a separate debug file. Most Microsoft programs come with stripped-out .DBG files. If a user chooses to put the DBG file in the program directory, then symbol information becomes available; if not, then it isn't. Unfortunately, DrWatson and the imagehlp library require MS-compatible debug information. And Borland generates non-compatible information. We need a way to convert from borland-format to ms-format. I wrote a routine "MAP2DBG" which takes a Borland-generated .MAP file, and generates the appropriate .DBG file, and marks the executable with a flag saying that the debug-information has been stripped out. There is a second problem. Every time you recompile your program, making a new executable, that flag gets lost! And without the flag, the system believes that all the debug-information is in the .exe not the .dbg, and so it ignores the .dbg totally. My solution was an expert which automatically marks it as debug-stripped every time it compiles. Or, use the command map2dbg /nomap file.exe. There is a third problem. The imagehlp library provides a standard way to change header information in an executable (e.g. to mark it as debug-stripped). But these standard routines fail to work on Borland-generated executables, claiming that they're not valid. Therefore I had to write mark-as-stripped routines from scratch. This also affected the loading of debug symbols. Again, we can't use imagehlp to automatically load all the symbols, because it doesn't believe that the BCB-generated executable is valid. Instead, we have to explicitly enumerate all loaded modules (using toolhelp or psapi as appropriate) and load the symbols for each module individually. To generate the dbg file merely requires the corresponding map file. It does not require Project|Options|Linker|CreateDebugInformation. It does not require UseDebugLibraries. It works fine whether you use the dynamic-RTL or the static, and it works fine whether you build with runtime packages or without. The directory MAP2DBG contains source code for the conversion utility. Comments in the map2dbg.cpp file explain the file-format of a simple .dbg file. STRIPPER contains the source code for the expert and isn't very interesting. The example in CALLDEMO is the one you should look at and copy into your own programs. NOTES I haven't tested this much at all. I've only run it on Win2000. If you use it in your own programs succesfully, please let me know! If there are bugs, or limitations, or irritations, please let me know! Email me at lu@wischik.com or go to my web site www.wischik.com/lu/programmer to look for updates.