I’m unable to catch exceptions in GCC generated code that were thrown by Cling interpreted code. Please consider the following code snippets illustrating my use case.
class ScriptDefinedClass : public somewhere::in::sharedobj::Base {
public:
ScriptDefinedClass() {}
void DoSth() override {
throw std::runtime_error("This is an exception");
}
};
somewhere::in::sharedobj::Base* InterpretMe() {
return new ScriptDefinedClass;
}
exception handling is working for both script and binary. I tested your suggestion using Cling interactively, in my script and in binary. Just the combination as described above is not working.
Should I mention that after invoking embedded Cling with
this->interpreter_ = new cling::Interpreter(argv.size(), this->ConvertCommandLineArgv(argv), LLVM_PATH_MACRO);
the binary called “cling” has a catch, just like your binary. It manages to catch the exception thrown by the interpreter.
Thus there must be a problem with how you compile or link your binary. Did you consider adding the exception flag I was proposing? Did you consider doing the compiled throw, compiled catch test I was proposing?
If the base class is triggered using “Base::Trigger” the current state is set to “Base::OnTriggered”. Class “Base” is part of a shared library compiled with GCC.
Now please consider the script defined class “ScriptDefinedClass” where exception handling works:
class ScriptDefinedClass : public somewhere::in::sharedobj::Base {
public:
ScriptDefinedClass() {}
void OnTriggered() override {
throw std::runtime_error("This is an exception.");
this->SetCurrentState([this]() { this->OnState1(); });
}
void OnState1() {
return;
}
// ...
};
If an exception is thrown from within “ScriptDefinedClass::OnTriggered”, it can be caught.
If the script defined class “ScriptDefinedClass” is defined like so
class ScriptDefinedClass : public somewhere::in::sharedobj::Base {
public:
ScriptDefinedClass() {}
void OnTriggered() override {
this->SetCurrentState([this]() { this->OnState1(); });
}
void OnState1() {
throw std::runtime_error("This is an exception.");
return;
}
// ...
};
the exception can’t be caught.
I was first thinking that this might be caused by the way GCC and Clang are translating lambda functions, but even std::bind is showing the same behaviour.
In cling, I can create a lambda that throws, call it, and cling’s compiled catch is catching it.
Can you run valgrind on this, to make sure there is no memory issue involved? Ideally you’d run valgrind on a compiled version (i.e. not using cling), to make better sense of stack traces.
I did not run valgrind but when using the script code in a compiled version inside the executable the exception is caught as expected. I did successfully check if my compilation of cling is able to catch exceptions thrown in lambdas as you suggested.