Skip to content

Reducing a bug with a specific compiler option

Vladimir Panteleev edited this page Feb 8, 2019 · 3 revisions

Let's say you have a program that compiles and runs fine when built with some compiler options, but crashes with others.

One common case of this is when enabling optimizations (-O) or inlining (-inline). Programs should behave identically whether or not these options were present (differing only in execution speed), but bugs in the compiler's inliner or optimization passes might generate wrong code in some cases.

The steps are very similar to Reducing a regression between two D versions, except we will be invoking the same compiler with different options instead of two different compiler versions.

To reduce the bug, our test script will need to compile and run the program with and without the problematic option.

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

# Build the program without optimizations.
# 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

# Build the program again, but this time with optimizations.
# Replace -O below with the switch which causes the problem in your
# case, if needed.

# 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 set of compiler options.

rdmd --force --build-only -O program.d

# This time, we expect that the program (when built with
# optimizations) will fail, so check for that explicitly, and exit the
# script with the appropriate exit code.

if ./program
then
    exit 1 # Program with optimizations succeeded - bad reduction
else
    exit 0 # Program with optimizations failed - good reduction
fi