@@ -255,7 +255,7 @@ static void MyStrCpy(char* szDest, size_t nMaxDestSize, const char* szSrc)
255
255
class StackWalkerInternal
256
256
{
257
257
public:
258
- StackWalkerInternal (StackWalker* parent, HANDLE hProcess)
258
+ StackWalkerInternal (StackWalker* parent, HANDLE hProcess, PCONTEXT ctx )
259
259
{
260
260
m_parent = parent;
261
261
m_hDbhHelp = NULL ;
@@ -273,6 +273,9 @@ class StackWalkerInternal
273
273
pSW = NULL ;
274
274
pUDSN = NULL ;
275
275
pSGSP = NULL ;
276
+ m_ctx.ContextFlags = 0 ;
277
+ if (ctx != NULL )
278
+ m_ctx = *ctx;
276
279
}
277
280
278
281
~StackWalkerInternal ()
@@ -411,6 +414,7 @@ class StackWalkerInternal
411
414
412
415
StackWalker* m_parent;
413
416
417
+ CONTEXT m_ctx;
414
418
HMODULE m_hDbhHelp;
415
419
HANDLE m_hProcess;
416
420
@@ -871,8 +875,36 @@ class StackWalkerInternal
871
875
};
872
876
873
877
// #############################################################
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 ()
875
887
{
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 ;
876
908
this ->m_options = options;
877
909
this ->m_modulesLoaded = FALSE ;
878
910
this ->m_szSymPath = NULL ;
@@ -885,18 +917,23 @@ bool StackWalker::Init(int options, LPCSTR szSymPath, DWORD dwProcessId, HANDLE
885
917
if (!buf)
886
918
return false ;
887
919
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
889
921
return true ;
890
922
}
891
923
892
924
StackWalker::StackWalker (DWORD dwProcessId, HANDLE hProcess)
893
925
{
894
- Init (OptionsAll, NULL , dwProcessId, hProcess);
926
+ Init (NonExcept, OptionsAll, NULL , dwProcessId, hProcess);
895
927
}
896
928
897
929
StackWalker::StackWalker (int options, LPCSTR szSymPath, DWORD dwProcessId, HANDLE hProcess)
898
930
{
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 );
900
937
}
901
938
902
939
StackWalker::~StackWalker ()
@@ -1092,7 +1129,10 @@ BOOL StackWalker::ShowCallstack(HANDLE hThread,
1092
1129
if (GetThreadId (hThread) == GetCurrentThreadId ())
1093
1130
#endif
1094
1131
{
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);
1096
1136
}
1097
1137
else
1098
1138
{
0 commit comments