- publishing free software manuals
Valgrind 3.3 - Advanced Debugging and Profiling for GNU/Linux applications
by J. Seward, N. Nethercote, J. Weidendorfer and the Valgrind Development Team
Paperback (6"x9"), 164 pages
ISBN 0954612051
RRP £12.95 ($19.95)

Get a printed copy>>>

4.2.1 A Simple Example

Supposing we want to wrap some function

int foo ( int x, int y ) { return x + y; }

A wrapper is a function of identical type, but with a special name which identifies it as the wrapper for ‘foo’. Wrappers need to include supporting macros from ‘valgrind.h’. Here is a simple wrapper which prints the arguments and return value:

#include <stdio.h>
#include "valgrind.h"
int I_WRAP_SONAME_FNNAME_ZU(NONE,foo)( int x, int y )
{
   int    result;
   OrigFn fn;
   VALGRIND_GET_ORIG_FN(fn);
   printf("foo's wrapper: args %d %d\n", x, y);
   CALL_FN_W_WW(result, fn, x,y);
   printf("foo's wrapper: result %d\n", result);
   return result;
}

To become active, the wrapper merely needs to be present in a text section somewhere in the same process' address space as the function it wraps, and for its ELF symbol name to be visible to Valgrind. In practice, this means either compiling to a ‘.o’ and linking it in, or compiling to a ‘.so’ and ‘LD_PRELOAD’ing it in. The latter is more convenient in that it doesn't require relinking.

All wrappers have approximately the above form. There are three crucial macros:

‘I_WRAP_SONAME_FNNAME_ZU’: this generates the real name of the wrapper. This is an encoded name which Valgrind notices when reading symbol table information. What it says is: I am the wrapper for any function named ‘foo’ which is found in an ELF shared object with an empty ("‘NONE’") soname field. The specification mechanism is powerful in that wildcards are allowed for both sonames and function names. The details are discussed below.

‘VALGRIND_GET_ORIG_FN’: once in the the wrapper, the first priority is to get hold of the address of the original (and any other supporting information needed). This is stored in a value of opaque type ‘OrigFn’. The information is acquired using ‘VALGRIND_GET_ORIG_FN’. It is crucial to make this macro call before calling any other wrapped function in the same thread.

‘CALL_FN_W_WW’: eventually we will want to call the function being wrapped. Calling it directly does not work, since that just gets us back to the wrapper and tends to kill the program in short order by stack overflow. Instead, the result lvalue, ‘OrigFn’ and arguments are handed to one of a family of macros of the form ‘CALL_FN_*’. These cause Valgrind to call the original and avoid recursion back to the wrapper.

ISBN 0954612051Valgrind 3.3 - Advanced Debugging and Profiling for GNU/Linux applicationsSee the print edition