LinuxSir.cn,穿越时空的Linuxsir!

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

请教,关于动态加载的动态分配函数

[复制链接]
发表于 2004-6-4 14:31:13 | 显示全部楼层 |阅读模式
下面的代码,编译连接都通过,运行时说时断错误,segmentation fault
????



源代码:
#include <dlfcn.h>
#include <stdlib.h>
#include <stdio.h>

static void *(*libc_malloc) (size_t)=0;

static void (*libc_free) (void *)=0;
static void load_libc ()
{
  void *handle;
  const char *err;
  char *libcname;

  libcname = "/lib/libc.so.6";

  handle = dlopen (libcname, RTLD_NOW);
  if ((err = dlerror ()))
    {
            /*
      printf ("*** wrapper can not open `");
      printf (libcname);
      printf ("'!\n");
      printf ("*** dlerror() reports: ");
      printf (err);
      printf ("\n");  */
      exit (1);
    }

  libc_malloc = (void *(*)(size_t)) dlsym (handle, "malloc");
  if ((err = dlerror ()))
    {

      printf ("***  does not find malloc in `libc.so'!\n");

      exit(1);
    }

  libc_free = (void (*)(void *)) dlsym (handle, "free");
  if ((err = dlerror ()))
    {
      printf ("***  does not find free in `libc.so'!\n");
      exit (1);
    }
}

void * malloc (size_t n)
{
        return (*libc_malloc)(n);
}

void free (void* p)
{
        return (*libc_free)(p);
}

int main()
{     
        load_libc();
        char * m =(char*) malloc(2);
.....
        free(m);
......
}
 楼主| 发表于 2004-6-4 14:55:56 | 显示全部楼层
我知道问题出在改写的两个函数
void * malloc(size_t);
void free(void *);

不明白为什么出错,???
是不是不能改写这写函数
发表于 2004-6-4 15:41:15 | 显示全部楼层
你确定libc_malloc和lib_free不为空?
 楼主| 发表于 2004-6-7 09:12:02 | 显示全部楼层
是的,不为空.

在注释掉改写的malloc(),free()后,
可以用libc_malloc,libc_free分配.释放内存空间的,
也可以 用libc_malloc分配,用free()释放,反之也可以.
发表于 2004-6-8 00:41:29 | 显示全部楼层
你还是gdb调试看看吧。我试的结果是在handle = dlopen(libcname, RTLD_NOW);这一句段错误。
为什么会这样我也不太明白。
发表于 2004-6-8 01:39:44 | 显示全部楼层
上一帖说到dlopen("/lib/libc.so.6", RTLD_NOW)导致段错误。后来发现把自定义的malloc和free和调用都改成malloc2和free2,就没有问题了。
尝试静态连接的时候系统提示:
$ gcc -g -o mem mem.c -ldl -static
/tmp/ccefwwhM.o(.text+0x1d): In function `load_libc':
/tmp/mem.c:16: Using 'dlopen' in statically linked applications requires at runtime the shared libraries from the glibc version used for linking
所以我认为是dlopen需要使用到malloc和free这两个函数,而恰好你自定义函数和c库函数重名,所以dlopen就重定向到自定义malloc和free函数,而libc_malloc和libc_free这时尚未初始化,结果导致segmentation fault。
于是我就在自定义malloc中下了断点,结果发现自定义malloc果然被dlopen()调用到。终于真相大白了。
结论就是:千万千万不要重定义系统库函数,否则会死的很难看。
 楼主| 发表于 2004-6-8 16:03:03 | 显示全部楼层

谢谢了!

终于明白了,!
感谢!
您需要登录后才可以回帖 登录 | 注册

本版积分规则

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