c++ - SymGetSymFromAddr64 有效,但 SymGetLineFromAddr64 失败,错误代码为 487

标签 c++ windows debugging exception-handling

我正在学习 Windows 7 中“DbgHelp”提供的 StackWalk API。我编写了一个使用 StackWalk64 的异常过滤器。目的是回溯最多 50 行函数名和行号。 “StackWalk64”遍历每个堆栈帧。从堆栈帧中检索到的地址 (AddrPC) 在“SymGetSymFromAddr64”和“SymGetLineFromAddr64”中分别用于检索符号名称和行号。但是,尽管“SymGetSymFromAddr64”成功运行,“SymGetLineFromAddr64”却失败了。返回的 Last Error 是 487。地址如何对前者成功而对后者不成功?

我错过了什么吗?有什么帮助吗?

LONG WINAPI TestStackWalker (EXCEPTION_POINTERS* lpFilter)
{
   STACKFRAME64 st;
   CONTEXT cc;
   HANDLE hProcess = ::GetCurrentProcess();
   HANDLE hThread = ::GetCurrentThread();

   vector<IMAGEHLP_SYMBOL64> vectSymbs(50);
   vector<IMAGEHLP_LINE64> vectLines(50);

   if (!SymInitialize(hProcess, NULL, TRUE))
   {
      cout << "Issue with SymInitialize ! " << ::GetLastError() << endl;
      return 1;
   } 

   cc = *(lpFilter->ContextRecord);

   printContext(cc);

   ::ZeroMemory(&st, sizeof(st));

   st.AddrStack.Mode = AddrModeFlat;
   st.AddrStack.Offset = cc.Esp;
   st.AddrFrame.Mode = AddrModeFlat;
   st.AddrFrame.Offset = cc.Ebp;
   st.AddrPC.Mode = AddrModeFlat;
   st.AddrPC.Offset = cc.Eip;

   for (int i = 0; i < 50; i++)
   {
      if (!::StackWalk64(IMAGE_FILE_MACHINE_I386,
         hProcess,
         hThread,
         &st,
         &cc,
         NULL,
         SymFunctionTableAccess64,
         SymGetModuleBase64,
         NULL))
      {
         cout <<  "Issue with StackWalkFailed: " << ::GetLastError () <<endl;
         return 1;
      }

      if (st.AddrReturn.Offset == st.AddrPC.Offset)
      {
         cout << "i think it's done!" << endl;
         break;
      }

      if (st.AddrPC.Offset != 0)
      {

         vectSymbs[i].SizeOfStruct = sizeof(IMAGEHLP_SYMBOL64);
         vectSymbs[i].MaxNameLength = 1024;
         if (!SymGetSymFromAddr64 (hProcess, st.AddrPC.Offset, 0, &vectSymbs[i]))
         {
            cout << "Issue with Getting Symbol From Address " << ::GetLastError() << endl;
            break;
         }

         SymSetOptions(SYMOPT_LOAD_LINES);

         vectLines[i].SizeOfStruct = sizeof(IMAGEHLP_LINE64);

         if (!SymGetLineFromAddr64 (hProcess, st.AddrPC.Offset, 0, &vectLines[i]))
         {
            cout << "Issue with Getting Line from Address " << ::GetLastError() << endl;
            break;
         }

         cout << vectSymbs[i].Name << " at " << vectLines[i].LineNumber <<endl;

      }

      if (st.AddrReturn.Offset ==  0)
      {
         cout << "seems finished " << endl;
         break;
      }
   }
   return 1;
}

最佳答案

pdwDisplacement 参数不是可选的:

     DWORD dis;
     if (!SymGetLineFromAddr64 (hProcess, st.AddrPC.Offset, &dis, &vectLines[i]))
     {
        cout << "Issue with Getting Line from Address " << ::GetLastError() << endl;
        break;
     }

关于c++ - SymGetSymFromAddr64 有效,但 SymGetLineFromAddr64 失败,错误代码为 487,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31637591/

相关文章:

即使添加到 PATH 后,Windows CMD 也无法识别 python

cocoa - Xcode调试: View value of NSNumber?

c++ - 在类中声明的 Const 和 Static,C++

c++ - 将派生类存储到 vector C++

c++ - 在 C 或 C++ 中的 3D 空间实现中从 3 个点构建圆

c - GTK 代码无法链接(win7-64bit、C、msys64)

c - Cygwin 的 GCC 与 Windows 上的 MSVC 编译器之间是否存在任何性能问题?

c - 查找 C 程序中的错误以反转字符串

c# - 调试在 visual studio 宏中引用的自定义 dll

c++ - 如何在 C++ 中声明 std::chrono::duration<double> 变量