Skip to content
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

Open
remittor opened this issue Nov 26, 2020 · 1 comment
Open

Incorrect stack trace info for C++ exceptions #41

remittor opened this issue Nov 26, 2020 · 1 comment

Comments

@remittor
Copy link
Contributor

remittor commented Nov 26, 2020

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

THROW_CPP_EXP = 0, CATCH_CPP_EXP = 0
----- bar -----
===== main.__except =====
main.cpp (23): bar
main.cpp (30): foo
main.cpp (41): test
main.cpp (72): main
exe_common.inl (253): __scrt_common_main_seh
----- Foo destructor -----
***** END *****

DebugLog for: THROW_CPP_EXP = 1, CATCH_CPP_EXP = 0

THROW_CPP_EXP = 1, CATCH_CPP_EXP = 0
----- bar -----
===== main.__except =====
KERNELBASE: RaiseException
throw.cpp (136): _CxxThrowException
main.cpp (22): bar
main.cpp (30): foo
main.cpp (41): test
main.cpp (71): main
exe_common.inl (253): __scrt_common_main_seh
----- Foo destructor -----
***** END *****

DebugLog for: THROW_CPP_EXP = 0, CATCH_CPP_EXP = 1

THROW_CPP_EXP = 0, CATCH_CPP_EXP = 1
----- bar -----
----- Foo destructor -----
===== test.catch =====
stackwalker.cpp (1073): StackWalker::ShowCallstack
main.cpp (52): `test'::`1'::catch$1
handlers.asm (50): _CallSettingFrame
frame.cpp (1322): __CxxCallCatchBlock
ntdll: RtlRestoreContext
main.cpp (41): test
main.cpp (72): main
exe_common.inl (253): __scrt_common_main_seh
===== main.__except =====
KERNELBASE: RaiseException
frame.cpp (1342): __CxxCallCatchBlock
ntdll: RtlRestoreContext
main.cpp (41): test
main.cpp (72): main
exe_common.inl (253): __scrt_common_main_seh
***** END *****

DebugLog for: THROW_CPP_EXP = 1, CATCH_CPP_EXP = 1

THROW_CPP_EXP = 1, CATCH_CPP_EXP = 1
----- bar -----
----- Foo destructor -----
===== test.catch =====
stackwalker.cpp (1073): StackWalker::ShowCallstack
main.cpp (52): `test'::`1'::catch$1
handlers.asm (50): _CallSettingFrame
frame.cpp (1322): __CxxCallCatchBlock
ntdll: RtlRestoreContext
main.cpp (41): test
main.cpp (71): main
exe_common.inl (253): __scrt_common_main_seh
===== main.__except =====
KERNELBASE: RaiseException
frame.cpp (1342): __CxxCallCatchBlock
ntdll: RtlRestoreContext
main.cpp (41): test
main.cpp (71): main
exe_common.inl (253): __scrt_common_main_seh
***** END *****

DebugLog for: THROW_CPP_EXP = 1, CATCH_CPP_EXP = 2

THROW_CPP_EXP = 1, CATCH_CPP_EXP = 2
----- bar -----
----- Foo destructor -----
===== test.catch =====
KERNELBASE: RaiseException
throw.cpp (136): _CxxThrowException
main.cpp (22): bar
main.cpp (30): foo
main.cpp (41): test
main.cpp (71): main
exe_common.inl (253): __scrt_common_main_seh
===== main.__except =====
KERNELBASE: RaiseException
frame.cpp (1342): __CxxCallCatchBlock
ntdll: RtlRestoreContext
main.cpp (41): test
main.cpp (71): main
exe_common.inl (253): __scrt_common_main_seh
***** END *****

The last log shows how using the CATCH_CPP_EXP = 2 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 better (but not correctly). There will be an error in the line numbers (look to main and bar line numbers).

DebugLog for: /EHsc, THROW_CPP_EXP = 0, CATCH_CPP_EXP = 0

THROW_CPP_EXP = 0, CATCH_CPP_EXP = 0
----- bar -----
===== main.__except =====
main.cpp (23): bar
main.cpp (30): foo
main.cpp (41): test
main.cpp (72): main
exe_common.inl (253): __scrt_common_main_seh
***** END *****

DebugLog for: /EHsc, THROW_CPP_EXP = 0, CATCH_CPP_EXP = 1

THROW_CPP_EXP = 0, CATCH_CPP_EXP = 1
----- bar -----
===== main.__except =====
main.cpp (23): bar
main.cpp (30): foo
main.cpp (41): test
main.cpp (72): main
exe_common.inl (253): __scrt_common_main_seh
***** END *****

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!

@JochenKalmbach
Copy link
Owner

JochenKalmbach commented Nov 28, 2020 via email

@remittor 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
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants