在C中模拟库函数

时间:2015-04-23 12:14:34

标签: c testing linker mocking

我想模拟c lib的函数,例如malloc,而不会更改原始源文件(使用malloc的文件)。

我尝试包含头文件“mock.h”,如

#ifndef MOCK_H_
# define MOCK_H_
# ifdef MOCK_MODE

#  include <sys/types.h>

extern void *my_mock_malloc(size_t n);
void    *malloc(size_t n) __attribute__((weak, alias ("my_mock_malloc")));

# endif /* MOCK_MODE */
#endif /* !MOCK_H_ */

但它给了我一个错误

in file included from ...:
/usr/include/stdlib.h:466:14: error: ‘malloc’ aliased to undefined symbol ‘my_mock_malloc’
 extern void *malloc (size_t __size) __THROW __attribute_malloc__ __wur;

GCC alias to function outside of translation unit -AKA- is this even the right tool for the job?提供了部分解决方案:使用链接器我在符号上创建别名。我现在可以使用-Xlinker --defsym "malloc"="my_mock_malloc"进行编译。问题是我的所有.o文件都是使用此选项链接的,因此我使用的单元测试框架(check)受到模拟的影响(因此当我创建模拟函数时它接收的是SIGSEGV返回NULL)。

有没有办法在本地执行这样的符号别名,所以我可以让我的测试框架使用真正的malloc? Os有比这个更好的解决方案吗?

4 个答案:

答案 0 :(得分:2)

C语言的大多数实现都将libc的所有符号指定为 weak,,也就是说,您可以根据需要覆盖它们。试试看!您可以编写自己的名为malloc的函数,它会自动替换提供的库malloc。请查看您的平台文档,因为您需要为free替换实现更多功能(例如realloccallocmalloc等)完整。

答案 1 :(得分:1)

我找到了一个包含头文件mock.h的解决方案,如

#ifndef MOCK_H_
# define MOCK_H_
# ifdef MOCK_MODE

#  include <sys/types.h>

extern void *my_mock_malloc(size_t n);
#  define malloc(x) (my_mock_malloc(x))

# endif /* MOCK_MODE */
#endif /* !MOCK_H_ */

但我仍然对另一种解决方案感到好奇。

答案 2 :(得分:0)

你可以这样做:

#include <stdio.h>
#include <stdlib.h>

#define malloc my_malloc

void *my_malloc(size_t size) {
    printf ("Called my_malloc\n");
    return NULL;
}

int main(void) {
    char * array = malloc(100);
    return 0;
}

节目输出:

Called my_malloc

答案 3 :(得分:0)

虽然不是对你的问题的完整答案,你会发现CppUTest对于测试C代码非常有用,并且在其模拟功能中包含大多数malloc / free库,允许你控制malloc失败等等。它也非常适合调试内存分配问题,因为它使用调试分配器。

我发现框架文档有点缺乏细节和示例。

当我使用那个框架&#34;愤怒&#34;几年前,我发现有必要实现我自己的模拟strdup()函数,我在CppUTest源代码中做了。

https://cpputest.github.io/mocking_manual.html

我还添加了DeathHandler工具,以帮助在测试期间捕获和诊断段错误。