addr2line for windows

While debugging os or application crash bug on windows ce (the tool winaddr2line isn't particularly used for windows CE application, it can be used for normal windows application too.) platform, developers may not always have the luxury to debug step by step within a IDE. Most of time, the only information available to us is the output on serial port. (It's already very fortunate if we can see serial port output every time a crash happens.) What we get is something like:
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(fff.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.
  1. In which module did the crash happen
  2. What's the address can we use to query
For question 1, the module name is already available in the log. In our example, it's test.exe. For question 2, we can see the PC register's value is 0x00011048. So, we run "winaddr2line.exe -e test.exe 11048 -a -p -s -f" command, and get this: "0x00011048: foo::crash at test.cpp:8". Now we open test.cpp and check what's around line 8, the root cause is very obvious.

 1
 2 class foo
 3 {
 4     public:
 5         void crash()
 6         {
 7             int *a = NULL;
 8             int b = *a;
         }
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

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
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
Qemu 1.0.1 Windows QEMU emulator version 1.0.1, Copyright (c) 2003-2008 Fabrice Bellard usage: qemu [options] [disk_image] 'disk_image' is a raw hard disk image for IDE hard disk 0 Standard options: -h or -help display this help and exit -version display version information and exit -machine [type=]name[,prop[=value][,...]] selects emulated machine (-machine ? for list) property accel=accel1[:accel2[:...]] selects accelerator supported accelerators are kvm, xen, tcg (default: tcg) -cpu cpu select CPU (-cpu ? for list) -smp n[,maxcpus=cpus][,cores=cores][,threads=threads][,sockets=sockets] set the number of CPUs to 'n' [default=1] maxcpus= maximum number of total cpus, including offline CPUs for hotplug, etc cores= number of CPU cores on one socket threads= number of threads on one CPU core sockets= number of discrete sockets in the system -numa node[,mem=size][,cpus=cpu[-cpu]][,nodeid=node] -fda/-fdb file use 'file' as floppy disk 0/1 image -hda/-hdb file use 'file' as IDE hard disk 0/1 image -hdc/-hdd file use 'file' as IDE hard disk 2/3 image -cdrom file use 'file' as IDE cdrom image (cdrom is ide1 master) -drive [file=file][,if=type][,bus=n][,unit=m][,media=d][,index=i] [,cyls=c,heads=h,secs=s[,trans=t]][,snapshot=on|off] [,cache=writethrough|writeback|none|directsync|unsafe][,format=f] [,serial=s][,addr=A][,id=name][,aio=threads|native] [,readonly=on|off] use 'file' as a drive image -set group.id.arg=value set parameter for item of type i.e. -set drive.$id.file=/path/to/image -global driver.property=value set a global default for a driver property -mtdblock file use 'file' as on-board Flash memory image -sd file use 'file' as SecureDigital card image -pflash file use 'file'

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值