Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/154.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/windows/17.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/django/22.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 无法在Windows中获取调用堆栈_C++_Windows - Fatal编程技术网

C++ 无法在Windows中获取调用堆栈

C++ 无法在Windows中获取调用堆栈,c++,windows,C++,Windows,在以下代码的情况下,为什么会出现错误\u无效\u句柄错误?我做错了什么 #include <Windows.h> #include <DbgHelp.h> #include <cstddef> #include <cstring> #include <iostream> void print_call_stack() { HANDLE cur_process_handle = GetCurrentProcess(); HAN

在以下代码的情况下,为什么会出现错误\u无效\u句柄错误?我做错了什么

#include <Windows.h>
#include <DbgHelp.h>

#include <cstddef>
#include <cstring>
#include <iostream>

void print_call_stack()
{
  HANDLE cur_process_handle = GetCurrentProcess();
  HANDLE cur_thread_handle = GetCurrentThread();

  CONTEXT cur_thread_context;
  std::memset(&cur_thread_context, 0, sizeof(CONTEXT));
  cur_thread_context.ContextFlags = CONTEXT_FULL;
  if (!GetThreadContext(cur_thread_handle, &cur_thread_context))
  {
    std::cerr << "An error occurred while using function GetThreadContext. "
      << "Error code: " << GetLastError() << '\n';
    return;
  }

  STACKFRAME64 sf;
  std::memset(&sf, 0, sizeof(sf));
  sf.AddrPC.Mode         = AddrModeFlat;
  sf.AddrStack.Mode      = AddrModeFlat;
  sf.AddrFrame.Mode      = AddrModeFlat;
#ifdef _M_IX86  // Intel Only!
  sf.AddrPC.Offset       = cur_thread_context.Eip;
  sf.AddrStack.Offset    = cur_thread_context.Esp;
  sf.AddrFrame.Offset    = cur_thread_context.Ebp;
#endif
#ifdef _M_X64  // Intel Only!
  sf.AddrPC.Offset       = cur_thread_context.Rip;
  sf.AddrStack.Offset    = cur_thread_context.Rsp;
  sf.AddrFrame.Offset    = cur_thread_context.Rbp;
#endif
#ifdef _M_IA64 // Itanium
#pragma message("fix me")
  sf.AddrPC.Offset       = 0;
  sf.AddrStack.Offset    = 0;
  sf.AddrFrame.Offset    = 0;
#endif

#ifdef _M_IX86
  DWORD machine_type = IMAGE_FILE_MACHINE_I386;
#endif
#ifdef _M_X64
  DWORD machine_type = IMAGE_FILE_MACHINE_AMD64;
#endif
#ifdef _M_IA64
  DWORD machine_type = IMAGE_FILE_MACHINE_IA64;
#endif

  int count = 0;
  // According to MSDN, the sum of FramesToSkip and FramesToCapture
  // must be less than 63 in case of Windows Server 2003 and Windows XP,
  // so set it to 62
  void* trace[62];

  while (StackWalk64(
    machine_type
    , cur_process_handle
    , cur_thread_handle
    , &sf
    , &cur_thread_context
    , NULL
    , SymFunctionTableAccess64
    , SymGetModuleBase64
    , NULL
    ) == TRUE && count < sizeof(trace) / sizeof(*trace))
  {
    trace[count++] = reinterpret_cast<void*>(sf.AddrPC.Offset);
  }

  for (std::size_t i = 0; i < count; ++i)
  {
    const int kMaxNameLength = 256;
    DWORD_PTR frame = reinterpret_cast<DWORD_PTR>(trace[i]);

    ULONG64 buffer[
      (sizeof(SYMBOL_INFO) +
        kMaxNameLength * sizeof(wchar_t) +
        sizeof(ULONG64) - 1) /
        sizeof(ULONG64)];
      std::memset(buffer, 0, sizeof(buffer));

      // Initialize symbol information retrieval structures.
      DWORD64 sym_displacement = 0;
      PSYMBOL_INFO symbol = reinterpret_cast<PSYMBOL_INFO>(&buffer[0]);
      symbol->SizeOfStruct = sizeof(SYMBOL_INFO);
      symbol->MaxNameLen = kMaxNameLength - 1;
      BOOL has_symbol = SymFromAddr(
        cur_process_handle
        , frame
        , &sym_displacement
        , symbol
      );
      if (has_symbol == FALSE)
      {
        std::cerr << "An error occurred while using function SymFromAddr."
                  << " Error code: " << GetLastError() << '\n';
      }

      // Attempt to retrieve line number information.
      DWORD line_displacement = 0;
      IMAGEHLP_LINE64 line = {};
      line.SizeOfStruct = sizeof(IMAGEHLP_LINE64);
      BOOL has_line = SymGetLineFromAddr64(
        cur_process_handle
        , frame
        , &line_displacement
        , &line
      );
      if (has_line == FALSE)
      {
        std::cerr << "An error occurred while using function SymGetLineFromAddr64."
                  << " Error code: " << GetLastError() << '\n';
      }

      if (has_symbol == TRUE)
      {
        std::cout << symbol->Name << " [0x" << trace[i] << "+"
          << sym_displacement << "]";
      }
      else
      {
        std::cout << "(No symbol) [0x" << trace[i] << "]";
      }

      if (has_line == TRUE)
      {
        std::cout << " (" << line.FileName << ":" << line.LineNumber << ")";
      }

      std::cout << '\n';
  }
}

int main()
{
  print_call_stack();
}
#包括
#包括
#包括
#包括
#包括
无效打印\调用\堆栈()
{
HANDLE cur_process_HANDLE=GetCurrentProcess();
HANDLE cur_thread_HANDLE=GetCurrentThread();
上下文当前线程上下文;
std::memset(&cur_thread_context,0,sizeof(context));
cur_thread_context.ContextFlags=context_FULL;
if(!GetThreadContext(cur\u thread\u handle,&cur\u thread\u context))
{

std::cerr根据,您需要首先调用。

在代码的哪一行上会出现错误?@Mats peterson我在使用SymFromAddr和symgetlinefromdr64函数时会出现这些错误,并且您肯定有符号?在编程历史上,您得到的错误与出现错误的实际原因。假设您的进程句柄仍然与开始时得到的值相同,我不认为这是无效的。但我看到许多错误消息“稍微不正确”的示例。或者,可能您没有执行“最初传递给SymInitialize函数的进程句柄”?