why does protobufs proto3 AssignDescriptors throw std::system_error?

353 Views Asked by At

I'm using protoc 3.19.4

message definition

syntax = "proto3";
package wibble;
option cc_enable_arenas = true;
option optimize_for = CODE_SIZE;

message Test {
  string id = 1;
  string name = 2;
}

client code capi

#include <google/protobuf/util/json_util.h>
#include <test.pb.h>

#include <string>

int main() {
  GOOGLE_PROTOBUF_VERIFY_VERSION;

  wibble::Test msg{};
  msg.set_id("wibble");
  msg.set_name("friznit");

  std::string asJSON{};
  google::protobuf::util::JsonPrintOptions jopts{};
  jopts.add_whitespace = true;
  jopts.preserve_proto_field_names = true;
  google::protobuf::util::MessageToJsonString(msg, &asJSON,
                                              jopts);  // crashes here
  std::cout << asJSON << std::endl;

  google::protobuf::ShutdownProtobufLibrary();
}

stack trace

Program received signal SIGABRT, Aborted.
__GI_raise (sig=sig@entry=6) at ../sysdeps/unix/sysv/linux/raise.c:50
50      ../sysdeps/unix/sysv/linux/raise.c: No such file or directory.
(gdb) where
#0  __GI_raise (sig=sig@entry=6) at ../sysdeps/unix/sysv/linux/raise.c:50
#1  0x00007ffff7bf9859 in __GI_abort () at abort.c:79
#2  0x00007ffff7e82911 in ?? () from /lib/x86_64-linux-gnu/libstdc++.so.6
#3  0x00007ffff7e8e38c in ?? () from /lib/x86_64-linux-gnu/libstdc++.so.6
#4  0x00007ffff7e8e3f7 in std::terminate() () from /lib/x86_64-linux-gnu/libstdc++.so.6
#5  0x00007ffff7e8e6a9 in __cxa_throw () from /lib/x86_64-linux-gnu/libstdc++.so.6
#6  0x00007ffff7e8573f in std::__throw_system_error(int) () from /lib/x86_64-linux-gnu/libstdc++.so.6
#7  0x00005555555c2eee in void std::call_once<google::protobuf::internal::AssignDescriptors(google::protobuf::internal::DescriptorTable const* (*)(), std::once_flag*, google::protobuf::Metadata const&)::{lambda()#1}>(std::once_flag&, google::protobuf::internal::AssignDescriptors(google::protobuf::internal::DescriptorTable const* (*)(), std::once_flag*, google::protobuf::Metadata const&)::{lambda()#1}&&) ()
#8  0x00005555555c2bb9 in google::protobuf::internal::AssignDescriptors(google::protobuf::internal::DescriptorTable const* (*)(), std::once_flag*, google::protobuf::Metadata const&) ()
#9  0x000055555556b790 in wibble::Test::GetMetadata (this=0x7fffffffe600) at src/protoc/test.pb.cc:153
#10 0x00005555555c5439 in google::protobuf::Message::GetDescriptor() const ()
#11 0x00005555555f222b in google::protobuf::util::MessageToJsonString(google::protobuf::Message const&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >*, google::protobuf::util::JsonPrintOptions const&) ()
#12 0x000055555556d009 in main () at src/main.cpp:29

inspection of the parameters passed to wibble::Test::GetMetadata

::PROTOBUF_NAMESPACE_ID::Metadata Test::GetMetadata() const {
  return ::PROTOBUF_NAMESPACE_ID::internal::AssignDescriptors(
      &descriptor_table_test_2eproto_getter, &descriptor_table_test_2eproto_once,
      file_level_metadata_test_2eproto[0]);
}

(gdb) p descriptor_table_test_2eproto_getter
$2 = {const google::protobuf::internal::DescriptorTable *(void)} 0x55555556b44a <descriptor_table_test_2eproto_getter()>

(gdb) p descriptor_table_test_2eproto_once
$4 = {_M_once = 0}

(gdb) p file_level_metadata_test_2eproto
$5 = {{descriptor = 0x0, reflection = 0x0}} // suspicious?

I suspect I'm missing a library that it expects (though I've checked all the ones listed by ldd capi are present.

Thanks for your help.

1

There are 1 best solutions below

0
On

the answer to this question helped: std::call_once

Linking with -pthread fixed the problem.