mardi 18 janvier 2022

GCC infers pass-by-value copy assignment with jsoncpp

const Descriptor* descriptor_ptr = msg.GetDescriptor();
const Reflection* reflection_ptr = msg.GetReflection();
const FieldDescriptor* field_ptr = descriptor_ptr->field(i);
Json::Value value;

if (field_ptr->cpp_type() == FieldDescriptor::CPPTYPE_UINT32)
{
    value[field_ptr->name()] = reflection_ptr->GetUInt32(msg, field_ptr);
}

In our case, we tried to build a shared lib with a proto to json function The linked app would crash with no core dump and we got output in gdb as

Inferior 1 (process xxx) exited with code 0177

and _dl_signal_error frame.

Code line resulted in the error was

value[field_ptr->name()] = reflection_ptr->GetUInt32(msg, field_ptr);

and we found that ldd -r shows the shared lib has undefined symbol pointing to _ZN4Json5ValueaSES0_, demangled as Json::Value::operator=(Json::Value) by c++filt

It surprised us a lot because there was no pass-by-value copy assignment function in jsoncpp's headers or source code. We tried recompile it with latest release of jsoncpp and the problem remains

However, when we make a stand alone jsoncpp demo, it works fine and ldd -r no longer shows the undefined symbol output

We guess it's gcc which interprets and chooses a non-existent copy assignment operator. It may be relevant to copy emision or other optimization, how can we fix it? or how to explicitly use a valid copy assignment operator?

Linux version we use is Linux version 2.6.32-696.el6.x86_64 CentOS release 6.9 (Final), gcc version is gcc (GCC) 9.1.0

compiling options are

C_FLAGS          = -Wall -D_GNU_SOURCE  -Wno-deprecated -fPIC -g -pipe -D_DEBUG -Woverloaded-virtual -Wpointer-arith -fno-strict-aliasing -std=c++17

and link with jsoncpp static lib

Aucun commentaire:

Enregistrer un commentaire