Load shared library for another shared library










-1















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.










share|improve this question






















  • 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















-1















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.










share|improve this question






















  • 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













-1












-1








-1








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.










share|improve this question














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






share|improve this question













share|improve this question











share|improve this question




share|improve this question










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

















  • 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












1 Answer
1






active

oldest

votes


















0














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.






share|improve this answer






















    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
    );



    );













    draft saved

    draft discarded


















    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









    0














    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.






    share|improve this answer



























      0














      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.






      share|improve this answer

























        0












        0








        0







        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.






        share|improve this answer













        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.







        share|improve this answer












        share|improve this answer



        share|improve this answer










        answered Nov 16 '18 at 8:16









        Jan SchatzJan Schatz

        7217




        7217





























            draft saved

            draft discarded
















































            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.




            draft saved


            draft discarded














            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





















































            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







            這個網誌中的熱門文章

            Barbados

            How to read a connectionString WITH PROVIDER in .NET Core?

            Node.js Script on GitHub Pages or Amazon S3