wolfcw / libfaketime

libfaketime modifies the system time for a single application
https://github.com/wolfcw/libfaketime
GNU General Public License v2.0
2.71k stars 325 forks source link

Work-around / fix libasan incompatibility #389

Closed psychon closed 2 years ago

psychon commented 2 years ago

This is my attempt at fixing #365. I cleaned up the proposed patch from there and actually simplified it a bit. I also added a unit test that would previously hang (deadlock in pthread_mutex_lock()) and now passes.

As requested, this adds a new define. I chose to call it FAIL_PRE_INIT_CALLS. I also had to enable it by default since otherwise the test would hang. I kind of expect this to be an unsatisfactory solutions. Please advice how to properly integrate this test (or whether it should just be deleted).

I did test that this makes the hang with both clang -fsanitize=address main.c and clang++ -fsanitize=address main.cpp go away (where main.c(pp) is just an empty main function). I also checked that without this changes, the resulting programs would hang under faketime.

Fixes #365

Edit: Also, I was lazy and just failed all calls before ftpl_init(), not only during ftpl_init(). That's different to the previous hacky patch.

wolfcw commented 2 years ago

Thanks, that looks simple and good so far. :-)

I'd suggest to also add FAIL_PRE_INIT_CALLS optionally to test/Makefile and adjust libmallocintercept.c accordingly, so the test does nothing / not hang when the new define is not set.

Unless we notice other resulting issues, it might be a good thing to enable it by default though.

psychon commented 2 years ago

I'd suggest to also add FAIL_PRE_INIT_CALLS optionally to test/Makefile

That means users have to edit two Makefiles (or use an env var), right? Fine with me. I'll push a commit doing that.

Unless we notice other resulting issues, it might be a good thing to enable it by default though.

The "old" code also managed to fake time before constructors were called. With my change, things now depend on I-dont-know-what and "early" calls would get no time (and nothing handles failures of clock_gettime). So... something "out there" might break.

I disabled it by default.

make check now prints lots of stuff like:

Called free() from libmallocintercept...FAIL_PRE_INIT_CALLS not defined, skipping poke_faketime() successfully

make clean test FAKETIME_COMPILE_CFLAGS=-DFAIL_PRE_INIT_CALLS does what it did before. (And I also fixed make clean to also delete libmallocintercept.so)