Resolving Nondeterminism Problems
Here are some problems with nondeterminism and stdout/stderr
that we've run into, and solutions we've used to address them.
- If the program contains
printfstatements tostderr, we make them write tostdoutinstead. One way to do this is add:#define STDERR STDOUTto the top of the program.
- If the program uses libraries or macros that write to stderr,
that's a problem that needs to be addressed case by case.
One example is
assert. Replace allassert(expr)withmyassert(expr)and add:int assert_fn(char * file, int line) { printf("%s: %i\n", file, line); exit(0); } #define myassert(EX) {(EX) || assert_fn(__FILE__, __LINE__);}to the program.
- If the program uses a random number generator, fixing the seed can make it deterministic.
- If the program uses dates or terminal ids or other information
that differs from run to run (e.g. date stamps),
we replace
printfstatements of such information withprintfstatements that print out deterministic placeholder strings. An example of doing this with a Java subject can be found in the non-deterministic Ant and JUnit test runner, sir_junit.tar.gz, provided under the Download Tools link. - If the program uses the executable file path or executable file
name to output messages then there can be problems when the two
executable files reside in different directories or when the names of
executable file differ. For example, you can have non-determinism when comparing
the outputs generated by the instrumented executable and non-instrumented
executable. This is because the name of the instrumented executable file
(foo.int.exe) differs from that of the non-instrumented executable (foo.exe).
One way to remove this problem is to change the
argv[0]inside theprintfstatements to some common name across all the versions like "Executable".