Load shared library for another shared library
I am working on an update application that must be able to run on an existing system and is also started by another application on this existing system.
I am using a shared library that itself uses OpenSSL, but didn't link against it. Previously my update application linked against OpenSSL to work around this. But now I cannot link against OpenSSL any longer due to binary incompatibilities. Now when my application is started on the existing system, I get an undefined symbol
error, because OpenSSL is not loaded. Note that I don't have the option to load it through LD_PRELOAD
, because I cannot change the application that starts my update application.
I thought about loading OpenSSL through dlopen
hoping that the shared library would be able to use it. But the shared library uses OpenSSL in a C constructor (__attribute__((constructor (101))) void myConstructor()
) and even if I call dlopen
inside another constructor with higher priority, the dynamic loader already seems to have searched (and failed) for OpenSSL. My constructor is not even being executed.
LD_BIND_NOW
is not set, so I wonder why the undefined symbol
error occurs before my constructor is being called.
c shared-libraries dlopen
add a comment |
I am working on an update application that must be able to run on an existing system and is also started by another application on this existing system.
I am using a shared library that itself uses OpenSSL, but didn't link against it. Previously my update application linked against OpenSSL to work around this. But now I cannot link against OpenSSL any longer due to binary incompatibilities. Now when my application is started on the existing system, I get an undefined symbol
error, because OpenSSL is not loaded. Note that I don't have the option to load it through LD_PRELOAD
, because I cannot change the application that starts my update application.
I thought about loading OpenSSL through dlopen
hoping that the shared library would be able to use it. But the shared library uses OpenSSL in a C constructor (__attribute__((constructor (101))) void myConstructor()
) and even if I call dlopen
inside another constructor with higher priority, the dynamic loader already seems to have searched (and failed) for OpenSSL. My constructor is not even being executed.
LD_BIND_NOW
is not set, so I wonder why the undefined symbol
error occurs before my constructor is being called.
c shared-libraries dlopen
To the one who downvoted my question: Please leave a comment at least, so I can improve the question.
– Jan Schatz
Nov 16 '18 at 8:00
add a comment |
I am working on an update application that must be able to run on an existing system and is also started by another application on this existing system.
I am using a shared library that itself uses OpenSSL, but didn't link against it. Previously my update application linked against OpenSSL to work around this. But now I cannot link against OpenSSL any longer due to binary incompatibilities. Now when my application is started on the existing system, I get an undefined symbol
error, because OpenSSL is not loaded. Note that I don't have the option to load it through LD_PRELOAD
, because I cannot change the application that starts my update application.
I thought about loading OpenSSL through dlopen
hoping that the shared library would be able to use it. But the shared library uses OpenSSL in a C constructor (__attribute__((constructor (101))) void myConstructor()
) and even if I call dlopen
inside another constructor with higher priority, the dynamic loader already seems to have searched (and failed) for OpenSSL. My constructor is not even being executed.
LD_BIND_NOW
is not set, so I wonder why the undefined symbol
error occurs before my constructor is being called.
c shared-libraries dlopen
I am working on an update application that must be able to run on an existing system and is also started by another application on this existing system.
I am using a shared library that itself uses OpenSSL, but didn't link against it. Previously my update application linked against OpenSSL to work around this. But now I cannot link against OpenSSL any longer due to binary incompatibilities. Now when my application is started on the existing system, I get an undefined symbol
error, because OpenSSL is not loaded. Note that I don't have the option to load it through LD_PRELOAD
, because I cannot change the application that starts my update application.
I thought about loading OpenSSL through dlopen
hoping that the shared library would be able to use it. But the shared library uses OpenSSL in a C constructor (__attribute__((constructor (101))) void myConstructor()
) and even if I call dlopen
inside another constructor with higher priority, the dynamic loader already seems to have searched (and failed) for OpenSSL. My constructor is not even being executed.
LD_BIND_NOW
is not set, so I wonder why the undefined symbol
error occurs before my constructor is being called.
c shared-libraries dlopen
c shared-libraries dlopen
asked Nov 14 '18 at 15:21
Jan SchatzJan Schatz
7217
7217
To the one who downvoted my question: Please leave a comment at least, so I can improve the question.
– Jan Schatz
Nov 16 '18 at 8:00
add a comment |
To the one who downvoted my question: Please leave a comment at least, so I can improve the question.
– Jan Schatz
Nov 16 '18 at 8:00
To the one who downvoted my question: Please leave a comment at least, so I can improve the question.
– Jan Schatz
Nov 16 '18 at 8:00
To the one who downvoted my question: Please leave a comment at least, so I can improve the question.
– Jan Schatz
Nov 16 '18 at 8:00
add a comment |
1 Answer
1
active
oldest
votes
I found a solution myself.
The problem was that shared libraries are initialised (i.e. C constructors are being called) before the main application. You can see the order when you set the environment variable LD_DEBUG=libs
. So I created a shared library myself. I linked this fix library after the buggy library (-lbuggy -lfix
), because initialisation roughly (I don't really understand the rules.) takes place in reverse loading order.
Now I was able to load OpenSSL inside the C constructor of my fix library like this:
void *p = dlopen("libssl.so.1.0.0", RTLD_LAZY | RTLD_GLOBAL | RTLD_NODELETE);
if(p)
dlclose(p);
The flag RTLD_GLOBAL
assures that OpenSSL can also be used by other libraries.
The flag RTLD_NODELETE
assures that the library is not unloaded on dlclose
.
Note: When my update application runs on a newer system with OpenSSL 1.1 and a shared library that correctly links against OpenSSL, loading libssl.so.1.0.0
will fail silently, because the old OpenSSL version is not present on this system (embedded system, need to save disk space). If OpenSSL 1.0 was still present, this could be a problem.
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%2f53303474%2fload-shared-library-for-another-shared-library%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 found a solution myself.
The problem was that shared libraries are initialised (i.e. C constructors are being called) before the main application. You can see the order when you set the environment variable LD_DEBUG=libs
. So I created a shared library myself. I linked this fix library after the buggy library (-lbuggy -lfix
), because initialisation roughly (I don't really understand the rules.) takes place in reverse loading order.
Now I was able to load OpenSSL inside the C constructor of my fix library like this:
void *p = dlopen("libssl.so.1.0.0", RTLD_LAZY | RTLD_GLOBAL | RTLD_NODELETE);
if(p)
dlclose(p);
The flag RTLD_GLOBAL
assures that OpenSSL can also be used by other libraries.
The flag RTLD_NODELETE
assures that the library is not unloaded on dlclose
.
Note: When my update application runs on a newer system with OpenSSL 1.1 and a shared library that correctly links against OpenSSL, loading libssl.so.1.0.0
will fail silently, because the old OpenSSL version is not present on this system (embedded system, need to save disk space). If OpenSSL 1.0 was still present, this could be a problem.
add a comment |
I found a solution myself.
The problem was that shared libraries are initialised (i.e. C constructors are being called) before the main application. You can see the order when you set the environment variable LD_DEBUG=libs
. So I created a shared library myself. I linked this fix library after the buggy library (-lbuggy -lfix
), because initialisation roughly (I don't really understand the rules.) takes place in reverse loading order.
Now I was able to load OpenSSL inside the C constructor of my fix library like this:
void *p = dlopen("libssl.so.1.0.0", RTLD_LAZY | RTLD_GLOBAL | RTLD_NODELETE);
if(p)
dlclose(p);
The flag RTLD_GLOBAL
assures that OpenSSL can also be used by other libraries.
The flag RTLD_NODELETE
assures that the library is not unloaded on dlclose
.
Note: When my update application runs on a newer system with OpenSSL 1.1 and a shared library that correctly links against OpenSSL, loading libssl.so.1.0.0
will fail silently, because the old OpenSSL version is not present on this system (embedded system, need to save disk space). If OpenSSL 1.0 was still present, this could be a problem.
add a comment |
I found a solution myself.
The problem was that shared libraries are initialised (i.e. C constructors are being called) before the main application. You can see the order when you set the environment variable LD_DEBUG=libs
. So I created a shared library myself. I linked this fix library after the buggy library (-lbuggy -lfix
), because initialisation roughly (I don't really understand the rules.) takes place in reverse loading order.
Now I was able to load OpenSSL inside the C constructor of my fix library like this:
void *p = dlopen("libssl.so.1.0.0", RTLD_LAZY | RTLD_GLOBAL | RTLD_NODELETE);
if(p)
dlclose(p);
The flag RTLD_GLOBAL
assures that OpenSSL can also be used by other libraries.
The flag RTLD_NODELETE
assures that the library is not unloaded on dlclose
.
Note: When my update application runs on a newer system with OpenSSL 1.1 and a shared library that correctly links against OpenSSL, loading libssl.so.1.0.0
will fail silently, because the old OpenSSL version is not present on this system (embedded system, need to save disk space). If OpenSSL 1.0 was still present, this could be a problem.
I found a solution myself.
The problem was that shared libraries are initialised (i.e. C constructors are being called) before the main application. You can see the order when you set the environment variable LD_DEBUG=libs
. So I created a shared library myself. I linked this fix library after the buggy library (-lbuggy -lfix
), because initialisation roughly (I don't really understand the rules.) takes place in reverse loading order.
Now I was able to load OpenSSL inside the C constructor of my fix library like this:
void *p = dlopen("libssl.so.1.0.0", RTLD_LAZY | RTLD_GLOBAL | RTLD_NODELETE);
if(p)
dlclose(p);
The flag RTLD_GLOBAL
assures that OpenSSL can also be used by other libraries.
The flag RTLD_NODELETE
assures that the library is not unloaded on dlclose
.
Note: When my update application runs on a newer system with OpenSSL 1.1 and a shared library that correctly links against OpenSSL, loading libssl.so.1.0.0
will fail silently, because the old OpenSSL version is not present on this system (embedded system, need to save disk space). If OpenSSL 1.0 was still present, this could be a problem.
answered Nov 16 '18 at 8:16
Jan SchatzJan Schatz
7217
7217
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%2f53303474%2fload-shared-library-for-another-shared-library%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
To the one who downvoted my question: Please leave a comment at least, so I can improve the question.
– Jan Schatz
Nov 16 '18 at 8:00