\section{Dynamic Analysis Tools}

Data races and invalid memory accesses are some of the most common and
difficult to debug errors that may occur in concurrent C code.
We developed dynamic analysis tools that run on top of the QEMU
system emulator~\cite{Bellard2005QEMU} to help detect these mistakes. 
Since these tools do not require additional support from the Pintos kernel; 
students can use them without complicating their code.

Data races are found by using a semaphore-aware modification of the RaceTrack algorithm~\cite{Yu2005RaceTrack}. 
Calls to Pintos's synchronization primitives are instrumented at runtime to track every thread's data
sharing pattern.  Meanwhile, every memory access records synchronization information to shadow memory
maintained by the analysis tool. When the synchronization information for a memory address
indicates that a data race occurred, a report including heap information for the data location and the
call stacks for the racing threads is generated.

Invalid memory accesses, such as a read from newly allocated but uninitialized data, are detected by
tracking all memory accesses.  Heap allocation calls are instrumented to map a range of addresses as
uninitialized. When data is written to a memory address, it is marked as initialized. If a address
marked as uninitialized is read from, the error is reported and the address is marked as
uninitialized to mask spurious reports. 
% More sophisticated analysis may be implemented in the future.

