Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/php/242.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ Linux共享库已加载两次_C++_Linux_Qt_Shared Libraries - Fatal编程技术网

C++ Linux共享库已加载两次

C++ Linux共享库已加载两次,c++,linux,qt,shared-libraries,C++,Linux,Qt,Shared Libraries,我有以下设置: 一个非常复杂的基于Qt+QML的应用程序 一个共享linux库,它还具有一些Qt功能 使用LD_预加载技巧将共享库注入到应用程序中。加载后,它启动一个TCP服务器,通过该服务器公开应用程序内部对象。目标是访问应用程序内部,而无需专门修改应用程序的源代码 我看到的奇怪的事情是共享库被加载了两次,我不明白为什么。由于库和应用程序都依赖于Qt,我理解Linux是否会加载同一Qt库的多个副本 但是应用程序不依赖于共享库,我也不重写应用程序本身的任何函数 我想知道: 如何防止共享库被加

我有以下设置:

  • 一个非常复杂的基于Qt+QML的应用程序
  • 一个共享linux库,它还具有一些Qt功能
使用LD_预加载技巧将共享库注入到应用程序中。加载后,它启动一个TCP服务器,通过该服务器公开应用程序内部对象。目标是访问应用程序内部,而无需专门修改应用程序的源代码

我看到的奇怪的事情是共享库被加载了两次,我不明白为什么。由于库和应用程序都依赖于Qt,我理解Linux是否会加载同一Qt库的多个副本

但是应用程序不依赖于共享库,我也不重写应用程序本身的任何函数

我想知道:

  • 如何防止共享库被加载两次(我曾考虑使用shell环境变量,但这似乎是一个丑陋的攻击)

  • 什么可能导致共享库被加载两次

  • 编辑 受雇的俄罗斯人(见下文)的评论引导我朝着正确的方向解决问题2。目标应用程序正在启动一个子进程,该进程将继承环境变量LD_PRELOAD。子进程是库被加载两次的原因

    至于问题#1,我也遵循了他的建议:库初始化函数只是取消环境变量LD#u PRELOAD的设置。因此,子进程不再重新加载库

    什么可能导致共享库被加载两次

    加载程序经过了很长的时间才不加载同一个共享库两次

    您很可能将代码链接到两个单独的共享库中,这就是造成所有混乱的原因


    设置
    LD_DEBUG=libs,files
    应该清楚地显示从哪个路径加载了哪些库。

    如何知道库被“加载”了两次?仅仅因为库中的“启动”代码可能会运行两次,并不意味着在目标的地址空间中必须有两个库副本。可能有,但不一定是这样。事实上,我的启动代码运行了两次,这就是为什么我认为库被加载了两次。在这个特殊的例子中,这看起来很奇怪,但是我不知道为什么启动函数会执行两次。库是用GCC编译的,我使用的是constructor属性。如果库被加载两次,那么它就不会在同一个地址加载。您可以检测到:将构造函数的地址转储到控制台。在第一次和第二次加载时应不同。如果它们相等,那么可能您的库被加载,然后卸载,然后再次加载-这是完全有效的,您应该优雅地处理它。库被加载两次。我通过转储库构造函数和析构函数的地址来确认这一点。但是我仍然不明白为什么注入了LD_预加载的库会出现这种情况。我认为这可能是因为目标应用程序正在派生一个新进程,该进程将继承父级环境。但是strac'ing应用程序并没有显示任何分叉系统调用。@在这里,应用程序链接到Qt库,并且应用程序中注入的共享库也链接到Qt库。这就是你的意思吗?如果是这样,我希望只加载Qt库,而不是注入库本身。@ngoncalves不,这不是我的意思。请重新阅读答案。@u俄语,共享库和应用程序之间没有通用代码,两者的构建过程完全独立。然而,调试表明了原因:应用程序正在启动一个进程,然后加载共享库。我想这是因为进程继承了父环境variables@ngoncalves是的,
    LD_PRELOAD
    由子进程继承。您可以在创建子项之前从应用程序中取消设置它。我不能。使用LD_PRELOAD的目的是允许我检查应用程序(用于测试目的),而不需要实际更改应用程序源代码。在我添加了防止多次加载库的保护措施之后,所有的工作都如期进行。