6

I am trying to mock a function in C, mocking works fine when the function and its caller function are defined in different files. But when both functions (function itself and its caller) are defined in the same file, the mocked function does not get invoked.


Case 1 :

//test.c

#include <stdio.h>

/*mocked function*/
int __wrap_func() {
   printf("Mock function !!!\n"); 
}

/*caller function*/
int myTest() {
  return func();
}

int main() {
    myTest();
    return 0;
}

//file.c
#include<stdio.h>

/*function need to be mocked*/
int func() {
  printf("Original function !!!\n");
    }

Case 2 :

//test.c
#include <stdio.h>
extern int myTest();
/*mocked function*/
int __wrap_func() {
  printf("Mock function !!!\n");
}

int main() {
    myTest();
}
//file.c
#include<stdio.h>

/*function need to be mocked*/
int func() {
  printf("Original function !!!\n");
}

/*caller function*/
int myTest() {
  return func();
}

Code compilation command : gcc -Wl,--wrap=func test.c file.c

In Case 1 . Mock function !!!
In Case 2 . Original function !!!

In case 2, mocking function is not being invoked. I am looking for a solution where I can mock function even caller and called function are in same file.

4

3 回答 3

3

在 C 中使用以两个下划线开头的函数名是未定义的行为。

(在您的情况下,我怀疑函数名称__wrap_func修饰名称冲突,func但这是推测性的并且完全依赖于编译器。)

您应该考虑使用函数指针的解决方案。

于 2015-07-01T08:40:03.980 回答
1

使用--wrap=symbol链接器选项将导致未定义的符号被解析为__wrap_symbol. 在您的第一种情况下,func是未定义的符号,因此链接器将搜索__wrap_func并调用该函数。在您的第二种情况下,链接器发现myTest因为它是声明的extern。当myTest调用func它时,它在同一个翻译单元中,所以不要取消定义,它与 being 位于同一个文件中int func()。所以原始func版本是调用而不是包装版本。当调用者和被调用者在同一个文件以及不同文件中时,您的设计不适合使用模拟函数。我建议你使用这里解释的MACRO或技术。function pointer

于 2015-07-01T11:49:42.437 回答
1

你不能。

链接器文档中,

--wrap symbol 使用符号的包装函数。任何未定义的符号引用都将解析为 __wrap_symbol。对 __real_symbol 的任何未定义引用都将被解析为符号。这可用于为系统函数提供包装器。包装函数应称为 __wrap_symbol。如果它想调用系统函数,它应该调用__real_symbol。这是一个简单的例子:

void *
__wrap_malloc (int c)
{
  printf ("malloc called with %ld\n", c);
  return __real_malloc (c);
}

如果您使用 --wrap malloc 将其他代码与此文件链接,则所有对 malloc 的调用将改为调用函数 __wrap_malloc。__wrap_malloc 中对 __real_malloc 的调用将调用真正的 malloc 函数。您可能还希望提供一个 __real_malloc 函数,以便没有 --wrap 选项的链接会成功。

这是最重要的部分...

如果这样做,则不应将 __real_malloc 的定义与 __wrap_malloc 放在同一个文件中;如果你这样做了,汇编器可能会在链接器有机会将它包装到 malloc 之前解决调用。

于 2015-10-23T08:53:41.797 回答