Exception 'Data Abort' (4): Thread-Id=06890fba(pth=88eb8948), Proc-Id=06750f9e(pprc=88eb8828) 'test.exe', VM-active=06750f9e(pprc=88eb8828) 'test.exe'
PC=00011048(test.exe+0x00001048) RA=00011018(test.exe+0x00001018) SP=0002fb98, BVA=00000000
Unhandled exception c0000005:
Terminating thread 88eb8948
PC=00011048(test.exe+0x00001048) RA=00011018(test.exe+0x00001018) SP=0002fb98, BVA=00000000
Unhandled exception c0000005:
Terminating thread 88eb8948
Given the PC register value, we need to figure out on while line in our code did the application crash. winaddr2line makes it an easy task as long as we have the pdb symbol file for the application. It's a attempt to port addr2line to windows world.
Let's take the preceding log for example. In order to find out the line number of the code that incurs the crash, we need following information.
- In which module did the crash happen
- What's the address can we use to query
1
2 class foo
3 {
4 public:
5 void crash()
6 {
7 int *a = NULL;
8 int b = *a;
9 }
10 };
11
12 int main ( int argc, char *argv[] )
13 {
14 foo f;
15 f.crash();
16 return 0;
17 }
2 class foo
3 {
4 public:
5 void crash()
6 {
7 int *a = NULL;
8 int b = *a;
9 }
10 };
11
12 int main ( int argc, char *argv[] )
13 {
14 foo f;
15 f.crash();
16 return 0;
17 }
In order for the preceding command to work correctly, we must make sure the test.exe and its symbol file test.pdb is available in current directory of the shell that we run winaddr2line. If it's not the case, we should pass correct path to test.exe for -e argument and path to directory containing test.pdb for -y argument respectively.
In the example, we use PC register's value directly to query line number. But it's not always the case. Consider the crash log below:
Exception 'Raised Exception' (-1): Thread-Id=06891422(pth=88eb8948), Proc-Id=0675143e(pprc=88eb8828) 'test.exe', VM-active=0675143e(pprc=88eb8828) 'test.exe'
PC=4006d270(coredll.dll+0x0005d270) RA=80118a60(kernel.dll+0x00007a60) SP=0002fb8c, BVA=00000000
Unhandled exception c0000094:
Terminating thread 88eb8948
PC=4006d270(coredll.dll+0x0005d270) RA=80118a60(kernel.dll+0x00007a60) SP=0002fb8c, BVA=00000000
Unhandled exception c0000094:
Terminating thread 88eb8948
The crash occurred in coredll.dll module. We run command "winaddr2line.exe -e coredll.dll 4006d270 -a -p -s -f", but we can see it fails to find the line number. This is because we can't use the PC register's value directly here. The coredll.dll is loaded at 0x40010000 (0x4006d270-0x0005d270), which is different from its preferred ImageBase address (0x10000000, which can be examined with "dumpbin /headers coredll.dll" command). And winaddr2line can only make use of the ImageBase address contained statically in PE header of the binary. So, we must change the address to 0x1005d270 (0x10000000+0x0005d270). By using this address, we can see the crash occured at: d:\dublin2-1\private\winceos\coreos\core\dll\crtsupp.cpp:240
Source code for winaddr2line:
http://code.google.com/p/winaddr2line/
1 comment:
Hi,
this tools is just what I needed, thanks a lot!
I had to add fflush(stdout); at the ends of the "print" function in winaddr2line.cpp to make the interactive mode work when being used from another program.
Post a Comment