-
Notifications
You must be signed in to change notification settings - Fork 16
Reducing a regression between two D versions
Vladimir Panteleev edited this page Feb 8, 2019
·
6 revisions
Let's say you have a program that compiles and runs fine on one D version, but segfaults on another.
To start, you'll need to have both D versions installed at the same time. One easy and universal way to do it is to use dvm.
Install dvm and the two D versions. Note that if you have a system-wide install of D, it might conflict with your local ones (the linker may use libphobos2.a from /usr/lib/), so uninstall (or rename the library) if you run into any linking problems.
The test script should look something like this:
#!/bin/bash
# Enable the "errexit" mode, which will cause the shell interpreter to
# exit (with a non-zero status) as soon as any command fails (exits
# with non-zero status). Therefore, any command in this script which
# fails will cause DustMite to consider the reduction it's currently
# trying as not valid.
# This applies to building the D program (the compiler and build tool
# will exit with a non-zero status in case of failure), and running
# the built program (the D runtime will exit with a non-zero status in
# case of an uncaught exception, and the OS will show a non-zero
# status in case of termination by signal, such as a segmentation
# fault).
set -e
# Our test script will need to compile and run the program with both D
# versions. You can't use `dvm use` in a script (it won't affect the
# script's environment), so we'll source DVM's environment scripts
# instead.
source ~/.dvm/env/dmd-2.059
# Build the program with the old compiler version.
# Because -e is set, building is expected to succeed for DustMite to
# consider the current reduction successful.
rdmd --force --build-only program.d
# Run the built program. It is expected to succeed.
./program
# Now, activate the new compiler version.
source ~/.dvm/env/dmd-2.060
# Build the program again, this time with the new compiler version.
# Building and running is split up, to ensure the search is not
# side-tracked by a different segfault somewhere else (i.e. inside the
# compiler).
# As always, when using `rdmd`, don't forget to use `--force`,
# otherwise it may not detect that we're building the program with
# another compiler version.
rdmd --force --build-only program.d
# Run the program, and capture its exit code in a shell variable.
# Because in this example we are looking for specifically a
# segmentation fault, we want to check the exact exit code (rather
# than just checking that it's non-zero).
# Do so by first capturing it in a variable (the way it is done below
# is to make it compatible with the "errexit" mode set above).
status=0
./program || status=$?
# We can now check the captured exit code, and exit the test script
# the appropriate exit code, to tell Dustmite if we've seen the sought
# segfault in the second execution or not.
if [[ $status -eq 139 ]] ; then
exit 0 # Program built with new compiler segfaulted - good reduction
else
exit 1 # Program built with new compiler succeeded - bad reduction
fi