Logging
libgreat now logs what it's up to internally. Here's an example:
clarion% LD_PRELOAD=libgreat_c99.so uname Thu Mar 13 22:19:46 2008 libgreat_c99 GREAT_RANDOM_SEED INFO: Defaulting to 5489 Thu Mar 13 22:19:46 2008 libgreat_c99 GREAT_SUBSETS INFO: Registered subset: /./ Thu Mar 13 22:19:46 2008 libgreat_c99 stdio:memory:malloc DEFAULT Thu Mar 13 22:19:46 2008 libgreat_c99 stdio:memory:free DEFAULT Thu Mar 13 22:19:46 2008 libgreat_c99 stdio:memory:malloc [C99 7.20.3.3 P3] IB: Returning NULL zsh: segmentation fault LD_PRELOAD=libgreat_c99.so uname clarion*
Here we can see a few preliminary bits and pieces being initialised (such as seeding the PRNG for deciding when to cause failures to occur).
Then we see malloc() being called, and (randomly) defaulting to call the underlying system's malloc(). Likewise free() defaults, and then malloc() is called again. This time, malloc() decided to (randomly) return NULL. As for all interceptions, this behaviour is justified in the log message, quoting the section of the appropriate standard which permits that behaviour.
Unfortunately, NetBSD's uname doesn't seem too happy with that, and promptly segfaults.
The file to which logs are sent defaults to standard output. This may be set explicitly by way of $GREAT_LOG:
clarion% LD_PRELOAD=libgreat_c99.so GREAT_LOG=/dev/null cat zsh: segmentation fault LD_PRELOAD=libgreat_c99.so GREAT_LOG=/dev/null cat clarion*
You can see the guts behind logging at shared/log.h.