I am trying to create a binding to the open() system function. I did this in the following lines.
I created a wrapper library with the following:
extern int mocked_open(const char* fn, int flags, va_list args); int open(const char* fn, int flags, ...) { int r = -1; va_list args; va_start(args, flags); r = mocked_open(fn, flags, args); va_end(args); return r; }
I will compile this in libwrapper.so, which I load with LD_PRELOAD.
The implementation of mocked_open() as follows (I use the CPPUtest framework):
int mocked_open(const char* fn, int flags, va_list args) { if (strncmp(fn, test_device_id, 11) == 0) { return mock().actualCall("open").returnValue().getIntValue(); } else { int r = -1; int (*my_open)(const char*, int, ...); void* fptr = dlsym(RTLD_NEXT, "open"); memcpy(&my_open, &fptr, sizeof(my_open)); if (flags & O_CREAT) { r = my_open(fn, flags, va_arg(args, mode_t)); } else { r = my_open(fn, flags); } return r; } }
test_device_id is a simple string ("test_device"), which I hope is not used elsewhere.
During tests, the executable fails with a segmentation error. I followed this up to the GCC profiling function, which wants to open / create a bunch of .gcda files and calls open() to do this.
After some debugging with strace (as suggested below), I found that the line r = my_open(fn, flags, va_arg(args, mode_t)); really is the culprit. It is called recursively, or so it seems: I see many calls to this line without returning a function. Then segfault. The file to be opened is the corresponding .gcda file (for profiling). In fact, segfault only happens when profiling is enabled.