📄 unwinder.cpp
字号:
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//
//
// This source code is licensed under Microsoft Shared Source License
// Version 1.0 for Windows CE.
// For a copy of the license visit http://go.microsoft.com/fwlink/?LinkId=3223.
//
/*++
Module Name:
unwinder.cpp
Module Description:
Stack unwinder
--*/
#include "osaxs_p.h"
ULONG GetCallStack(HANDLE hThrd, ULONG dwMaxFrames, LPVOID lpFrames, DWORD dwFlags, DWORD dwSkip)
{
DWORD dwFrames;
PTHREAD pth;
CONTEXT ctx;
if (!pfnDoThreadGetContext || !pfnNKGetThreadCallStack)
{
DEBUGGERMSG(OXZONE_ALERT,(L" Unwinder!GetCallStack: pfnDoThreadGetContext or pfnNKGetThreadCallStack is NULL\r\n"));
dwFrames = 0;
goto Exit;
}
pth = HandleToThread (hThrd);
if (!pth)
{
DEBUGGERMSG(OXZONE_ALERT,(L" Unwinder!GetCallStack: Invalid thread handle, hThrd=0x%08X\r\n", hThrd));
dwFrames = 0;
goto Exit;
}
if (pth == pCurThread)
{
// If this is the current thread we need to start unwinding from the point of
// the exception, otherwise we get the HDSTUB + OSAXS frames included
ctx = *g_pContextException;
}
else
{
// For other threads, get the threads context
ctx.ContextFlags = CONTEXT_FULL;
if (!pfnDoThreadGetContext(hThrd, &ctx))
{
DEBUGGERMSG(OXZONE_ALERT, (L" Unwinder!GetCallStack: DoThreadGetContext failed, hThrd=0x%08X, Error=%u\r\n",
hThrd, pfnGetLastError()));
dwFrames = 0;
goto Exit;
}
}
dwFrames = pfnNKGetThreadCallStack(pth, dwMaxFrames, lpFrames, dwFlags, dwSkip, &ctx);
Exit:
return dwFrames;
}
#ifdef _TEST
#define MAX_NUM_FRAMES 10
VOID RunCallStackTest()
{
DEBUGGERMSG (1, (TEXT("+++RunCallStackTest: \r\n")));
HANDLE hThread = GetCurrentThread();
CallSnapshotEx callstack[MAX_NUM_FRAMES] = {0};
GetCallStack(hThread, MAX_NUM_FRAMES, (LPVOID)callstack, 2, 0, NULL);
for (int i=0; i < MAX_NUM_FRAMES; i++)
{
DEBUGGERMSG(1, (TEXT("0x%.08x - "), callstack[i].dwReturnAddr));
}
DEBUGGERMSG (1, (TEXT("\r\n---RunCallStackTest: ")));
}
#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -