上调试器
利用~*e ? @$tid;!gle
命令,去显示进程中每个线程的TID和LastError值。其中~*
查看所有线程,e
选项是支持多条命令,不然只是显示最后一条。@$tid
显示tid,!gle
:显示LastError。
LastErrorValue,最后一次错误码,是一个很小的数,LastStatusValue,最后一次系统状态码,是一个很大的数。一般的,调用系统服务失败,会把状态码传递给RtlNtStatusToError函数,在函数内部修改LastStatusValue,然后将LastStatusValue转化为LastErrorValue。
细看14d8线程
在windbg,切换线程使用~ 线程序号 s。如果需要使用TID切换线程,可以使用~~ TID s
。
细看现场
对于某些.NET托管代码,windbg由于没有私有符号,所以在栈回溯的时候没有办法显示名称,使用SOS扩展模块可以解析托管代码。
使用.loadby sos mscorwks
加载模块,使用!clrstack
回溯栈,发现WinIoError函数,说明出现异常,产生异常的是该函数的下面一个函数。
使用!thread
命令查看线程信息,可以发现存在一次异常信息。异常名称的后面显示的是异常对象的地址。利用!do [异常对象地址]
可以查看异常的详细信息。或者使用!Printexception
打印所有异常。
追本溯源
判断某个函数的父函数,可以利用函数的返回地址是否在父函数内部来判断。