如何读取调用堆栈?

A. *_*ray 2 winapi callstack native memory-address visual-c++

我们在Windows 2003服务器上通过COM +运行本机C++应用程序.我最近从事件查看器中注意到它抛出异常,特别是C0000005异常,根据http://blogs.msdn.com/calvin_hsia/archive/2004/06/30/170344.aspx表示该过程试图写入不在其地址空间内的内存,即访问冲突.

事件查看器中的条目提供了一个调用堆栈:

LibFmwk!UTIL_GetDateFromLogByDayDirectory(char const*,class utilCDate&)+ 0xa26c LibFmwk!UTIL_GetDateFromLogByDayDirectory(char const*,class utilCDate&)+ 0x8af4 LibFmwk!UTIL_GetDateFromLogByDayDirectory(char const*,class utilCDate&)+ 0x13a1 LibFmwk!utilCLogController :: GetFLFInfoLevel(void )const + 0x1070 LibFmwk!utilCLogController :: GetFLFInfoLevel(void)const + 0x186

现在,我明白它给我的方法名称去看看,但我感觉每行末尾的地址(例如+ 0xa26c)试图指向我在该方法中的特定行或指令.

所以我的问题是:

  1. 有谁知道如何使用这个地址或调用堆栈中的任何其他信息来确定代码中的哪一行掉进去?
  2. 有没有我可以阅读的资源,以便更好地理解调用栈,
  3. 是否有任何免费软件/开源工具可以帮助分析调用堆栈,可能是通过附加到调试符号文件和/或二进制文件?

编辑:根据要求,这是似乎导致问题的方法:

BOOL UTIL_GetDateFromLogByDayDirectory(LPCSTR pszDir, utilCDate& oDate)
{
BOOL bRet = FALSE;

if ((pszDir[0] == '%') &&
    ::isdigit(pszDir[1]) && ::isdigit(pszDir[2]) &&
    ::isdigit(pszDir[3]) && ::isdigit(pszDir[4]) &&
    ::isdigit(pszDir[5]) && ::isdigit(pszDir[6]) &&
    ::isdigit(pszDir[7]) && ::isdigit(pszDir[8]) &&
    !pszDir[9])
{
    char acCopy[9];
    ::memcpy(acCopy, pszDir + 1, 8);
    acCopy[8] = '\0';

    int iDay = ::atoi(&acCopy[6]);
    acCopy[6] = '\0';
    int iMonth = ::atoi(&acCopy[4]);
    acCopy[4] = '\0';
    int iYear = ::atoi(&acCopy[0]);

    oDate.Set(iDay, iMonth, iYear);

    bRet = TRUE;
}

return (bRet);
Run Code Online (Sandbox Code Playgroud)

}

这是10年前由我们公司的一位成员编写的代码,该代码早已消失,因此我不认为确切知道这是做什么但我知道它涉及从'今天重命名日志目录的过程'到特定日期,例如%20090329.运算符的数组索引,memcpy和地址确实使它看起来很可疑.

我们似乎遇到的另一个问题是,这只发生在生产系统上,我们从来没有能够在我们的测试系统或开发系统上重现它,这将允许我们附加调试器.

非常感激!安迪

小智 5

其他人在这些线之间说过这个,但没有明确说明.看着:

LibFmwk!UTIL_GetDateFromLogByDayDirectory(char const *,class utilCDate &) + 0xa26c
Run Code Online (Sandbox Code Playgroud)

0xa26c偏移是巨大的,超过了函数的结束.调试器显然没有LibFmwk的正确符号,所以它依赖于DLL导出并显示相对于它能找到的最接近的一个的偏移量.

所以,是的,获得适当的符号然后它应该是轻而易举的.UTIL_GetDateFromLogByDayDirectory在这里没有错.