What determines binary compatibility of shared libraries on Linux?
I am building a shared library on Linux, which serves as a "plugin" to some software (to be specific, it extends Mathematica).
I find that if I build on Ubuntu 16.04, the resulting library does not work on RHEL 7.6. However, if I build on RHEL 7.6, the library works both on RHEL and Ubuntu.
By "does not work", I mean that Mathematica refuses to load it, but it only gives a generic and unuseful "failed to load" error message.
I have eliminated a number of factors that could break compatibility, and I cannot find any more. This question is about what else might affect compatibility than what I list below.
The library is written in a mix of C and C++, but it exports a C interface. It is built with -static-libstdc++
and -static-libgcc
. If I use ldd
on the .so
file, the only dependencies it lists are:
linux-vdso.so.1 => (0x00007ffc757b9000)
libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007fa286e62000)
/lib64/ld-linux-x86-64.so.2 (0x00007fa287854000)
One potential source of incompatibility is the glibc
version. I looked at the symbols in the library using nm -gC
, and the highest GLIBC version reference I see when I build on Ubuntu is 2.14. RHEL 7.6 has glibc 2.17, i.e. newer than 2.14. Thus I do not believe that the incompatibility is due to glibc.
What else is there that can cause a shared object compiled on Ubuntu 16.04 not to load on RHEL 7.6?
Update: I managed to coax Mathematica to give a more descriptive error (it was a not very well documented feature), so I have a concrete error message. The same could also be seen with @Ctx's suggestion to set LD_DEBUG=all
.
The error is:
IGraphM.so: undefined symbol: _ZTVNSt7__cxx1115basic_stringbufIcSt11char_traitsIcESaIcEEE
(IGraphM.so
is my library.)
This function would seem to be part of libstdc++ unless I am mistaken. Why does this error occur if I specified -static-libstdc++
and verified that ldd
does not list libstdc++?
Update 2:
Per the advice by SergeyA and this QA, I compiled after defining _GLIBCXX_USE_CXX11_ABI=0
. This does fix the incompatibility.
But I still do not understand why. The error message complains about a missing symbol. Where is this symbol normally loaded from? I was under the impression that if I use -static-libstdc++
, then it should be contained within my library. This seems to be wrong.
While I seem to have a practical solution for the incompatibility for this specific case, I would appreciate some explanations so in the future I can solve similar problems on my own.
c++ c linux shared-libraries abi
|
show 15 more comments
I am building a shared library on Linux, which serves as a "plugin" to some software (to be specific, it extends Mathematica).
I find that if I build on Ubuntu 16.04, the resulting library does not work on RHEL 7.6. However, if I build on RHEL 7.6, the library works both on RHEL and Ubuntu.
By "does not work", I mean that Mathematica refuses to load it, but it only gives a generic and unuseful "failed to load" error message.
I have eliminated a number of factors that could break compatibility, and I cannot find any more. This question is about what else might affect compatibility than what I list below.
The library is written in a mix of C and C++, but it exports a C interface. It is built with -static-libstdc++
and -static-libgcc
. If I use ldd
on the .so
file, the only dependencies it lists are:
linux-vdso.so.1 => (0x00007ffc757b9000)
libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007fa286e62000)
/lib64/ld-linux-x86-64.so.2 (0x00007fa287854000)
One potential source of incompatibility is the glibc
version. I looked at the symbols in the library using nm -gC
, and the highest GLIBC version reference I see when I build on Ubuntu is 2.14. RHEL 7.6 has glibc 2.17, i.e. newer than 2.14. Thus I do not believe that the incompatibility is due to glibc.
What else is there that can cause a shared object compiled on Ubuntu 16.04 not to load on RHEL 7.6?
Update: I managed to coax Mathematica to give a more descriptive error (it was a not very well documented feature), so I have a concrete error message. The same could also be seen with @Ctx's suggestion to set LD_DEBUG=all
.
The error is:
IGraphM.so: undefined symbol: _ZTVNSt7__cxx1115basic_stringbufIcSt11char_traitsIcESaIcEEE
(IGraphM.so
is my library.)
This function would seem to be part of libstdc++ unless I am mistaken. Why does this error occur if I specified -static-libstdc++
and verified that ldd
does not list libstdc++?
Update 2:
Per the advice by SergeyA and this QA, I compiled after defining _GLIBCXX_USE_CXX11_ABI=0
. This does fix the incompatibility.
But I still do not understand why. The error message complains about a missing symbol. Where is this symbol normally loaded from? I was under the impression that if I use -static-libstdc++
, then it should be contained within my library. This seems to be wrong.
While I seem to have a practical solution for the incompatibility for this specific case, I would appreciate some explanations so in the future I can solve similar problems on my own.
c++ c linux shared-libraries abi
glibc should be fine. I assume both systems are the same platform (say, x86-64). Perhaps Mathematica is a 32-bit application but you're supplying a 64-bit shared object? Have you tried creating an empty "dummy" plugin with no code, and using C only, to see if that works? The result might rule out some possibilities either way.
– TypeIA
Nov 13 '18 at 15:33
Also look around and see if Mathematica writes a log file that might contain more information. I'd be surprised if it didn't log something useful somewhere.
– TypeIA
Nov 13 '18 at 15:34
You can try toexport LD_DEBUG=all
in the console, where you start mathematica. Maybe it yields some debug output which can help you.
– Ctx
Nov 13 '18 at 15:44
@TypeIA Yes, same architecture (x86-64) and same version of Mathematica, but now that you asked, I started to wonder if the CPUs of the two machines support the same instruction set (e.g. when compiled on one system, gcc emits an instruction that only newer CPUs have). However, that would cause a crash, not a non-fatal failure, no?
– Szabolcs
Nov 13 '18 at 15:45
1
You missing symbol demangles tovtable for std::__cxx11::basic_stringbuf<char, std::char_traits<char>, std::allocator<char> >
stackoverflow.com/questions/33394934/… might have some clues.
– SergeyA
Nov 13 '18 at 16:24
|
show 15 more comments
I am building a shared library on Linux, which serves as a "plugin" to some software (to be specific, it extends Mathematica).
I find that if I build on Ubuntu 16.04, the resulting library does not work on RHEL 7.6. However, if I build on RHEL 7.6, the library works both on RHEL and Ubuntu.
By "does not work", I mean that Mathematica refuses to load it, but it only gives a generic and unuseful "failed to load" error message.
I have eliminated a number of factors that could break compatibility, and I cannot find any more. This question is about what else might affect compatibility than what I list below.
The library is written in a mix of C and C++, but it exports a C interface. It is built with -static-libstdc++
and -static-libgcc
. If I use ldd
on the .so
file, the only dependencies it lists are:
linux-vdso.so.1 => (0x00007ffc757b9000)
libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007fa286e62000)
/lib64/ld-linux-x86-64.so.2 (0x00007fa287854000)
One potential source of incompatibility is the glibc
version. I looked at the symbols in the library using nm -gC
, and the highest GLIBC version reference I see when I build on Ubuntu is 2.14. RHEL 7.6 has glibc 2.17, i.e. newer than 2.14. Thus I do not believe that the incompatibility is due to glibc.
What else is there that can cause a shared object compiled on Ubuntu 16.04 not to load on RHEL 7.6?
Update: I managed to coax Mathematica to give a more descriptive error (it was a not very well documented feature), so I have a concrete error message. The same could also be seen with @Ctx's suggestion to set LD_DEBUG=all
.
The error is:
IGraphM.so: undefined symbol: _ZTVNSt7__cxx1115basic_stringbufIcSt11char_traitsIcESaIcEEE
(IGraphM.so
is my library.)
This function would seem to be part of libstdc++ unless I am mistaken. Why does this error occur if I specified -static-libstdc++
and verified that ldd
does not list libstdc++?
Update 2:
Per the advice by SergeyA and this QA, I compiled after defining _GLIBCXX_USE_CXX11_ABI=0
. This does fix the incompatibility.
But I still do not understand why. The error message complains about a missing symbol. Where is this symbol normally loaded from? I was under the impression that if I use -static-libstdc++
, then it should be contained within my library. This seems to be wrong.
While I seem to have a practical solution for the incompatibility for this specific case, I would appreciate some explanations so in the future I can solve similar problems on my own.
c++ c linux shared-libraries abi
I am building a shared library on Linux, which serves as a "plugin" to some software (to be specific, it extends Mathematica).
I find that if I build on Ubuntu 16.04, the resulting library does not work on RHEL 7.6. However, if I build on RHEL 7.6, the library works both on RHEL and Ubuntu.
By "does not work", I mean that Mathematica refuses to load it, but it only gives a generic and unuseful "failed to load" error message.
I have eliminated a number of factors that could break compatibility, and I cannot find any more. This question is about what else might affect compatibility than what I list below.
The library is written in a mix of C and C++, but it exports a C interface. It is built with -static-libstdc++
and -static-libgcc
. If I use ldd
on the .so
file, the only dependencies it lists are:
linux-vdso.so.1 => (0x00007ffc757b9000)
libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007fa286e62000)
/lib64/ld-linux-x86-64.so.2 (0x00007fa287854000)
One potential source of incompatibility is the glibc
version. I looked at the symbols in the library using nm -gC
, and the highest GLIBC version reference I see when I build on Ubuntu is 2.14. RHEL 7.6 has glibc 2.17, i.e. newer than 2.14. Thus I do not believe that the incompatibility is due to glibc.
What else is there that can cause a shared object compiled on Ubuntu 16.04 not to load on RHEL 7.6?
Update: I managed to coax Mathematica to give a more descriptive error (it was a not very well documented feature), so I have a concrete error message. The same could also be seen with @Ctx's suggestion to set LD_DEBUG=all
.
The error is:
IGraphM.so: undefined symbol: _ZTVNSt7__cxx1115basic_stringbufIcSt11char_traitsIcESaIcEEE
(IGraphM.so
is my library.)
This function would seem to be part of libstdc++ unless I am mistaken. Why does this error occur if I specified -static-libstdc++
and verified that ldd
does not list libstdc++?
Update 2:
Per the advice by SergeyA and this QA, I compiled after defining _GLIBCXX_USE_CXX11_ABI=0
. This does fix the incompatibility.
But I still do not understand why. The error message complains about a missing symbol. Where is this symbol normally loaded from? I was under the impression that if I use -static-libstdc++
, then it should be contained within my library. This seems to be wrong.
While I seem to have a practical solution for the incompatibility for this specific case, I would appreciate some explanations so in the future I can solve similar problems on my own.
c++ c linux shared-libraries abi
c++ c linux shared-libraries abi
edited Nov 13 '18 at 16:43
Szabolcs
asked Nov 13 '18 at 14:51
SzabolcsSzabolcs
16.1k361144
16.1k361144
glibc should be fine. I assume both systems are the same platform (say, x86-64). Perhaps Mathematica is a 32-bit application but you're supplying a 64-bit shared object? Have you tried creating an empty "dummy" plugin with no code, and using C only, to see if that works? The result might rule out some possibilities either way.
– TypeIA
Nov 13 '18 at 15:33
Also look around and see if Mathematica writes a log file that might contain more information. I'd be surprised if it didn't log something useful somewhere.
– TypeIA
Nov 13 '18 at 15:34
You can try toexport LD_DEBUG=all
in the console, where you start mathematica. Maybe it yields some debug output which can help you.
– Ctx
Nov 13 '18 at 15:44
@TypeIA Yes, same architecture (x86-64) and same version of Mathematica, but now that you asked, I started to wonder if the CPUs of the two machines support the same instruction set (e.g. when compiled on one system, gcc emits an instruction that only newer CPUs have). However, that would cause a crash, not a non-fatal failure, no?
– Szabolcs
Nov 13 '18 at 15:45
1
You missing symbol demangles tovtable for std::__cxx11::basic_stringbuf<char, std::char_traits<char>, std::allocator<char> >
stackoverflow.com/questions/33394934/… might have some clues.
– SergeyA
Nov 13 '18 at 16:24
|
show 15 more comments
glibc should be fine. I assume both systems are the same platform (say, x86-64). Perhaps Mathematica is a 32-bit application but you're supplying a 64-bit shared object? Have you tried creating an empty "dummy" plugin with no code, and using C only, to see if that works? The result might rule out some possibilities either way.
– TypeIA
Nov 13 '18 at 15:33
Also look around and see if Mathematica writes a log file that might contain more information. I'd be surprised if it didn't log something useful somewhere.
– TypeIA
Nov 13 '18 at 15:34
You can try toexport LD_DEBUG=all
in the console, where you start mathematica. Maybe it yields some debug output which can help you.
– Ctx
Nov 13 '18 at 15:44
@TypeIA Yes, same architecture (x86-64) and same version of Mathematica, but now that you asked, I started to wonder if the CPUs of the two machines support the same instruction set (e.g. when compiled on one system, gcc emits an instruction that only newer CPUs have). However, that would cause a crash, not a non-fatal failure, no?
– Szabolcs
Nov 13 '18 at 15:45
1
You missing symbol demangles tovtable for std::__cxx11::basic_stringbuf<char, std::char_traits<char>, std::allocator<char> >
stackoverflow.com/questions/33394934/… might have some clues.
– SergeyA
Nov 13 '18 at 16:24
glibc should be fine. I assume both systems are the same platform (say, x86-64). Perhaps Mathematica is a 32-bit application but you're supplying a 64-bit shared object? Have you tried creating an empty "dummy" plugin with no code, and using C only, to see if that works? The result might rule out some possibilities either way.
– TypeIA
Nov 13 '18 at 15:33
glibc should be fine. I assume both systems are the same platform (say, x86-64). Perhaps Mathematica is a 32-bit application but you're supplying a 64-bit shared object? Have you tried creating an empty "dummy" plugin with no code, and using C only, to see if that works? The result might rule out some possibilities either way.
– TypeIA
Nov 13 '18 at 15:33
Also look around and see if Mathematica writes a log file that might contain more information. I'd be surprised if it didn't log something useful somewhere.
– TypeIA
Nov 13 '18 at 15:34
Also look around and see if Mathematica writes a log file that might contain more information. I'd be surprised if it didn't log something useful somewhere.
– TypeIA
Nov 13 '18 at 15:34
You can try to
export LD_DEBUG=all
in the console, where you start mathematica. Maybe it yields some debug output which can help you.– Ctx
Nov 13 '18 at 15:44
You can try to
export LD_DEBUG=all
in the console, where you start mathematica. Maybe it yields some debug output which can help you.– Ctx
Nov 13 '18 at 15:44
@TypeIA Yes, same architecture (x86-64) and same version of Mathematica, but now that you asked, I started to wonder if the CPUs of the two machines support the same instruction set (e.g. when compiled on one system, gcc emits an instruction that only newer CPUs have). However, that would cause a crash, not a non-fatal failure, no?
– Szabolcs
Nov 13 '18 at 15:45
@TypeIA Yes, same architecture (x86-64) and same version of Mathematica, but now that you asked, I started to wonder if the CPUs of the two machines support the same instruction set (e.g. when compiled on one system, gcc emits an instruction that only newer CPUs have). However, that would cause a crash, not a non-fatal failure, no?
– Szabolcs
Nov 13 '18 at 15:45
1
1
You missing symbol demangles to
vtable for std::__cxx11::basic_stringbuf<char, std::char_traits<char>, std::allocator<char> >
stackoverflow.com/questions/33394934/… might have some clues.– SergeyA
Nov 13 '18 at 16:24
You missing symbol demangles to
vtable for std::__cxx11::basic_stringbuf<char, std::char_traits<char>, std::allocator<char> >
stackoverflow.com/questions/33394934/… might have some clues.– SergeyA
Nov 13 '18 at 16:24
|
show 15 more comments
1 Answer
1
active
oldest
votes
I can't explain why your .so library doesn't link all the used symbols statically (and instead leaves them as undefined), but I can offer practical suggestion on how to fix the issue at hand.
You can stop linking libstdc++
statically into your plugin, and instead use the one available to host system. This doesn't work for you because of ABI incompatibility between build and target platforms. You can downgrade an ABI in use for your plugin by specifying macro _GLIBCXX_USE_CXX11_ABI=0
.
add a comment |
Your Answer
StackExchange.ifUsing("editor", function ()
StackExchange.using("externalEditor", function ()
StackExchange.using("snippets", function ()
StackExchange.snippets.init();
);
);
, "code-snippets");
StackExchange.ready(function()
var channelOptions =
tags: "".split(" "),
id: "1"
;
initTagRenderer("".split(" "), "".split(" "), channelOptions);
StackExchange.using("externalEditor", function()
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled)
StackExchange.using("snippets", function()
createEditor();
);
else
createEditor();
);
function createEditor()
StackExchange.prepareEditor(
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: true,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: 10,
bindNavPrevention: true,
postfix: "",
imageUploader:
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
,
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
);
);
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53283649%2fwhat-determines-binary-compatibility-of-shared-libraries-on-linux%23new-answer', 'question_page');
);
Post as a guest
Required, but never shown
1 Answer
1
active
oldest
votes
1 Answer
1
active
oldest
votes
active
oldest
votes
active
oldest
votes
I can't explain why your .so library doesn't link all the used symbols statically (and instead leaves them as undefined), but I can offer practical suggestion on how to fix the issue at hand.
You can stop linking libstdc++
statically into your plugin, and instead use the one available to host system. This doesn't work for you because of ABI incompatibility between build and target platforms. You can downgrade an ABI in use for your plugin by specifying macro _GLIBCXX_USE_CXX11_ABI=0
.
add a comment |
I can't explain why your .so library doesn't link all the used symbols statically (and instead leaves them as undefined), but I can offer practical suggestion on how to fix the issue at hand.
You can stop linking libstdc++
statically into your plugin, and instead use the one available to host system. This doesn't work for you because of ABI incompatibility between build and target platforms. You can downgrade an ABI in use for your plugin by specifying macro _GLIBCXX_USE_CXX11_ABI=0
.
add a comment |
I can't explain why your .so library doesn't link all the used symbols statically (and instead leaves them as undefined), but I can offer practical suggestion on how to fix the issue at hand.
You can stop linking libstdc++
statically into your plugin, and instead use the one available to host system. This doesn't work for you because of ABI incompatibility between build and target platforms. You can downgrade an ABI in use for your plugin by specifying macro _GLIBCXX_USE_CXX11_ABI=0
.
I can't explain why your .so library doesn't link all the used symbols statically (and instead leaves them as undefined), but I can offer practical suggestion on how to fix the issue at hand.
You can stop linking libstdc++
statically into your plugin, and instead use the one available to host system. This doesn't work for you because of ABI incompatibility between build and target platforms. You can downgrade an ABI in use for your plugin by specifying macro _GLIBCXX_USE_CXX11_ABI=0
.
edited Nov 13 '18 at 17:16
answered Nov 13 '18 at 17:08
SergeyASergeyA
44.6k53990
44.6k53990
add a comment |
add a comment |
Thanks for contributing an answer to Stack Overflow!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53283649%2fwhat-determines-binary-compatibility-of-shared-libraries-on-linux%23new-answer', 'question_page');
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
glibc should be fine. I assume both systems are the same platform (say, x86-64). Perhaps Mathematica is a 32-bit application but you're supplying a 64-bit shared object? Have you tried creating an empty "dummy" plugin with no code, and using C only, to see if that works? The result might rule out some possibilities either way.
– TypeIA
Nov 13 '18 at 15:33
Also look around and see if Mathematica writes a log file that might contain more information. I'd be surprised if it didn't log something useful somewhere.
– TypeIA
Nov 13 '18 at 15:34
You can try to
export LD_DEBUG=all
in the console, where you start mathematica. Maybe it yields some debug output which can help you.– Ctx
Nov 13 '18 at 15:44
@TypeIA Yes, same architecture (x86-64) and same version of Mathematica, but now that you asked, I started to wonder if the CPUs of the two machines support the same instruction set (e.g. when compiled on one system, gcc emits an instruction that only newer CPUs have). However, that would cause a crash, not a non-fatal failure, no?
– Szabolcs
Nov 13 '18 at 15:45
1
You missing symbol demangles to
vtable for std::__cxx11::basic_stringbuf<char, std::char_traits<char>, std::allocator<char> >
stackoverflow.com/questions/33394934/… might have some clues.– SergeyA
Nov 13 '18 at 16:24