Re: [GD-Windows] Finding routine that's crashing
Brought to you by:
vexxed72
From: Colin F. <cp...@ea...> - 2002-08-02 09:05:33
|
2002 August 2nd Friday Help! First, I'm going to reply to my own post, contradicting and criticizing myself. >>> [1] Under Windows 98, the DLL with the symbol handler and >>> StackWalk() functions is called: "imagehlp.dll". >>> (i.e., different from the "dbghelp.dll" references >>> scattered around the source and project settings) Okay, the first part is true, but the posted code doesn't mention "dbghelp.dll" anywhere! I was just confused. After I couldn't get the posted code to work, I downloaded a completely different project (Bugslayer1000), and *THAT* project had "dbghelp.dll" all over the place! >>> [2] Under Windows 98, we need the process **ID** for >>> SymInitialize(), NOT the process handle. >>> (See MSDN Library documentation for SymInitialize().) This really was in the documentation, but I'm getting mixed signals from the code... (a) If I use the process ID (following MSDN documentation on SymInitialize()), the StackWalk() stops walking after a single iteration! The symbol lookup returns an empty symbol string, but doesn't complain about accessing an invalid address. (b) If I use hProcess handle (contradicting MSDN documentation on SymInitialize()), the StackWalk() walks up the stack just fine (apparently)! The symbol lookup fails (complain about accessing an invalid address). I'd really like to get the code working, just as an educational example. Here's a kind of trace of what happened: ======================================== (NOTE: The following trace assumes that we can get away with using hProcess for the symbol handler (contradicting the documentation). The trace with the process ID as symbol handler and StackWalk parameter is similar, but ends with a whimper: StackWalk() ends its walk immediately, and SymGetSymFromAddr() returns nothing!) When my test application starts executing: ------------------------------------------ ENTER ExceptionHandler::ExceptionHandler() ENTER ExceptionHandler::InitClass() LEAVE ExceptionHandler::InitClass() ENTER ExceptionHandler::InitDLL() global_hProcess = 0x7fffffff global_ProcessId = 0xfffcfd73 global_SymProcess = 0x7fffffff mHImageHlpDll = LoadLibrary("imagehlp.dll"); = 0x7d750000 LEAVE ExceptionHandler::InitDLL() Dir with executable: 'C:\WINDOWS\DESKTOP\ASSERT_CODE\TEST_ASSERT\DEBUG\TEST_ASSERT.EXE' LEAVE ExceptionHandler::ExceptionHandler() When my test application calls ASSERTx(...): -------------------------------------------- ENTER ExceptionHandler::DumpCrash(HANDLE hThread = 0xfffffffe, void* pExceptionInfo = 0x0065f8c0) About to do SymInitialize 0x7fffffff, "C:\WINDOWS\Desktop\assert_code\test_assert\Debug;C:\WINDOWS\DESKTOP\ASSERT_ CODE\TEST_ASSERT\DEBUG;", FALSE ); About to do SymSetOptions(SYMOPT_LOAD_LINES | SYMOPT_UNDNAME | SYMOPT_CASE_INSENSITIVE); About to do enumAndLoadModuleSymbols( global_hProcess, global_ProcessId ); ENTER void enumAndLoadModuleSymbols( HANDLE hProcess = 0x7fffffff, DWORD pid = 0xfffcfd73 ); . . . . . . . . . sSymLoadModule global_SymProcess = 0x7fffffff, 0, img='C:\WINDOWS\DESKTOP\ASSERT_CODE\TEST_ASSERT\DEBUG\STDASSERT.DLL', mod='STDASSERT.DLL', base=0x10000000, size=311296 ); ==> Result = 0x10000000 sSymLoadModule global_SymProcess = 0x7fffffff, 0, img='C:\WINDOWS\DESKTOP\ASSERT_CODE\TEST_ASSERT\DEBUG\TEST_ASSERT.EXE', mod='TEST_ASSERT.EXE', base=0x00400000, size=180224 ); ==> Result = 0x00400000 sSymLoadModule global_SymProcess = 0x7fffffff, 0, img='C:\WINDOWS\SYSTEM\KERNEL32.DLL', mod='KERNEL32.DLL', base=0xbff70000, size=471040 ); ==> Result = 0xbff70000 . . . LEAVE void enumAndLoadModuleSymbols( HANDLE hProcess = 0x7fffffff, DWORD pid = 0xfffcfd73 ); (Back in ExceptionHandler::DumpCrash()...) StackWalk ( ..., global_SymProcess = 0x7fffffff, hThread = 0xfffffffe, {sfStackFrame.AddrPC.Offset = 0x100042b3}, ...); ==> Result = 1 SymGetSymFromAddr global_SymProcess = 0x7fffffff, ui32_Address = 0x100042b3, &(dwSymOffset = 0x00000000), (pSymbol->Name = '') ); ==> Result = 0x00000001 ERROR: "Attempt to access invalid address" StackWalk ( ..., global_SymProcess = 0x7fffffff, hThread = 0xfffffffe, {sfStackFrame.AddrPC.Offset = 0x004012c0}, ...); ==> Result = 1 SymGetSymFromAddr global_SymProcess = 0x7fffffff, ui32_Address = 0x004012c0, &(dwSymOffset = 0x00000000), (pSymbol->Name = '') ); ==> Result = 0x00000001 ERROR: "Attempt to access invalid address" StackWalk ( ..., global_SymProcess = 0x7fffffff, hThread = 0xfffffffe, {sfStackFrame.AddrPC.Offset = 0x0040139e}, ...); ==> Result = 1 SymGetSymFromAddr global_SymProcess = 0x7fffffff, ui32_Address = 0x0040139e, &(dwSymOffset = 0x00000000), (pSymbol->Name = '') ); ==> Result = 0x00000001 ERROR: "Attempt to access invalid address" StackWalk ( ..., global_SymProcess = 0x7fffffff, hThread = 0xfffffffe, {sfStackFrame.AddrPC.Offset = 0x004013fd}, ...); ==> Result = 1 SymGetSymFromAddr global_SymProcess = 0x7fffffff, ui32_Address = 0x004013fd, &(dwSymOffset = 0x00000000), (pSymbol->Name = '') ); ==> Result = 0x00000001 ERROR: "Attempt to access invalid address" StackWalk ( ..., global_SymProcess = 0x7fffffff, hThread = 0xfffffffe, {sfStackFrame.AddrPC.Offset = 0x0040144a}, ...); ==> Result = 1 SymGetSymFromAddr global_SymProcess = 0x7fffffff, ui32_Address = 0x0040144a, &(dwSymOffset = 0x00000000), (pSymbol->Name = '') ); ==> Result = 0x00000001 ERROR: "Attempt to access invalid address" StackWalk ( ..., global_SymProcess = 0x7fffffff, hThread = 0xfffffffe, {sfStackFrame.AddrPC.Offset = 0x004020c9}, ...); ==> Result = 1 SymGetSymFromAddr global_SymProcess = 0x7fffffff, ui32_Address = 0x004020c9, &(dwSymOffset = 0x00000000), (pSymbol->Name = '') ); ==> Result = 0x00000001 ERROR: "Attempt to access invalid address" StackWalk ( ..., global_SymProcess = 0x7fffffff, hThread = 0xfffffffe, {sfStackFrame.AddrPC.Offset = 0xbff8b537}, ...); ==> Result = 1 SymGetSymFromAddr global_SymProcess = 0x7fffffff, ui32_Address = 0xbff8b537, &(dwSymOffset = 0x00000000), (pSymbol->Name = '') ); ==> Result = 0x00000001 ERROR: "Attempt to access invalid address" Closing Comments: ----------------- The stack walking looks fine! The addresses fall within the various *.DLL files. I'm sure I could convert the addresses to functions by hand; i.e., I am confident that the addresses are valid. I initiatialized the structure size field in the symbol structure (which wasn't done in the original version of the code) for SymGetSymFromAddr(). The process handle is the same as that used to initialize the symbol handler -- and if I try using a different handle, the function reports (via GetLastError()) "invalid handle". What could this be?! What is the "Attempt to access invalid address" reported by SymGetSymFromAddr() (via GetLastError())? I also tried using the exact address of an existing symbol in the SymGetSymFromAddr(), just as a sanity check... But there was no sanity! It also resulted in the "Attempt to access invalid address" error. All of this is under Windows 98, using Visual C++ 6.0 Professional, with Service Pack 5. I never explicitly installed a different version of "imagehlp.{dll,lib,h}" -- although VC++ 6.0 SP5 may have overwritten the version that shipped with VC++ 6.0. I'd step in to SymGetSymFromAddr()...IF I KNEW HOW!!! ;-) --- Colin |