原理不多说了,我们知道,GetThreadContext只能取得被挂起线程的上下文,所以我这里使用内嵌汇编得到当前地址eip和当前函数栈指针ebp
由于没有使用Debug Help API,当然也不想自己分析pdb文件,打印信息可以和map文件和cond文件对照使用,还是比较方便的
其实可以从teb中得到堆栈位置信息来确定最外层调用栈,这里偷懒了,但是不影响这段代码的实用性,呵呵。
使用这段代码跟踪的程序,最好将编译选项中的优化去掉,原因大家都知道的
void PrintStackTrace()
{
DWORD dwAddr = 0;
DWORD dwChildEbp = 0;
_asm call $+5;
_asm pop eax;
_asm mov dwAddr,eax;
_asm mov dwChildEbp,ebp;
DWORD dwRetAddr = *(DWORD*)(dwChildEbp+4);
CString strMsg = "Addr\t\tChildEbp\t\tRetAddr\r\n"
"===============================\r\n";
try
{
while (TRUE)//dwRetAddr != 0)
{
dwAddr = dwRetAddr;
dwChildEbp = *(DWORD*)dwChildEbp;
dwRetAddr = *(DWORD*)(dwChildEbp+4);
CString strTemp;
strTemp.Format("0x%08X\t0x%08X\t0x%08X\r\n",dwAddr,dwChildEbp,dwRetAddr);
strMsg += strTemp;
}
}
catch (...)
{
printf("%s",(LPCTSTR)strMsg);
}
}
- 标 题:放一段可以随处打印函数调用栈的代码
- 作 者:xxxDebug
- 时 间:2010-04-01 16:46:09
- 链 接:http://bbs.pediy.com/showthread.php?t=110024