Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/linux/25.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
在Linux中重写malloc、free和calloc会导致递归_C_Linux_Recursion_Memory Management_Malloc - Fatal编程技术网

在Linux中重写malloc、free和calloc会导致递归

在Linux中重写malloc、free和calloc会导致递归,c,linux,recursion,memory-management,malloc,C,Linux,Recursion,Memory Management,Malloc,我已经覆盖了Linux平台中的malloc、calloc和free函数,如下所示: #include <stdio.h> #include <dlfcn.h> #include <stdlib.h> typedef void* (*MALLOCFN)(size_t); typedef void* (*CALLOCFN)(size_t, size_t); typedef void* (*CALLOCFN)(size_t, size_t); typedef voi

我已经覆盖了Linux平台中的
malloc
calloc
free
函数,如下所示:

#include <stdio.h>
#include <dlfcn.h>
#include <stdlib.h>
typedef void* (*MALLOCFN)(size_t);
typedef void* (*CALLOCFN)(size_t, size_t);
typedef void* (*CALLOCFN)(size_t, size_t);
typedef void (*FREEFN)(void *);
MALLOCFN real_malloc = (MALLOCFN) 0;
CALLOCFN real_calloc = (CALLOCFN) 0;
FREEFN real_free = (FREEFN) 0;
void *get_realfn(const char *fnm)
{
  void *pfunc = (void *) NULL;
  printf("searching for original %s\n", fnm);
  pfunc = dlsym(RTLD_NEXT, fnm);
  if (pfunc) printf("found original %s\n", fnm);
  else printf("not found original %s\n", fnm);
  return pfunc;
}
void *malloc(size_t s)
{
  printf("called malloc\n");
  if(real_malloc == NULL) real_malloc = (MALLOCFN) get_realfn("malloc");
  if (real_malloc) return real_malloc(s);
  else return NULL;
}
void *calloc(size_t s1, size_t s2)
{
  printf("called calloc\n");
  if(real_calloc == NULL) real_calloc = (CALLOCFN) get_realfn("calloc");
  if (real_calloc) return real_calloc(s1, s2);
  else return NULL;
}
void free (void * ptr)
{
  printf("called free\n");
  if(real_free == NULL) real_free = (FREEFN) get_realfn("free");
  if (real_free) real_free(ptr);
}
int main()
{
  char * c1 = (char *) malloc(400);
  char * c2 = (char *) malloc(400);
  free(c2); free(c1);
  return 0;
}
输出的前几行如下所示,它进入无限递归并崩溃:

called malloc
searching for original malloc
called free
searching for original free
called free
searching for original free
called free
searching for original free
called free
searching for original free
called free
. . . .

请建议如何避免递归

printf
函数可以分配内存。因此,当您在未指定“实”函数指针之前调用
printf
时,它会进入插入函数,从而导致无限递归。因此,不要在插入函数中使用
printf
语句

#include <sys/syscall.h>

...

syscall(SYS_write, STDOUT_FILENO, "searching for original\n",
                                  sizeof "searching for original\n" - 1);
如果确实需要打印某些内容,请使用
syscall(2)
,这将绕过stdio库函数

#include <sys/syscall.h>

...

syscall(SYS_write, STDOUT_FILENO, "searching for original\n",
                                  sizeof "searching for original\n" - 1);
#包括
...
syscall(SYS\u write,STDOUT\u FILENO,“搜索原始文件”,
sizeof“搜索原始\n”-1);

gcc,wrap选项。为什么要麻烦使用
syscall(SYS\u write…)
?只需使用
write()
。可能吧。我想是习惯。这样更好,dlsym会导致调用malloc或calloc吗?我的调试器显示了从malloc到最终dlsym然后到calloc的调用,导致无限递归,我可以避免从dlsym调用重写的malloc/calloc吗?
dlsym
不会分配,除非失败(当前的glibc实现)。所以是的,这是可能的。如果您想使其安全,可能需要为dlsym提供单独的分配器。查看一些现有库(如TCmalloc、Jemalloc等)了解它是如何实现的。似乎dlsym正在失败,如何让dlsym驱动器不陷入这种麻烦?