ExerciseThe following program
generates arbitrary hashes and prints them to the screen in an infinite
loop. It has been written in such a way that any changes to the
program are very likely to change the output - a scenario in which
debuggers become a very important tool. Your task is to use a
breakpoint to figure out the 49,791st hash value that will be
printed. (Hint: Don't worry too much about how the values are
generated, just find where the value to be printed is computed and use
the breakpoint expertise introduced above to find the answer)
import java.math.BigInteger;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
/**
* DebugHash provides an executable program to print arbitrary values to
* the screen in an infinite loop. It is written in such a way that code
* changes are very likely to change the output, and thus demonstrates the
* utility of debuggers to instrument code without modifying it.
*
*/
public class DebugHash {
/**
* Using a supplied seed value, compute arbitrary (but repeatable) values
* based upon an underlying hashing algorithm.
*
* @param seed - the seed used to determine the sequence of arbitrary values.
*/
private static void printArbitraryHashes(byte seed) {
MessageDigest md5 = null;
try {
md5 = MessageDigest.getInstance("MD5");
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
System.exit(-1);
}
byte[] last_hash = {seed};
while (true) {
md5.update(last_hash);
byte[] new_hash = md5.digest();
String hashString = getHashString(new_hash);
System.out.println(hashString);
last_hash = new_hash;
}
}
/**
* Translate a given byte array into a hexadecimal String represention of
* the given array.
*
* @param hash - the byte array to be translated.
* @return - the hexadecimal String representation.
*/
private static String getHashString(byte[] hash) {
return String.format("%032x", new BigInteger(1, hash));
}
/**
* Entry-point for this executable class.
*
* @param args - the command line parameters (unused by this program).
*/
public static void main(String[] args) {
byte seed = 0;
for (StackTraceElement element: Thread.currentThread().getStackTrace()) {
seed += element.getLineNumber();
}
printArbitraryHashes(seed);
}
}
Another challenge...
Exercise
For this exercise we'll emulate the process of dealing with a bug
report from a user. Download the following codebase:
http://subversion.assembla.com/svn/ee461l-debugginglab/trunk/
A user of this software has provided the following bug report:
The sorting algorithm throws exceptions when traversing through the array and when a null element is present in the array.
Your task is to work through the following steps to put this bug to
rest:
- Find a way to reliably reproduce the bugs.
- Write a jUnit test fixture (containing one or more tests as
appropriate) that fails because of these bugs and can be added to
the program's test suite.
- Use the debugger to track down the source of the bugs.
- Fix the code to remove the bugs.