C 如何在共享库中使用popen()?

C 如何在共享库中使用popen()?,c,debian,shared-libraries,popen,preload,C,Debian,Shared Libraries,Popen,Preload,当尝试在共享库中使用popen()并通过LD_PRELOAD或/etc/LD.so.PRELOAD对其进行预加载时,进程会陷入无限循环,并显示错误消息,说明无法预加载共享库,或者系统只是冻结,需要重新启动,具体取决于代码 请注意,不作为共享库进行编译(gcc test.c;/a.out)将不会出错 如果有帮助,我将在VirtualBox上重新安装Debian: Linux debian 3.16.0-4-586#1 debian 3.16.36-1+deb8u2(2016-10-19)i686

当尝试在共享库中使用popen()并通过LD_PRELOAD或/etc/LD.so.PRELOAD对其进行预加载时,进程会陷入无限循环,并显示错误消息,说明无法预加载共享库,或者系统只是冻结,需要重新启动,具体取决于代码

请注意,不作为共享库进行编译(
gcc test.c;/a.out
)将不会出错

如果有帮助,我将在VirtualBox上重新安装Debian:

Linux debian 3.16.0-4-586#1 debian 3.16.36-1+deb8u2(2016-10-19)i686 GNU/Linux

好的,那么这个代码:

#define _GNU_SOURCE
#include <stdio.h>

__attribute__((constructor, visibility("hidden")))
void init()
{
    FILE *fp = popen("/usr/bin/id", "r");
    pclose(fp);
}
此代码:

...
#include <limits.h>
...
{
    FILE *fp = popen("/usr/bin/id", "r");

    if(!fp)
        puts("Error.\n");

    char buf[PATH_MAX];

    while(fgets(buf, sizeof buf, fp))
        printf("%s\n", buf);

    pclose(fp);    // Never gets here: VM just freezes.
}
。。。
#包括
...
{
文件*fp=popen(“/usr/bin/id”,“r”);
如果(!fp)
puts(“错误。\n”);
char buf[PATH_MAX];
而(fgets(buf、sizeof buf、fp))
printf(“%s\n”,buf);
pclose(fp);//永远不会到达这里:虚拟机只是冻结。
}
结果在第二种情况下(系统冻结)。我怀疑这是因为while循环没有结束,导致没有调用pclose(),因为第一个代码示例也将冻结没有pclose()的系统


任何帮助都将不胜感激。谢谢大家!

你不在这儿吗?
LD\u PRELOAD
中的构造函数将导致
/usr/bin/id
永远执行自身(因为每个新实例都会预加载库),很可能会停止机器。在弹出之前,您可能应该
unsetenv

我认为问题在于,在加载libc的其余部分之前,您的库已经被预加载,因此您不能在
init()
函数中调用这些函数。@Barmar如果他的
init()
函数链接到libc,那么加载libc会是预加载的一部分吗?OP我很确定您必须将
-shared-fPIC
放在.c文件之前。此外,您是否尝试过用一个简单的
printf
替换
init()的内容,这样您就可以推断它可能不是
popen()
中断?
-shared-fPIC
之前未更改输出。另外,是的,我尝试了
printf
和其他libc函数,效果很好。这是我的一个更大项目的一部分,在这个项目中,我连接libc和其他共享lib中的函数。这个
popen
代码是有问题的(这不是我的项目引起的问题)。谢谢你们的帮助!啊,老兄!非常感谢。这是有道理的。我不知道我是怎么忘记的。我已经想了好几天了。我觉得很傻。欢迎来到运行时工具世界;)
...
#include <limits.h>
...
{
    FILE *fp = popen("/usr/bin/id", "r");

    if(!fp)
        puts("Error.\n");

    char buf[PATH_MAX];

    while(fgets(buf, sizeof buf, fp))
        printf("%s\n", buf);

    pclose(fp);    // Never gets here: VM just freezes.
}