Reputation: 183
I want to mock functions of the c lib such as malloc
without altering too much the original source file (the one that uses malloc).
I tried including a header file "mock.h" like
#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_ */
but it gives me an error
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? gives a partial solution: using the linker I create an alias on a symbol. I can now compile with -Xlinker --defsym "malloc"="my_mock_malloc"
. The problem is that all my .o
files are linked using this option and thus the unit testing framework I use (check) is affected by the mocking (and thus it receives is SIGSEGV when I make my mock function return NULL
).
Is there a way to perform such symbol aliasing locally, so I can make my tesing framework use the real malloc? Os is there a better solution than this one?
Upvotes: 2
Views: 2525
Reputation: 6120
Although not a full answer to your question, you will find that CppUTest is very useful for testing C code as well, and includes most of the malloc/free library in its mock capabilities, allowing you to control malloc failure and so on. It's also very good for debugging memory allocation issues since it uses a debug allocator.
I found that the framework documentation was however a little lacking in detail and examples.
When I used that framework "in anger" a couple of years ago, I found it necessary to implement my own mocked strdup() function, which I did within the CppUTest source.
https://cpputest.github.io/mocking_manual.html
I added the DeathHandler facility as well, to help capture and diagnose segfaults during test.
Upvotes: 0
Reputation: 93082
Most implementations of the C language specify all symbols of the libc as weak, that is, you can override them as needed. Try it out! You can write your own function named malloc
and it automatically replaces the library supplied malloc
. Have a look at your platforms documentation as there are a couple more functions (like free
, realloc
, calloc
, etc) that you need to implement for a malloc
replacement to be complete.
Upvotes: 3
Reputation: 34575
You could do it like this:
#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;
}
Program output:
Called my_malloc
Upvotes: 0
Reputation: 183
I found a solution which is to include a header file mock.h
like
#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_ */
but I am still curious about another solution.
Upvotes: 2