Chinaunix

标题: 请教setenv设置环境变量的问题,setenv之后,对当前程序不起作用? [打印本页]

作者: larace    时间: 2009-05-04 18:05
标题: 请教setenv设置环境变量的问题,setenv之后,对当前程序不起作用?
我测试的代码如下:
cat test.c
#include<stdio.h>
#include<stdlib.h>
void hi(void)
{
        printf("hi");
}

int main(void)
{
        char *p;
        setenv("LD_PRELOAD","./libmylib.so.1.0",1);
        p=getenv("LD_PRELOAD");
        printf("LD_PRELOAD:%s\n",p);
        //hi();
        printf("hello\n");
}


cat prog.c
#include <unistd.h>
#include <stdio.h>
#include <sys/types.h>
#include <stdlib.h>
/*
void _init()
{
    unsetenv("LD_PRELOAD");
    execl("./abc.sh","abc.sh","init",NULL);
}
*/
int printf(const char *s,...)
{
    unsetenv("LD_PRELOAD");
    execl("./abc.sh","abc.sh",s,NULL);
}

gcc test.c -o test
gcc -o prog.o -c prog.c -fPIC
gcc -shared -Wl,-soname,libmylib.so.1 -o libmylib.so.1.0 prog.o -nostartfiles

我的测试的结果:
当前环境变量里没有LD_PRELOAD,执行./test  发现printf没有替换。
然后 我export LD_PRELOAD="./libmylib.so.1.0" 之后,再次执行./test,printf就被替换成我的共享库里的printf了

为什么test.c里的 setenv("LD_PRELOAD","./libmylib.so.1.0",1); 没起作用呢?



还有一个问题,对于共享库中_init  用法,我不是太明白,当我把注释取消的时候,什么时候_init 起作用? 好像只要执行函数调用,这个_init 就会起作用,为什么啊?那块知识是介绍这块东西的?谢谢各位给执教一下

还有,test.c中,有两个printf,export LD_PRELOAD="./libmylib.so.1.0" 之后,只看到t.txt 中有LD_PRELOAD:%s,没有看到hello,这个是为什么啊?

谢谢指点一下!
作者: larace    时间: 2009-05-05 13:22
各位老大,出面给小弟指点一下啊
我在APUE书上也没找到解释,也许我没看懂吧,请各位帮帮忙啊 谢谢啦
作者: datacodebugs    时间: 2009-05-05 15:17
原帖由 larace 于 2009-5-4 18:05 发表
我测试的代码如下:
cat test.c
#include
#include
void hi(void)
{
        printf("hi");
}

int main(void)
{
        char *p;
        setenv("LD_PRELOAD","./libmylib.so.1.0",1);
       ...


你改变的是当前进程的环境变量。貌似本来你想改变的是他的父进程shell的环境变量,
目标错了嘛
作者: larace    时间: 2009-05-06 19:39
没太明白。
我在shell上export env之后,对我执行的程序有影响,因为这个环境变量传到程序里了
如果我在程序里执行setenv 之后,程序内的当前的环境变量不是也改了吗?getenv已经看到了,为什么再执行某个函数,这个环境变量没有起作用呢?
作者: datacodebugs    时间: 2009-05-07 18:38
shell 使用的是内置命令,而且修改是当前进程shell的环境变量;shell加载程序运行时,一般会复制shell的环境变量给那个进程,所以对那个进程来说会起作用
作者: datacodebugs    时间: 2009-05-08 07:00
LZ,你的信益积分怎会只有5分...


作者: sakulagi    时间: 2009-05-11 14:31
LZ,这个有个误解,就是LD_PRELOAD不是给进程自己用的,而是loader来使用的。你在进程中修改了自己进程的LD_PRELOAD,可是父进程(就是shell)并没有这个变量。所以ld.so根本就没有什么变化。

通常的做法是写一个脚本:

wrapper.sh:
export LD_PRELOAD=./libmylib.so.1.0
./test

而不是在进程里修改这个环境变量




欢迎光临 Chinaunix (http://bbs.chinaunix.net/) Powered by Discuz! X3.2