Interceptors

I have been trying for several days with no success to set up some very basic logic with libc interceptors from compiler-rt/lib/interception as used in (most?) sanitizers. The logic is very simple: in my sanitizer “runtime” I have some counters that just record the number of calls to various libc functions that were intercepted.

The actual interceptors look like this:

void *simplesan_malloc(uptr sz) {
 ENSURE_SIMPLESAN_INITED();
 void *ret = REAL(malloc)(sz);
 simplesan_metadata.malloc_count += 1;
 return ret;
}

void simplesan_free(void *ptr) {
 simplesan_metadata.free_count += 1;
 REAL(free)(ptr);
}

INTERCEPTOR(void, free, void *ptr) {
 simplesan_free(ptr);
}

INTERCEPTOR(void*, malloc, uptr size) {
 return simplesan_malloc(size);
}

In my sanitizer runtime init function, I call INTERCEPT_FUNCTION(free) and INTERCEPT_FUNCTION(malloc). In the corresponding pass, I just insert a call to the sanitizer init function into the entry block of main. I’ve looked at the comments in the interception headers, and I’m certain that I’m doing things in the way that they are intended to be done. The only problem is, it isn’t working! I get all sorts of issues with, for example, the REAL macro not being able to see the definitions of malloc and free, and with a bit of tweaking, I can get past those errors, and compile a sanitizer that just causes an immediate segmentation fault when malloc or free is called in user code, even if I just leave the body of the relevant interceptor totally empty, and do not read or write through the resulting pointers (compiling with -O0 so they aren’t trivially eliminated).

I have tried just inserting the relevant code around calls to malloc and free in my pass, but that seems kind of unsatisfactory, because it only works properly as long as someone never links in any code that was compiled without the pass inserting the instrumentation.

Is there any more documentation or example code for the interceptor machinery than the comments in the interception header files? Or if anyone happens to have a simple working example lying around, I’d be thrilled to see it – it feels like I’ve hit a wall with this avenue of investigation!

Did you solve this?

@junwha0511 sort of… in the end, I just copied and pasted the source code of LeakSanitizer, and customized it as I needed. Looking at the code of the other sanitizers, it appears that that approach has been taken more than once before :confused:

For a component of the LLVM ecosystem that is so widely used, the sanitization infrastructure feels dangerously hacked-together and undocumented. It’s good that it works but that doesn’t really have any bearing on the lack of docs and examples.

Thank you for response!! I will try it…:joy: