Skip to content

Commit bf32dbc

Browse files
committed
Added type of exception handling and use of PTD to get the current exception context
Recommended MSVC2005 or newer.
1 parent acaf658 commit bf32dbc

File tree

2 files changed

+57
-7
lines changed

2 files changed

+57
-7
lines changed

Main/StackWalker/StackWalker.cpp

+46-6
Original file line numberDiff line numberDiff line change
@@ -255,7 +255,7 @@ static void MyStrCpy(char* szDest, size_t nMaxDestSize, const char* szSrc)
255255
class StackWalkerInternal
256256
{
257257
public:
258-
StackWalkerInternal(StackWalker* parent, HANDLE hProcess)
258+
StackWalkerInternal(StackWalker* parent, HANDLE hProcess, PCONTEXT ctx)
259259
{
260260
m_parent = parent;
261261
m_hDbhHelp = NULL;
@@ -273,6 +273,9 @@ class StackWalkerInternal
273273
pSW = NULL;
274274
pUDSN = NULL;
275275
pSGSP = NULL;
276+
m_ctx.ContextFlags = 0;
277+
if (ctx != NULL)
278+
m_ctx = *ctx;
276279
}
277280

278281
~StackWalkerInternal()
@@ -411,6 +414,7 @@ class StackWalkerInternal
411414

412415
StackWalker* m_parent;
413416

417+
CONTEXT m_ctx;
414418
HMODULE m_hDbhHelp;
415419
HANDLE m_hProcess;
416420

@@ -871,8 +875,36 @@ class StackWalkerInternal
871875
};
872876

873877
// #############################################################
874-
bool StackWalker::Init(int options, LPCSTR szSymPath, DWORD dwProcessId, HANDLE hProcess)
878+
879+
#if defined(_MSC_VER) && _MSC_VER >= 1400 && _MSC_VER < 1900
880+
extern "C" void* __cdecl _getptd();
881+
#endif
882+
#if defined(_MSC_VER) && _MSC_VER >= 1900
883+
extern "C" void** __cdecl __current_exception_context();
884+
#endif
885+
886+
static PCONTEXT get_current_exception_context()
875887
{
888+
PCONTEXT * pctx = NULL;
889+
#if defined(_MSC_VER) && _MSC_VER >= 1400 && _MSC_VER < 1900
890+
LPSTR ptd = (LPSTR)_getptd();
891+
if (ptd)
892+
pctx = (PCONTEXT *)(ptd + (sizeof(void*) == 4 ? 0x8C : 0xF8));
893+
#endif
894+
#if defined(_MSC_VER) && _MSC_VER >= 1900
895+
pctx = (PCONTEXT *)__current_exception_context();
896+
#endif
897+
return pctx ? *pctx : NULL;
898+
}
899+
900+
bool StackWalker::Init(ExceptType extype, int options, LPCSTR szSymPath, DWORD dwProcessId,
901+
HANDLE hProcess, PEXCEPTION_POINTERS exp)
902+
{
903+
PCONTEXT ctx = NULL;
904+
if (extype == AfterCatch)
905+
ctx = get_current_exception_context();
906+
if (extype == AfterExcept && exp)
907+
ctx = exp->ContextRecord;
876908
this->m_options = options;
877909
this->m_modulesLoaded = FALSE;
878910
this->m_szSymPath = NULL;
@@ -885,18 +917,23 @@ bool StackWalker::Init(int options, LPCSTR szSymPath, DWORD dwProcessId, HANDLE
885917
if (!buf)
886918
return false;
887919
memset(buf, 0, sizeof(StackWalkerInternal));
888-
this->m_sw = new(buf) StackWalkerInternal(this, this->m_hProcess); // placement new
920+
this->m_sw = new(buf) StackWalkerInternal(this, this->m_hProcess, ctx); // placement new
889921
return true;
890922
}
891923

892924
StackWalker::StackWalker(DWORD dwProcessId, HANDLE hProcess)
893925
{
894-
Init(OptionsAll, NULL, dwProcessId, hProcess);
926+
Init(NonExcept, OptionsAll, NULL, dwProcessId, hProcess);
895927
}
896928

897929
StackWalker::StackWalker(int options, LPCSTR szSymPath, DWORD dwProcessId, HANDLE hProcess)
898930
{
899-
Init(options, szSymPath, dwProcessId, hProcess);
931+
Init(NonExcept, options, szSymPath, dwProcessId, hProcess);
932+
}
933+
934+
StackWalker::StackWalker(ExceptType extype, int options, PEXCEPTION_POINTERS exp)
935+
{
936+
Init(extype, options, NULL, GetCurrentProcessId(), GetCurrentProcess(), exp);
900937
}
901938

902939
StackWalker::~StackWalker()
@@ -1092,7 +1129,10 @@ BOOL StackWalker::ShowCallstack(HANDLE hThread,
10921129
if (GetThreadId(hThread) == GetCurrentThreadId())
10931130
#endif
10941131
{
1095-
GET_CURRENT_CONTEXT_STACKWALKER_CODEPLEX(c, USED_CONTEXT_FLAGS);
1132+
if (m_sw->m_ctx.ContextFlags != 0)
1133+
c = m_sw->m_ctx; // context taken at Init
1134+
else
1135+
GET_CURRENT_CONTEXT_STACKWALKER_CODEPLEX(c, USED_CONTEXT_FLAGS);
10961136
}
10971137
else
10981138
{

Main/StackWalker/StackWalker.h

+11-1
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,13 @@ class StackWalkerInternal; // forward
5757
class StackWalker
5858
{
5959
public:
60+
typedef enum ExceptType
61+
{
62+
NonExcept = 0, // RtlCaptureContext
63+
AfterExcept = 1,
64+
AfterCatch = 2, // get_current_exception_context
65+
} ExceptType;
66+
6067
typedef enum StackWalkOptions
6168
{
6269
// No addition info will be retrieved
@@ -91,6 +98,8 @@ class StackWalker
9198
OptionsAll = 0x3F
9299
} StackWalkOptions;
93100

101+
StackWalker(ExceptType extype, int options, PEXCEPTION_POINTERS exp = NULL);
102+
94103
StackWalker(int options = OptionsAll, // 'int' is by design, to combine the enum-flags
95104
LPCSTR szSymPath = NULL,
96105
DWORD dwProcessId = GetCurrentProcessId(),
@@ -105,7 +114,8 @@ class StackWalker
105114
bool SetTargetProcess(DWORD dwProcessId, HANDLE hProcess);
106115

107116
private:
108-
bool Init(int options, LPCSTR szSymPath, DWORD dwProcessId, HANDLE hProcess);
117+
bool Init(ExceptType extype, int options, LPCSTR szSymPath, DWORD dwProcessId,
118+
HANDLE hProcess, PEXCEPTION_POINTERS exp = NULL);
109119

110120
public:
111121
typedef BOOL(__stdcall* PReadProcessMemoryRoutine)(

0 commit comments

Comments
 (0)