首页
社区
课程
招聘
[求助]绝望了,Release版crash后到底能不能得到完整的调用栈?
发表于: 2007-11-21 15:55 7295

[求助]绝望了,Release版crash后到底能不能得到完整的调用栈?

2007-11-21 15:55
7295
代码里通过Stackwalk64来获取调用栈,可是debug版工作正常,到release版就不对了。本来以为是写得不够健壮,所以从网上找了一个别人写好的东西来用,结果发现它给出的demo在release情况下也不能工作正常。
http://www.codeproject.com/threads/StackWalker.asp

后来又看到说通过MiniDumpWriteDump写dump文件,然后用WinDbg来读取可以分析出调用栈,结果还是Debug版输出的dump文件能够分析出完整的调用栈,release版输出的dump只能得到不完整的调用栈

各位大虾,Release版到底能不能获取完整的调用栈呢?

-------------------------------------------
我的系统是XP-SP2,编译器是VC2003 version 7.1.3088

[招生]科锐逆向工程师培训(2024年11月15日实地,远程教学同时开班, 第51期)

收藏
免费 0
支持
分享
最新回复 (6)
雪    币: 200
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
2
这是通过MiniDumpWriteDump写dump文件的demo代码:

#include <stdio.h>
#include <time.h>
#include <windows.h>
#include <DbgHelp.h>

#pragma comment(lib, "DbgHelp.lib")

LONG WINAPI TopLevelFilter( struct _EXCEPTION_POINTERS *pExceptionInfo )
{
    LONG ret = EXCEPTION_CONTINUE_SEARCH;

    time_t  nowtime;
    time(&nowtime);
    struct tm *pTime = localtime(&nowtime);
    char szFile[128] = {0};
    sprintf(szFile, "%4d.%02d.%02d_%02d.%02d.%02d.dmp", pTime->tm_year+1900, pTime->tm_mon+1, pTime->tm_mday, pTime->tm_hour, pTime->tm_min, pTime->tm_sec);

    HANDLE hFile = ::CreateFile(szFile, GENERIC_WRITE, FILE_SHARE_WRITE, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);

    if (hFile != INVALID_HANDLE_VALUE)
    {
        MINIDUMP_EXCEPTION_INFORMATION ExInfo;

        ExInfo.ThreadId = ::GetCurrentThreadId();
        ExInfo.ExceptionPointers = pExceptionInfo;
        ExInfo.ClientPointers = NULL;

        // write the dump
        BOOL bOK = MiniDumpWriteDump( GetCurrentProcess(), GetCurrentProcessId(), hFile, MiniDumpNormal, &ExInfo, NULL, NULL );
        ret = EXCEPTION_EXECUTE_HANDLER;
        ::CloseHandle(hFile);
    }
    return ret;
}

void ExpTest5() { char *p = NULL; p[0] = 0; }
void ExpTest4() { ExpTest5(); }
void ExpTest3() { ExpTest4(); }
void ExpTest2() { ExpTest3(); }
void ExpTest1() { ExpTest2(); }
void TestExceptionWalking() { ExpTest1(); }

int main()
{
    ::SetUnhandledExceptionFilter(TopLevelFilter);

    TestExceptionWalking();
    return 0;
}
2007-11-21 15:57
0
雪    币: 1852
活跃值: (504)
能力值: (RANK:1010 )
在线值:
发帖
回帖
粉丝
3
[1] 出错的时候先不要关闭消息,绑定调试器就可有查看调用堆栈
[2] 有种方法是利用MAP文件,我没用过
编译的时候选择生成MAP文件,在崩溃的时候就借助MAP来分析
2007-11-21 16:09
0
雪    币: 200
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
4
添加这样的功能是为了在用户那里Crash时能得到有用的信息,所以不希望通过绑定调试器来获取调用栈
MAP文件应该是帮助获取函数名之类的具体信息的吧,如果连调用栈信息都没有的话,有map文件好像也没用吧

[QUOTE=北极星2003;383583][1] 出错的时候先不要关闭消息,绑定调试器就可有查看调用堆栈
[2] 有种方法是利用MAP文件,我没用过
编译的时候选择生成MAP文件,在崩溃的时候就借助MAP来分析[/QUOTE]
2007-11-21 16:17
0
雪    币: 1852
活跃值: (504)
能力值: (RANK:1010 )
在线值:
发帖
回帖
粉丝
5
没做过,不过查了MSDN,都有现成的接口。就是你用的DbgHelp。
2005的MSDN
BOOL SymFromAddr(
  HANDLE hProcess,
  DWORD64 Address,
  PDWORD64 Displacement,
  PSYMBOL_INFO Symbol
);
这个函数还有个实例Retrieving Symbol Information by Address
2007-11-21 16:38
0
雪    币: 200
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
6
这个函数是根据地址获取symbol 的,可以配合StackWalk64来获取详细的调用栈,我现在连调用栈的地址(只是Release版,Debug版没有问题)都获取不全

2007-11-21 16:48
0
雪    币: 200
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
7
晕死,我知道原因了

是因为Release版把短小的测试函数优化为inline的了,所以调用栈显示不完全。也就是说这两种方式都是可以工作正常的,无论在Debug版和Release版。
2007-11-21 18:15
0
游客
登录 | 注册 方可回帖
返回
//