Problem
Turning on O2 compiler optimizations (via CMAKE_BUILD_TYPE=Release) produces a Engine that builds successfully, but crashes on startup:
terminate called after throwing an instance of 'std::runtime_error'
what(): Invalid protobuf type.
Investigation
Debugger
Hooking up the Engine to a Debugger (LLDB) produces the following backtrace:
* frame #6: 0x00005555555b849f bentobox`ics::component::UserComponent::setValue(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, bento::protos::Value const&) (.cold) at userValue.h:81:5
frame #7: 0x00005555555db6d4 bentobox`main at main.cpp:63:18
From the backtrace, the issue seems to stem from:
auto tex1 = ics::component::Texture2DComponent();
auto value = bento::protos::Value();
value.mutable_primitive()->set_int_64(1);
value.mutable_data_type()->set_primitive(
bento::protos::Type_Primitive_INT64);
tex1.setValue("texture", value); // Crash happens here
isProtoTypeOfType() is called in setValue():
// TODO(joeltio): Streamline this together with eqOp
// If schemaType and value are numeric, try to convert
if (proto::isProtoTypeOfTypes<proto_NUMERIC>(schemaType) && // Crash happens here
proto::isValOfTypes<proto_NUMERIC>(value)) {
proto::runFnWithVal<proto_NUMERIC>(
value, [&valToSet, &schemaType]<class X>(X x) {
Resulting in a crash in isProtoTypeOfType():
template <class T>
requires ProtobufType<T> bool isProtoTypeOfType(
const bento::protos::Type& protoType) {
throw std::runtime_error("Invalid protobuf type.");
}
Templating
isProtoTypeOfType() is template function that is implemented for:
- specific types:
INT32, INT64, FLOAT32, FLOAT64, STR, BOOL.
- a catchall
T type with an implementation that throws the exception causing the crash.
- this function assumes the catchall implementation will be skipped if a specific types implementation with a closer matching type exists.
To verify this assumption print statements where inserted in isProtoTypeOfType():
- Without optimization, this assumption holds and the catchall implementation is never executed.
- With optimization this assumption does not hold: ALL implementations, including the catchall implementation is executed, causing the crash.
Proposed Fix
Rework isProtoTypeOfType() to remove its dependency on this assumption:
- Remove the catchall case. This should convert the error of specifying an invalid type from a runtime one to a compile time one. The compiler should fail to find a matching implementation for
isProtoTypeOfType() and throw an error.
Problem
Turning on
O2compiler optimizations (viaCMAKE_BUILD_TYPE=Release) produces a Engine that builds successfully, but crashes on startup:Investigation
Debugger
Hooking up the Engine to a Debugger (LLDB) produces the following backtrace:
From the backtrace, the issue seems to stem from:
isProtoTypeOfType()is called insetValue():Resulting in a crash in
isProtoTypeOfType():Templating
isProtoTypeOfType()is template function that is implemented for:INT32,INT64,FLOAT32,FLOAT64,STR,BOOL.Ttype with an implementation that throws the exception causing the crash.To verify this assumption print statements where inserted in isProtoTypeOfType():
Proposed Fix
Rework
isProtoTypeOfType()to remove its dependency on this assumption:isProtoTypeOfType()and throw an error.