GCC Makefile定义

时间:2014-09-17 16:54:06

标签: c gcc makefile

我有一些C代码,我想做一些测试。它使用malloc,calloc,并通过代码免费。我想将这些函数更改为内部调用原始函数的自定义函数。例如:

emxArray->size = (int *)malloc((unsigned int)(sizeof(int) * numDimensions));

会变成:

emxArray->size = (int *)myMalloc((unsigned int)(sizeof(int) * numDimensions));

myMalloc在哪里:

void* myMalloc(unsigned size)
{
    if (size < 8)
    {
        //printf("*** Bumped from %d....\n", size);
        size = 8;
    }
    allocated += size;
    return malloc(size);
}

如您所见,myMalloc在内部调用malloc。它只是做了一些额外的事情。我想用myMalloc替换代码中的malloc的用法。我通过遍历所有代码并手动用myMalloc替换malloc来成功完成此操作,但这远非理想。我将仅在测试的基础上替换此代码,因此生产代码应仅包含malloc调用。我意识到我也可以用脚本来做这个,但是想在Makefile中使用一个define语句:

-Dmalloc=myMalloc

但是这也取代了myMalloc函数中的malloc,这会导致无限的递归情况。我尝试将myMalloc函数中的malloc调用更改为malloc_d,并向Makefile添加了第二个定义。

-Dmalloc=myMalloc -Dmalloc_d=malloc

我认为第一个定义不会替换malloc_d(它没有),而第二个定义只会改变malloc_d(它没有)。我得到了同样的递归情况。无论如何使用Makefile定义吗?或者多通道预编译情况总会搞砸了?

更新

好的,所以我开始查看已经指出的LD_PRELOAD选项。我以为我有一个可行的解决方案,但是,我仍然遇到麻烦!这就是我做的......

  1. 我将myMalloc()和myFree()移出主文件并进入自己的文件。然后我使用以下方法将其编译为共享库: gcc -shared -o libMyMalloc.so -fPIC myMalloc.c
  2. 然后我将以下'虚拟函数'添加到主文件中:

    void * myMalloc(无符号大小) {   void * ptr;   返回ptr; }

    void myFree(void * ptr) { }

  3. 如您所见,他们什么都不做。

    1. 我在make文件中添加了以下定义: -Dmalloc = myMalloc \ -Dfree = myFree
    2. 我编译了代码并针对我创建的libMyMalloc.so库运行它:

      LD_PRELOAD = / home / rad / Desktop / myMalloc / libMyMalloc.so ./testRegress

    3. 但是,我仍然没有使用libMyMalloc.so文件中定义的myMalloc函数运行它。

3 个答案:

答案 0 :(得分:2)

最简单的解决方案是不要直接在代码中调用malloc:如果您选择其他名称(例如MALLOC),则切换到自定义分配器是微不足道的。

示例代码:

#ifndef MALLOC
#define MALLOC malloc
#endif

对于测试版本,您需要-DMALLOC=myMalloc

如果由于某种原因你想要保持对malloc的调用,它会变得更复杂。然后,在包含所有标准库标题之后,您必须添加类似以下的内容

#ifdef USE_MY_MALLOC
#undef malloc
#define malloc(SIZE) myMalloc(SIZE)
#endif

您可以使用parens调用标准库函数,即

void* myMalloc(unsigned size)
{
    ...
    return (malloc)(size);
}

并通过-DUSE_MY_MALLOC启用它。


考虑到评论中给出的额外要求,我们会想到两种方法:

  • 预处理生成的源,以文本方式替换对malloc
  • 的调用
  • 拦截stdlib.h的包含(假设MATLAB从其中获取malloc声明)

您自己的stdlib.h版本看起来像这样:

#ifndef MY_STDLIB_H_
#define MY_STDLIB_H_

#include "/usr/include/stdlib.h"

#undef malloc
#define malloc(SIZE) myMalloc(SIZE)

#endif

然后,您可以有条件地将您放置该文件的目录添加到包含路径。另请注意,这不是一个特别强大的解决方案,但无论如何它可能对您有用。

答案 1 :(得分:0)

您可以使用指向函数的指针。在正常情况下,使其指向malloc。在调试模式下,让它指向你的功能。

在某个h文件中:

extern void *(*myMalloc)(size_t size);

在你的一个c文件中:

#ifdef DEBUG
void *(*myMalloc)(size_t size) = dMalloc;
#else
void *(*myMalloc)(size_t size) = malloc; // derived from libc
#endif

答案 2 :(得分:0)

我找到了解决方案并想分享。感谢所有贡献并为我指明正确方向的人。

我最终创建了自定义库代码并将其编译为共享库:

gcc -shared -o libtmalloc.so -fPIC tmalloc.c

然后我修改了makefile以使用共享库并全局定义'malloc'到我的自定义函数名(内部调用malloc())到malloc_t,以及calloc()和free():

gcc -L/home/path/to/mallocTrace -Wall -o test test.c lib/coder/*.c -lm -ltmalloc \
-Dmalloc=malloc_t \
-Dcalloc=calloc_t \
-Dfree=free_t

这些定义更改了我链接到共享库中的实现的所有函数调用。因为我使用的是共享库(已经编译过),所以我不必担心我的makefile定义导致我的自定义函数中的递归调用情况。有了这种用法,我可以从我的其他工具中获取任何预生成的C代码,并通过这些简单的makefile更改和使用我的自定义malloc跟踪库来观察内存使用情况。