-
Notifications
You must be signed in to change notification settings - Fork 182
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Incorrect stack trace info for C++ exceptions #41
Comments
Please make a PR.
Von: Oleg S. <notifications@github.com>
Gesendet: Donnerstag, 26. November 2020 12:42
An: JochenKalmbach/StackWalker <StackWalker@noreply.github.com>
Cc: Subscribed <subscribed@noreply.github.com>
Betreff: [JochenKalmbach/StackWalker] Incorrect stack trace info for C++ exceptions (Win64) (#41)
If C++ exceptions are used in the project, then to use __except it is necessary to build the project with the /EHa option!
Proof: https://docs.microsoft.com/en-us/cpp/cpp/structured-exception-handling-c-cpp?view=msvc-160
When using C++ exceptions, the StackWalker cannot get information about the last call in which the exception occurred.
Here is the code to demonstrate this bug:
#include "stackwalker.h"
#include <stdio.h>
#include <stdexcept>
#define THROW_CPP_EXCEPTION 1
#define CATCH_CPP_EXCEPTION 1
#define NOINLINE __declspec(noinline)
NOINLINE int bar(int * pi = nullptr)
{
#if THROW_CPP_EXCEPTION == 1
throw(std::exception("Bar error")); /* line 13 */
#else
*pi = 0xBADDEAD; /* line 15 */
#endif
return 0;
}
NOINLINE void foo()
{
int x = bar(nullptr); /* line 22 */
printf("bar = %d \n", x);
}
extern "C" void** __cdecl __current_exception_context();
NOINLINE void test()
{
try {
foo(); /* line 31 */
}
catch(...) {
#if CATCH_CPP_EXCEPTION == 1
PCONTEXT ctx = *(PCONTEXT *)__current_exception_context();
StackWalker sw(StackWalker::RetrieveVerbose);
sw.ShowCallstack(GetCurrentThread(), ctx);
#endif
throw;
}
}
LONG WINAPI ExpFilter(EXCEPTION_POINTERS * pExp, DWORD dwExpCode)
{
StackWalker sw(StackWalker::RetrieveVerbose);
sw.ShowCallstack(GetCurrentThread(), pExp->ContextRecord);
return EXCEPTION_EXECUTE_HANDLER;
}
int main()
{
…__try {
test(); /* line 53 */
}
__except( ExpFilter(GetExceptionInformation(), GetExceptionCode()) ) {
// nothing
}
return 0;
}
Compiler: MSVC2015 (x64 Release)
Options with which the test project was built: /MT /Zi /O2 /EHa
DebugLog for: THROW_CPP_EXCEPTION = 0, CATCH_CPP_EXCEPTION = 0
KERNELBASE: RaiseException
frame.cpp (1342): __CxxCallCatchBlock
ntdll: RtlRestoreContext
main.cpp (31): test
main.cpp (54): main
exe_common.inl (253): __scrt_common_main_seh
DebugLog for: THROW_CPP_EXCEPTION = 1, CATCH_CPP_EXCEPTION = 0
KERNELBASE: RaiseException
frame.cpp (1342): __CxxCallCatchBlock
ntdll: RtlRestoreContext
main.cpp (31): test
main.cpp (53): main
exe_common.inl (253): __scrt_common_main_seh
DebugLog for: THROW_CPP_EXCEPTION = 1, CATCH_CPP_EXCEPTION = 1
KERNELBASE: RaiseException
throw.cpp (136): _CxxThrowException
main.cpp (13): bar
main.cpp (22): foo
main.cpp (31): test
main.cpp (53): main
exe_common.inl (253): __scrt_common_main_seh
KERNELBASE: RaiseException
frame.cpp (1342): __CxxCallCatchBlock
ntdll: RtlRestoreContext
main.cpp (31): test
main.cpp (53): main
exe_common.inl (253): __scrt_common_main_seh
The last log shows how using the CATCH_CPP_EXCEPTION = 1 option allows you to fix the StackWalker bug.
But it is worth noting the following fact. If the test program is compiled with the /EHsc option, the StackWalker will work almost correctly. There will only be an error in the line numbers (look to main and foo line numbers).
DebugLog for: /EHsc, THROW_CPP_EXCEPTION = 0, CATCH_CPP_EXCEPTION = 0
main.cpp (11): bar
main.cpp (23): foo
main.cpp (31): test
main.cpp (54): main
exe_common.inl (253): __scrt_common_main_seh
And this bug is very serious! Need to fix!
—
You are receiving this because you are subscribed to this thread.
Reply to this email directly, view it on GitHub<#41>, or unsubscribe<https://github.com/notifications/unsubscribe-auth/ACP35X5O5IEHWDBB4JEI2SDSRY5HTANCNFSM4UDT2Y4Q>.
|
remittor
changed the title
Incorrect stack trace info for C++ exceptions (Win64)
Incorrect stack trace info for C++ exceptions
Nov 29, 2020
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
If C++ exceptions are used in the project, then to use
__try
/__except
it is necessary to build the project with the/EHa
option!Proof: https://docs.microsoft.com/en-us/cpp/cpp/structured-exception-handling-c-cpp?view=msvc-160
When using C++ exceptions, the
StackWalker
cannot get information about the last call in which the exception occurred.Here is the code to demonstrate this bug:
https://github.com/remittor-pr/StackWalker/blob/9be4790427145ba81adfd22188e591820f92a0ad/Main/StackWalker/main.cpp
Compiler:
MSVC2015
(x64 Release)Options with which the test project was built:
/MT /Zi /O2 /EHa
DebugLog for:
THROW_CPP_EXP = 0
,CATCH_CPP_EXP = 0
DebugLog for:
THROW_CPP_EXP = 1
,CATCH_CPP_EXP = 0
DebugLog for:
THROW_CPP_EXP = 0
,CATCH_CPP_EXP = 1
DebugLog for:
THROW_CPP_EXP = 1
,CATCH_CPP_EXP = 1
DebugLog for:
THROW_CPP_EXP = 1
,CATCH_CPP_EXP = 2
The last log shows how using the
CATCH_CPP_EXP = 2
option allows you to fix theStackWalker
bug.But it is worth noting the following fact. If the test program is compiled with the
/EHsc
option, theStackWalker
will work better (but not correctly). There will be an error in the line numbers (look tomain
andbar
line numbers).DebugLog for:
/EHsc
,THROW_CPP_EXP = 0
,CATCH_CPP_EXP = 0
DebugLog for:
/EHsc
,THROW_CPP_EXP = 0
,CATCH_CPP_EXP = 1
DebugLog for:
/EHsc
,THROW_CPP_EXP = 1
,CATCH_CPP_EXP = 0
Same as for
/EHa
DebugLog for:
/EHsc
,THROW_CPP_EXP = 1
,CATCH_CPP_EXP = 1
Same as for
/EHa
DebugLog for:
/EHsc
,THROW_CPP_EXP = 1
,CATCH_CPP_EXP = 2
Same as for
/EHa
It is necessary to explicitly write about this problem in the documentation!
The text was updated successfully, but these errors were encountered: