oneTBB icon indicating copy to clipboard operation
oneTBB copied to clipboard

Is resumable task exception safe?

Open feverzsj opened this issue 2 years ago • 4 comments

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.

feverzsj avatar Jan 13 '24 11:01 feverzsj

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?

sarathnandu avatar Jan 16 '24 19:01 sarathnandu

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.

feverzsj avatar Jan 17 '24 05:01 feverzsj

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 avatar Jan 17 '24 21:01 sarathnandu

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

sarathnandu avatar Feb 01 '24 17:02 sarathnandu

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.

sarathnandu avatar May 20 '24 10:05 sarathnandu