Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Static linking to executable and dll (shared object) #863

Closed
nadiasvertex opened this issue Oct 7, 2015 · 3 comments
Closed

Static linking to executable and dll (shared object) #863

nadiasvertex opened this issue Oct 7, 2015 · 3 comments

Comments

@nadiasvertex
Copy link

I have a project which compiles c++ generated protobuf serializers into a static library. An executable links against this library, and an .so (.dll) does too. The executable later loads the .so file. When that happens, I get:

[libprotobuf ERROR /home/csnelson/meps/projects/mf-toolchain/src/protobuf-3.0.0-beta-1/src/google/protobuf/descriptor_database.cc:57] File already exists in database: mri.proto
[libprotobuf FATAL /home/csnelson/meps/projects/mf-toolchain/src/protobuf-3.0.0-beta-1/src/google/protobuf/descriptor.cc:1128] 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):
Aborted (core dumped)

This didn't happen with 2.6.1, but is now happening with 3.0 beta-1. This is quite a problem since both the .so and the executable need to have a copy of the serializer/deserializer.

I looked at similar errors, but I'm quite sure that I'm only linking against the library, not recompiling the source. As far as I can tell, this should mean that the compiled-in data is the same.

Also note: this problem only happens on Linux. This works fine on Windows and OS X.

Any suggestions to fix this are appreciated.

@xdmiodz
Copy link

xdmiodz commented Nov 6, 2015

Hi,

I had the same issue when my libraries were linked to the dynamic protobuf library, but the issue gone after I changed it to the static one. Also I had to recompile the static protobuf library with the -fPIC flag.

However I'm not sure whether this is an issue or a feature. I there is no such issue with 2.6.1, it would be great to have the same behaviour in 3.0 too.

@drubinstein
Copy link

I believe the cause for this is the same as in the issue talked about in #194 and that affects protobuf 2.6.1.

I recently ran into this issue and I believe the problem has to do with the existence of non-plain old data static const class members in the source. One example being the variable kEmpty in descriptor.cc. The easiest way to duplicate this bug as mentioned in the initial post is to have a binary and a shared object. Both of which statically link against libprotobuf. Have the binary dlopen the shared object. That will create a memory leak since the static const variable is effectively a global and the symbol table will not resolve them as different since they are both in the global scope. Valgrind will report definitely lost memory showing as much. Upon dlclosing the shared object, the destructor for the static const will be called. When the program ends, the destructor for the static const will be called again, creating a double delete. Also, this practice is against google coding standards as per https://google.github.io/styleguide/cppguide.html#Static_and_Global_Variables.

One possible solution is to replace the static const non-pod type with a getter function that returns a const reference. Inside that function, it is safe to define a static const non-pod variable.

Another solution is to limit the scoping of the symbol table. Have some variables that need to be exported in global scope and others in local scope.

The coding standards link suggests letting the leak happen and dynamically allocating memory for the object on startup, but never freeing.

@rinatz
Copy link
Contributor

rinatz commented Dec 19, 2015

@nadiasvertex I sent the pull request to fix this problem and it was merged.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

5 participants