cophi
asked on
Debugging finding address
Let's say I have some program that I'm running and I get an exception while running in debug mode of Visual Studio .Net. I can see from the call stack that the origin of my problem starts at 'SomeProgram.dll!100042be( )' How do I find where that address is in my code? The SomeProgram.dll is a program that I have written, so I'm trying to find what line and file 100042be is. How do I do that?
ntdll.dll!_DbgBreakPoint@0 ()
vrfcore.dll!00363537()
ntdll.dll!_vDbgPrintExWith Prefix@20( ) + 0x5a
ntdll.dll!ExecuteHandler@2 0() + 0x24
ntdll.dll!_KiUserException Dispatcher @8() + 0xe
ntdll.dll!_RtlDosApplyFile IsolationR edirection _Ustr@36() + 0x25d
vfbasics.dll!003911dd()
kernel32.dll!_BasepMapModu leHandle@8 () + 0x7a4
SomeProgram.dll!100042be()
ntdll.dll!_DbgBreakPoint@0
vrfcore.dll!00363537()
ntdll.dll!_vDbgPrintExWith
ntdll.dll!ExecuteHandler@2
ntdll.dll!_KiUserException
ntdll.dll!_RtlDosApplyFile
vfbasics.dll!003911dd()
kernel32.dll!_BasepMapModu
SomeProgram.dll!100042be()
ASKER CERTIFIED SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
>>I can see from the call stack that the origin of my problem starts at 'SomeProgram.dll!100042be( )' How do I >>find where that address is in my code?
Set the compiler to create a map file for that module. When you have both the map file and the faulting address (here: 'SomeProgram.dll!100042be( )'), you can find the function where the fault occurred the following way: Consider e.g.
#include <windows.h>
#include <stddef.h>
#include <stdio.h>
LONG
WINAPI
ExceptionHandler(LPEXCEPTI ON_POINTER S pe) {
char acModule[MAX_PATH];
MEMORY_BASIC_INFORMATION mbi;
HMODULE hMod;
VirtualQuery (pe->ExceptionRecord->Exce ptionAddre ss,&mbi,si zeof(mbi)) ;
ptrdiff_t RVA = (char*)pe->ExceptionRecord ->Exceptio nAddress - (char*)mbi.AllocationBase;
hMod = (HMODULE) mbi.AllocationBase;
GetModuleFileName(hMod,acM odule,size of (acModule));
printf( "Detected Exception in %s at RVA 0x%08X\n", acModule, RVA);
return EXCEPTION_EXECUTE_HANDLER;
}
void FaultingFunction () {
LONG* p = NULL;
*p = 42;
}
void main(){
SetUnhandledExceptionFilte r (ExceptionHandler);
FaultingFunction ();
}
(compiled with "cl rvaxcept.cpp /link /map")
which prints
Detected Exception in C:\tmp\cc\rvaxcept.exe at RVA 0x00001088
The map file is
rvaxcept
Timestamp is 44660958 (Sat May 13 18:29:12 2006)
Preferred load address is 00400000
Start Length Name Class
0001:00000000 00004938H .text CODE
[...]
Address Publics by Value Rva+Base Lib:Object
0001:00000000 _ExceptionHandler@4 00401000 f rvaxcept.obj
0001:0000007a _FaultingFunction 0040107a f rvaxcept.obj
0001:00000092 _main 00401092 f rvaxcept.obj
0001:000000a7 _printf 004010a7 f LIBC:printf.obj
0001:000000d8 _mainCRTStartup 004010d8 f LIBC:crt0.obj
0001:000001b7 __amsg_exit 004011b7 f LIBC:crt0.obj
[...]
You can see the 'Rva+Base' column, base is given as 'Preferred load address is 00400000'
Add that to the faulting module RVA of 0x00001088 and you get 0x00401088, then look that up in the above (i.e. the 'nearest symbol' and you can see that it is 'FaultingFunction'
0001:0000007a _FaultingFunction 0040107a f rvaxcept.obj
0001:00000092 _main 00401092 f rvaxcept.obj
The address is between main and FaultingFunction, which starts before 0x00401088, the next function is main and starts later.
Set the compiler to create a map file for that module. When you have both the map file and the faulting address (here: 'SomeProgram.dll!100042be(
#include <windows.h>
#include <stddef.h>
#include <stdio.h>
LONG
WINAPI
ExceptionHandler(LPEXCEPTI
char acModule[MAX_PATH];
MEMORY_BASIC_INFORMATION mbi;
HMODULE hMod;
VirtualQuery (pe->ExceptionRecord->Exce
ptrdiff_t RVA = (char*)pe->ExceptionRecord
hMod = (HMODULE) mbi.AllocationBase;
GetModuleFileName(hMod,acM
printf( "Detected Exception in %s at RVA 0x%08X\n", acModule, RVA);
return EXCEPTION_EXECUTE_HANDLER;
}
void FaultingFunction () {
LONG* p = NULL;
*p = 42;
}
void main(){
SetUnhandledExceptionFilte
FaultingFunction ();
}
(compiled with "cl rvaxcept.cpp /link /map")
which prints
Detected Exception in C:\tmp\cc\rvaxcept.exe at RVA 0x00001088
The map file is
rvaxcept
Timestamp is 44660958 (Sat May 13 18:29:12 2006)
Preferred load address is 00400000
Start Length Name Class
0001:00000000 00004938H .text CODE
[...]
Address Publics by Value Rva+Base Lib:Object
0001:00000000 _ExceptionHandler@4 00401000 f rvaxcept.obj
0001:0000007a _FaultingFunction 0040107a f rvaxcept.obj
0001:00000092 _main 00401092 f rvaxcept.obj
0001:000000a7 _printf 004010a7 f LIBC:printf.obj
0001:000000d8 _mainCRTStartup 004010d8 f LIBC:crt0.obj
0001:000001b7 __amsg_exit 004011b7 f LIBC:crt0.obj
[...]
You can see the 'Rva+Base' column, base is given as 'Preferred load address is 00400000'
Add that to the faulting module RVA of 0x00001088 and you get 0x00401088, then look that up in the above (i.e. the 'nearest symbol' and you can see that it is 'FaultingFunction'
0001:0000007a _FaultingFunction 0040107a f rvaxcept.obj
0001:00000092 _main 00401092 f rvaxcept.obj
The address is between main and FaultingFunction, which starts before 0x00401088, the next function is main and starts later.
http://msdn.microsoft.com/library/en-us/vccore/html/_core_.2f.Z7.2c_2f.Zd.2c_2f.Zi.asp?frame=true
Another option is to do a dump in the .dll (with dumpbin.exe), maybe you can check the relative address of each function and get a hint at what function it is.