LinuxSir.cn,穿越时空的Linuxsir!

 找回密码
 注册
搜索
热搜: shell linux mysql
查看: 1704|回复: 15

LD_PRELOAD为什么不起作用

[复制链接]
发表于 2006-4-14 15:55:34 | 显示全部楼层 |阅读模式
我自己创建了一个libmy.so.1.0.1共享连接库,主要功能是重定义了strlen这个函数

使用export LD_PRELOAD=./libmy.so.1.0.1后,用测试程序测试strlen发现没有调用我的strlen
可是用shell下输入ls后,又表现出调用了我的strlen程序,请问这是怎么回事,怎样才能让我的strlen在测试程序中生效

root:~# cat mystrlib.c
#include <stdio.h>
#include <dlfcn.h>
#include <stdlib.h>

int strlen(const char * s)
{
    void * handle;
    char * dl_error;

    int  orig_return;
    typedef int (*func_t) (const char *);
    func_t my_strlen;
    char *my_name="strlen";

    printf("using strlen here!\n");

    handle = dlopen("/lib/libc.so.6",RTLD_LAZY);
    if(!handle)exit(0);
    my_strlen=dlsym(handle,my_name);
    if((dl_error = dlerror()) != NULL)exit(0);
    orig_return =  my_strlen(s);

    return orig_return;
}
root:~# gcc -fPIC -rdynamic -g -c -Wall mystrlib.c
root:~# gcc -shared -WI,-soname,libmy.so.1 -o libmy.so.1.0.1 mystrlib.o -lc -ldl
root:~# cat test_lib.c
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
int main()
{
        char *a="isndfiasdf";
        int len;
        len = strlen(a);
        printf("The word '%s' len = %d\n",a,len);
        return 1;
}
root:~# gcc -g test_lib.c -o test_lib
root:~# ./test_lib
The word 'isndfiasdf' len = 10
root:~# export LD_PRELOAD=./libmy.so.1.0.1
root:~# ./test_lib
The word 'isndfiasdf' len = 10
root:~# ls
using strlen here!
using strlen here!
libmy.so.1.0.1  using strlen here!
mystrlib.c  using strlen here!
mystrlib.o  test_lib  using strlen here!
test_lib.c
root:~#
 楼主| 发表于 2006-4-15 13:17:53 | 显示全部楼层
没人知道么,请大大们给个线索啊

我又重定义了strcpy函数,方法类似上面的strlen,结果可以调用我的strcpy函数,难道strlen函数很特殊么,要怎样让我的strlen定义生效呢
回复 支持 反对

使用道具 举报

发表于 2006-4-15 17:03:12 | 显示全部楼层
换绝对路径试试
回复 支持 反对

使用道具 举报

 楼主| 发表于 2006-4-15 19:54:21 | 显示全部楼层
Post by zhllg
换绝对路径试试
还是不行!strcpy可以,但就是strlen不行
回复 支持 反对

使用道具 举报

发表于 2006-4-15 20:02:30 | 显示全部楼层
确实没有调用strlen
你可以编译成汇编看看,没有
call strlen
而是一段汇编代码
回复 支持 反对

使用道具 举报

 楼主| 发表于 2006-4-15 20:25:11 | 显示全部楼层
Post by zhllg
确实没有调用strlen
你可以编译成汇编看看,没有
call strlen
而是一段汇编代码
感谢zhllg

这样的话我想让我重定义的strlen生效,该用什么方法呢
回复 支持 反对

使用道具 举报

发表于 2006-4-15 21:12:08 | 显示全部楼层
Post by zhllg
确实没有调用strlen
你可以编译成汇编看看,没有
call strlen
而是一段汇编代码


如果根本没有调用strlen的话,难道被编译器优化掉了?待测的字符串是定义好的常量,换个运行时输入的变量试试看……
回复 支持 反对

使用道具 举报

 楼主| 发表于 2006-4-15 21:32:19 | 显示全部楼层
Post by yyccrasher
如果根本没有调用strlen的话,难道被编译器优化掉了?待测的字符串是定义好的常量,换个运行时输入的变量试试看……
还是不行,不过受楼上提醒,这个可能和编译器有关,编译器可能编译后直接把strlen替换成了汇编语言,有没有什么方法不让编译器这样优化
回复 支持 反对

使用道具 举报

发表于 2006-4-17 12:59:25 | 显示全部楼层
确实是被优化了,试试 -O0 编译选项
回复 支持 反对

使用道具 举报

 楼主| 发表于 2006-4-17 17:59:56 | 显示全部楼层
Post by rickxbx
确实是被优化了,试试 -O0 编译选项
还是不行,gcc默认就把它给优化了
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 注册

本版积分规则

快速回复 返回顶部 返回列表