English 中文(简体)
Unit testing C library, memory management
原标题:

I am working on a quite large C library that doesn t have any tests now. As the API starts to be final, I d like to start writing unit tests.

Nearly all my functions acts on the first parameter (a structure).

The naive approach to unit test is to have the pre function call structure in a known state, call the function, and then compare the pre call structure with the expected result.

Now this works with structure composed of scalar types, but as for allocated memory, I was wondering what kind of approach you were using.

For example, imagine an image structure, when you do:

CreateImage(&img, x, y);

you expect the img->x to be x, img->y to be y and img->pixels to be a pointer to something big enough to hold x * y * sizeof(pixel).

Checking for the first two is trivial, but what about the img->pixels? I don t mean to check if the malloc call was successful, as I can overload malloc, but I want to know if malloc was called properly.

This is especially important in case like that:

CreateImage(*img, x, y)
{
    img->x = x; img->y = y;
    /* do something, dhoo, that something is broken and modify x or y */
    img->pixels = malloc(x * y * sizeof(pixel)); /* wrong allocation size */
    if(!img->pixels) error("no memory");
}

I hope my question is clear.

Thanks.

最佳回答

In your unit test, have your overloaded malloc function log the value that it was called with (eg. alloc_size).

Then just test that all of these are true:

  • alloc_size % sizeof(pixel) == 0
  • alloc_size % x == 0
  • alloc_size % y == 0
  • ((alloc_size / sizeof(pixel)) / x ) / y == 1

Do not just replicate the code from the function you re testing - ie. the multiplication - because you may end up replicating a bug.

In this case you would potentially replicate a bug - if there s no bounds tests on x and y, then the multiplication in the malloc call is itself buggy (consider what would happen on a system with a 32 bit size_t, sizeof(pixel) == 4, x == 40000 and y == 40000).

问题回答

You can overload malloc so as to set a number of expectations on it. Since you know before you make the call how much memory it needs to allocate you could something of the sort.

SetMallocExpectation(x * y * sizeof(pixel));
CreateImage(&img, x, y);
if ( InvalidMalloc() ) {
    // The malloc call was with a different size 
}
ResetMalloc();

As for the implementation I figure it d look something like this

size_t mallocExpectations[SOME_SIZE];
int mallocCur = 0;
int mallocError = 0;
int numExpectations = 0;

void* MyMalloc(size_t size) {

    if ( size != mallocExpectations[mallocCur++] ) {
        mallocError = 1;
    }

    return (*malloc)(size);
}

void SetMallocExpectation(size_t size) {
    mallocExpectations[numExpectations++] = size;
}

int InvalidMalloc() {
    return mallocError;
}

void ResetMalloc() {
    mallocCur = 0;
    mallocError = 0;
    curExpecations = 0;
}

Another idea is to try and fill the buffer created by malloc to maximal size, and then run your test suite with Valgrind. This should surface allocation problems. Running it with Valgrind is helpful for other things as well, such as detecting memory leaks.





相关问题
Fastest method for running a binary search on a file in C?

For example, let s say I want to find a particular word or number in a file. The contents are in sorted order (obviously). Since I want to run a binary search on the file, it seems like a real waste ...

Print possible strings created from a Number

Given a 10 digit Telephone Number, we have to print all possible strings created from that. The mapping of the numbers is the one as exactly on a phone s keypad. i.e. for 1,0-> No Letter for 2->...

Tips for debugging a made-for-linux application on windows?

I m trying to find the source of a bug I have found in an open-source application. I have managed to get a build up and running on my Windows machine, but I m having trouble finding the spot in the ...

Trying to split by two delimiters and it doesn t work - C

I wrote below code to readin line by line from stdin ex. city=Boston;city=New York;city=Chicago and then split each line by ; delimiter and print each record. Then in yet another loop I try to ...

Good, free, easy-to-use C graphics libraries? [closed]

I was wondering if there were any good free graphics libraries for C that are easy to use? It s for plotting 2d and 3d graphs and then saving to a file. It s on a Linux system and there s no gnuplot ...

Encoding, decoding an integer to a char array

Please note that this is not homework and i did search before starting this new thread. I got Store an int in a char array? I was looking for an answer but didn t get any satisfactory answer in the ...

热门标签