Reputation: 12838
I want to extensively test some pieces of C code for memory leaks.
On my machine I have 4 Gb of RAM, so it's very unlikely for a dynamic memory allocation to fail. Still I want to see the comportment of the code if memory allocation fails, and see if the recover mechanism is "strong" enough.
What do you suggest ? How do I emulate an environment with lower memory specs ? How do i mock my tests ?
EDIT: I want my tests to be code independent. I only have "access" to return values for different functions in the library I am testing. I am not supposed to write "test logic" inside the code I am testing.
Upvotes: 4
Views: 3014
Reputation: 2500
If this is a unix -type of system, then you can do the same thing that jemalloc does. Implement your own malloc, compile it as .so -library and start the test with LD_PRELOAD=yourmalloc.so
You could build in a setting that will allow you to control how it operates:
void tester() {
your_malloc_allow_allocation(1024*1024*4); // allow 4 more megs of allocation
librarycall();
// ... handle errors..
your_malloc_reset_limits(); // drop limits
}
Upvotes: 3
Reputation: 24177
type in *(char*)0; when you want your code to fail or store it in allocated var
(obviously it should be activated/desactivated by some #define setted by makefile)
The idea is to precisely control which malloc you want to fail. I used the previous trick to ensure what would be the behavior of a program I wrote if a segfault ever occured. I was able to check that the exception was caught and that there was no memory leak with allready allocated object.
You can also add some kind of counter to make your alloc return 0 only after a while and check that your code corretly handle this case (and, for instance, correctly free parts of what your program choose to destroy to handle memory starvation).
Upvotes: 1
Reputation: 347296
Make a wrapper malloc and free, you can put your own logic there for when it fails and when it doesn't.
Then:
#define malloc(X) (myMalloc(X))
#define free(X) (myFree(X))
#define realloc(X, Y) (myRealloc(X, Y))
#define calloc(X, Y) (myCalloc(X, Y))
#define valloc(X) (myValloc(X))
You can #define
and #undef
the macros as you want throughout your code.
Upvotes: 7
Reputation: 224079
When I had to do this, I made a small program which used up all the memory quickly. Something like this:
// Beware, brain-compiled code ahead:
#include <stdlib.h>
bool alloc(size_t n)
{
return NULL != malloc(n);
}
int main()
{
size_t n = 1;
for(;;) {
while( alloc(n) )
n*=2;
do
n/=2;
while( !alloc(n) );
}
}
My experience with the NT line of Windows was that, while the OS was rock-solid, just about everything else crashed on me, including the debugger. No fun to work that way.
Upvotes: 1
Reputation: 43084
To do this code independently, I'd suggest using a virtual machine with a much smaller memory setting and running your code within that. Otherwise, you are left with testing on actual systems with smaller memory configurations.
Upvotes: 3
Reputation: 14069
disable swap, then at the beginning of your app do while(malloc(1000000));
This will leave the environment with less than 1MB of free memory for the rest of your app to run. Adjust the value for other results.
Upvotes: 0