Home Ask Login Register

Developers Planet

Your answer is one click away!

Crete February 2016

Protobuf and Node.JS library error

I'm working with google protocol buffers with Node.JS on Ubuntu 14.04 LTS. I have two different (A and B) Node.JS addons (c++) using the same protocol buffers and protobuf library. When I create a new instance of module B with require() after module A had been required before, the server stops with error message:

[libprotobuf ERROR google/protobuf/descriptor_database.cc:57] File already exists in database: Anam.proto 
[libprotobuf FATAL google/protobuf/descriptor.cc:1157] CHECK failed: generated_database_->Add(encoded_file_descriptor, size):  terminate called after throwing an instance of 'google::protobuf::FatalException'
what():  CHECK failed: generated_database_->Add(encoded_file_descriptor, size)

I've googled the error and found that others experience this error only on Linux. I've also installed the latest version of protobuf library from github, but it didn't helped. The part of binding.gyp, where I include libprotobuf looks like this:

"libraries": ["/usr/lib/libpq.so",
              "/usr/local/lib/libprotobuf.so",
              "/usr/local/lib/libboost_system.so",
              "/usr/local/lib/libboost_thread.so",
              "/usr/local/lib/libboost_signals.so"]

If I make more instances of the same module (for example require addon A 2 times), it works. Does anybody have any suggestion how to fix this problem?

Answers


Kenton Varda February 2016

The problem is probably that both of these C++ modules contain separate compiled copies of the same .proto file(s), but are sharing the same copy of libprotobuf.so. Each one tries to register its protobuf descriptor types with the global type descriptor table, and then a conflict is seen.

There are two ways to correct the problem:

  1. Move the shared .proto files into a shared library which both modules link against (so that they end up sharing one copy of the complied protos).
  2. Make each module statically link against libprotobuf, so that they don't share libprotobuf. This way each will get its own descriptor table. Note that this approach won't work if one module ever receives protobuf objects created by the other (if they only exchange serialized messages, not objects, that's fine).

Note that this problem affects all platforms, but it's possible that people aren't seeing it on Windows because statically linking libprotobuf is more common there.

Post Status

Asked in February 2016
Viewed 3,243 times
Voted 11
Answered 1 times

Search




Leave an answer


Quote of the day: live life