简体   繁体   English

GCC Makefile定义

[英]GCC Makefile Define

I have some C code that I want to do some tests on. 我有一些要测试的C代码。 It uses malloc, calloc, and free through out the code. 它使用malloc,calloc和释放代码。 I want to change those functions to a custom function that internally calls the original function. 我想将这些功能更改为内部调用原始功能的自定义功能。 For example: 例如:

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

would become: 会成为:

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

where myMalloc is: myMalloc在哪里:

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

As you can see, myMalloc internally calls malloc. 如您所见,myMalloc在内部调用malloc。 It just does some extra stuff. 它只是做一些额外的东西。 I wanted to replace the usage of malloc through out the code with myMalloc. 我想用myMalloc替换整个代码中的malloc用法。 I have done this successfully by going through all the code and replacing malloc with myMalloc manually, but this is far from ideal. 我已经通过完成所有代码并将malloc手动替换为myMalloc来成功地做到了这一点,但这远非理想。 I will be replacing this code on a test only basis, thus the production code should contain only malloc calls. 我将仅在测试的基础上替换此代码,因此生产代码应仅包含malloc调用。 I realize I could also do this with a script, but wanted to just use a define statement in the Makefile: 我意识到我也可以使用脚本来执行此操作,但只想在Makefile中使用define语句:

-Dmalloc=myMalloc

But that also replaces malloc in the myMalloc function, which causes an infinite recursive situation. 但这也替换了myMalloc函数中的malloc,这会导致无限递归的情况。 I tried changing the malloc call in the myMalloc function to malloc_d, and added a second define to the Makefile. 我尝试将myMalloc函数中的malloc调用更改为malloc_d,并向Makefile添加了第二个定义。

-Dmalloc=myMalloc -Dmalloc_d=malloc

I was thinking that the first define would not replace the malloc_d (which it didn't) and that the second define would only change the malloc_d (which it didn't). 我在想,第一个定义不会替换malloc_d(它没有),而第二个定义只会更改malloc_d(它没有)。 I got the same recursive situation. 我有相同的递归情况。 Is there anyway to do this with Makefile defines? 无论如何,用Makefile定义可以做到这一点吗? Or are multipass pre-compile situations going to always mess this up? 还是多遍预编译的情况总是会搞砸呢?

UPDATE: 更新:

Ok, so I have started looking at the LD_PRELOAD option that has been pointed out. 好的,因此我已经开始查看已指出的LD_PRELOAD选项。 I thought I had a workable solution, however, I am still having trouble! 我以为我有一个可行的解决方案,但是,我仍然遇到麻烦! Here is what I did... 这是我做的...

  1. I moved myMalloc() and myFree() out of the main file and into its own file. 我将myMalloc()和myFree()从主文件移到了自己的文件中。 I then compiled it into a shared library using: gcc -shared -o libMyMalloc.so -fPIC myMalloc.c 然后,我使用以下命令将其编译到共享库中:gcc -shared -o libMyMalloc.so -fPIC myMalloc.c
  2. I then added the following 'dummy functions' to the main file: 然后,我在主文件中添加了以下“虚拟函数”:

    void* myMalloc(unsigned size) { void* ptr; void * myMalloc(unsigned size){void * ptr; return ptr; 返回ptr; } }

    void myFree(void* ptr) { } 无效的myFree(void * ptr){}

As you can see, they do nothing. 如您所见,它们什么也不做。

  1. I added the following defines to the make file: -Dmalloc=myMalloc \\ -Dfree=myFree 我在make文件中添加了以下定义:-Dmalloc = myMalloc \\ -Dfree = myFree
  2. I compiled the code and ran it against the libMyMalloc.so library I created: 我编译了代码,并针对创建的libMyMalloc.so库运行了该代码:

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

However, I am still not getting it to run with the myMalloc functions that are defined in the libMyMalloc.so file. 但是,我仍然无法使其与libMyMalloc.so文件中定义的myMalloc函数一起运行。

The simplest solution is to not call malloc directly in your code: If you choose a different name (say MALLOC ), it's trivial to switch to a custom allocator. 最简单的解决方案是不直接在代码中调用malloc :如果选择其他名称(例如MALLOC ),则切换到自定义分配器很简单。

Example code: 示例代码:

#ifndef MALLOC
#define MALLOC malloc
#endif

For test builds, you'd do -DMALLOC=myMalloc . 对于测试版本,可以使用-DMALLOC=myMalloc

It gets more complicated if for some reason you want keep the calls to malloc . 如果出于某种原因要保留对malloc的调用,它将变得更加复杂。 Then you'd have to add something like the following after all standard library headers have been included : 然后, 在包含所有标准库头之后,您必须添加以下内容:

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

You can call the standard library function by using parens, ie 您可以使用parens调用标准库函数,即

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

and enable it via -DUSE_MY_MALLOC . 并通过-DUSE_MY_MALLOC启用它。


Considering the additional requirements given in the comments, two approaches come to mind: 考虑到注释中给出的其他要求,想到了两种方法:

  • pre-process the generated source, textually replacing calls to malloc 预处理生成的源,以文本方式替换对malloc调用
  • intercept inclusion of stdlib.h (assuming that's where MATLAB gets its malloc declaration from) 拦截stdlib.h包含(假设这是MATLAB从中获取其malloc声明的位置)

Your own version of stdlib.h would look something like this: 您自己的stdlib.h版本看起来像这样:

#ifndef MY_STDLIB_H_
#define MY_STDLIB_H_

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

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

#endif

Then, you can conditionally add the directory where you've placed that file to the include path. 然后,您可以有条件地将放置该文件的目录添加到包含路径。 Also note that this is not a particularly robust solution, but it might work for you anyway. 还要注意,这不是一个特别健壮的解决方案,但是无论如何它可能对您有用。

You can use a pointer to a function. 您可以使用指向函数的指针。 In the normal case, make it point to malloc. 通常情况下,使其指向malloc。 In debugging mode, let it point to you function. 在调试模式下,让它指向您的功能。

In some h file: 在一些h文件中:

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

In one of you c files: 在你们其中的一个c文件中:

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

I found my solution and wanted to share. 我找到了解决方案,并希望分享。 Thank you to everyone that contributed and pointed me in the right direction. 感谢所有为我做出正确贡献的人。

I ended up creating my custom library code and compiling it into a shared library: 我最终创建了自定义库代码,并将其编译为共享库:

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

I then modified the makefile to use the shared library and globally define 'malloc' to my custom function name (which internally calls malloc()) to malloc_t, as well as calloc() and free(): 然后,我修改了makefile以使用共享库,并在自定义函数名称(内部调用malloc()),malloc_t以及calloc()和free()中全局定义了“ malloc”:

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

The defines changed all the function calls for me which were linked to the implementation in the shared library. 定义更改了对我所有与共享库中的实现链接的函数调用。 Because I am using a shared library (which is already compiled), I didn't have to worry about my makefile defines causing a recursive call situation in my custom functions. 因为我使用的是共享库(已编译),所以我不必担心我的makefile定义会在我的自定义函数中引起递归调用的情况。 With this usage, I can take any pre-generated C code from my other tools and observe the memory usage with these simple makefile changes and using my custom malloc trace library. 通过这种用法,我可以从其他工具中获取任何预先生成的C代码,并通过这些简单的makefile更改并使用我的自定义malloc跟踪库来观察内存使用情况。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM