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

Is resumable task exception safe? #1293

Closed
feverzsj opened this issue Jan 13, 2024 · 5 comments
Closed

Is resumable task exception safe? #1293

feverzsj opened this issue Jan 13, 2024 · 5 comments
Assignees
Labels

Comments

@feverzsj
Copy link

I know windows fiber is exception safe with proper compiler flags. But gcc/llvm based implementations typically require save/restore cxa global states while switching context to assure correct exception behaviour, which I didn't find in the source.

@sarathnandu
Copy link
Contributor

I believe save/restore cxa global states is managed as part of the C++ runtime support for exception handling. In the case of TBB, exception handling is facilitated through functions available in stdexcept/exception header. Nevertheless for any parallel algorithm with resumable task any exceptions that arise are captured and subsequently thrown on the thread that initiated the algorithm.
Do you have any specific use-case or example in mind?

@feverzsj
Copy link
Author

feverzsj commented Jan 17, 2024

I believe save/restore cxa global states is managed as part of the C++ runtime support for exception handling. In the case of TBB, exception handling is facilitated through functions available in stdexcept/exception header. Nevertheless for any parallel algorithm with resumable task any exceptions that arise are captured and subsequently thrown on the thread that initiated the algorithm. Do you have any specific use-case or example in mind?

libc++/libstdc++ based exception handling typically uses per thread cxa globals. When you switch the context, these gobals may be mismatched. On win/msvc, structured exception handling is stack based, so win fiber is also exception safe.

A portable way to handle cxa global is to overwrite __cxa_get_globals, and switch globals manually while switching context. Here is a example:

https://github.com/userver-framework/userver/blob/3cdb435a57d91df88124cbfdddaac714ba07b1d6/core/src/engine/task/cxxabi_eh_globals.cpp#L53-L60

https://github.com/userver-framework/userver/blob/3cdb435a57d91df88124cbfdddaac714ba07b1d6/core/src/engine/task/task_context.cpp#L82-L98

Without switching those globals, simple throw and catch are just fine, but when you try switching the context in the middle of stack unwinding (for doing some async cleanup maybe), crashes may happen.

Popular implementation like boost.context doesn't do this, because it wants a portable way to control the stack space, while win fiber won't let you do this, and cxa globals only work in libc++/libstdc++. So such implementation would forbid switching context while unwinding.

@sarathnandu
Copy link
Contributor

Thank you for providing more information! We were previously unaware that libc++/libstdc++ based exception handling relies on per thread cxa global. We will investigate further and provide necessary patch to support exception safety in resumable task.

@sarathnandu sarathnandu self-assigned this Jan 17, 2024
@sarathnandu
Copy link
Contributor

Would you be able to provide us a reproducer which cause the issue with TBB suspend/resume API?

@sarathnandu
Copy link
Contributor

I am assuming this has been resolved. Please provide a reproducer and feel free to reopen the issue if you think we could implement exception safety in a better way.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

2 participants