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

时间:2015-07-26 13:37:26

标签: c++ windows debugging exception-handling

我正在学习Windows 7中“DbgHelp”提供的StackWalk API。我编写了一个使用StackWalk64的异常过滤器。目的是用功能名称和行​​号回溯最多50行。 “StackWalk64”遍历每个堆栈帧。从堆栈帧检索的地址(AddrPC)用于“SymGetSymFromAddr64”和“SymGetLineFromAddr64”以分别检索符号名称和行号。但是,虽然“SymGetSymFromAddr64”成功运行,但“SymGetLineFromAddr64”失败。返回的上一个错误是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;
}

2 个答案:

答案 0 :(得分:2)

pdwDisplacement参数不是可选的:

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

答案 1 :(得分:0)

我有同样的问题。我的符号在符号服务器上。解决方案是将symsrv.dll(来自Windows SDK)放在dbghelp.dll旁边,以便可以加载它。此后一切正常。实际上,解决方案是将dbghelp.dll和symsrv.dll与我的应用程序一起分发(以及dbgcore.dll和srcsrv.dll)。请参阅Visual Studio中的“模块”列表,以验证是否从期望的位置加载了symsrv.dll和dbghelp.dll。

更多信息在这里: