Well, what it does now it that the program just crashes with an "uncaught exception".
Catching all exceptions inside becomes very hairy though, as functions called inside with_libc might throw some exceptions that need to be handled elsewhere.
For now the best fix seems to wrap only the necessary functions inside with_libc (and have it return an error code the C way) and doing the rest of the computations outside it.
Wouldn't it make sense to move with_libc into the critical functions that need it themselves? Or to create wrappers for them in the include files included by the components (socket.h etc.), similar to how posix just transparently wraps main() in with_libc? This way the programmer is not bothered with it at all unless it's necessary.
On 14-03-17 16:01, Christian Helmuth wrote:
Hello Boris,
On Tue, Mar 14, 2017 at 03:11:27PM +0100, Boris Mulder wrote:
Whenever I throw an exception somewhere in code inside a with_libc lambda expression, and try to catch it outside of that block, it will not catch that exception.
As I know the inner workings of the libc execution model this observation sounds pretty natural, because in the end with_libc() is just like: Please execute the given lambda body on an alternate stack. The C++ exception implementation on the other hand heavily depends on the current execution stack. Therefore, I wonder does it just not work as expected or does it break gloriously?
Example:
|t||ry {|
| Libc::with_libc([&] () { ... throw E||xception(); ... } );|
|} catch (Exception &e) {|| Genode::log("caught");|||| }
|The "caught" will never be printed in this case. What can I do to fix/work around this?
The only workaround I see at the moment is to move the exception handling also into the lambda function. Reflection of error or exceptional conditions to the enclosing function then could be implemented by return values or state changes in referenced objects. I admit that is not what one should expect from a C++ framework but to be fair with_libc() just bridges a strange gap between Genode components and the legacy C runtime world.
We also had a small discussion about a more advanced solution where you may declare expected exception types that can be passed out of the lambda like we did for RPC. But, a solution with reasonable effort would also come with a bunch of limitations, e.g., that exception types could only be POD-like.
Greets