Fjalar: A Dynamic Analysis Framework for C and C++ Programs

Programmer's Manual

Fjalar is a framework that facilitates the construction of dynamic analysis tools for programs written in C and C++. This document serves as a guide to building tools on top of the Fjalar framework.

Getting Started

Here are the relevant entries in the directory structure after you have un-tarred the Fjalar package (executables shown in bold): Fjalar is implemented as a tool on top of the Valgrind binary instrumentation framework, so that is why Valgrind's files dominate the directory structure. Fjalar and its tools are located in the valgrind-3/valgrind/fjalar sub-directory. The significance of all of these files will be explained in this document.

Creating Fjalar tools

To create a new tool:
  1. Create a sub-directory in the valgrind-3/valgrind/fjalar directory and place all of your tool's source files in there.
  2. Edit Makefile.am in valgrind-3/valgrind/fjalar to include all the .c files of your tool by adding them to the list of files assigned to the FJALAR_SOURCES_COMMON variable. (Feel free to tweak other variables in that file. For instance, you can adjust AM_CFLAGS_X86_LINUX to add optimizations to boost run-time performance. The default is to turn off all optimizations in order to ease debugging.)
  3. Run auto-everything.sh to create a new Makefile from your modified Makefile.am and re-compile everything. You only need to run auto-everything.sh whenever you make a change to Makefile.am. (Notice that directly editing Makefile and Makefile.in is probably futile because they are auto-generated from Makefile.am every time auto-everything.sh is run.) If you do not subsequently change Makefile.am, you can simply use make and make install to compile and install, respectively.
  4. At this point, you'll probably get some compilation error. In order for Fjalar to compile properly with your tool, your tool's source files will need to implement all of the functions listed in fjalar_tool.h. Include this header file in one of your tool's source files and define stubs for all of the functions (or just copy them from basic-tool.c). Hopefully your tool should compile properly now.
  5. If you've configured everything properly, you should be able to do make and make install in the valgrind-3/valgrind/fjalar directory to compile Fjalar and your tool. Running make creates two shared libraries vgpreload_fjalar.so and vgpreload_core.so, as well as a special fjalar file, which are dynamically-loaded by Valgrind during execution. Running make install moves those shared libraries into valgrind-3/valgrind/inst/lib/valgrind.
Programming tips for Fjalar tools:

Executing Fjalar tools

Here is the command for executing your tool:
valgrind-3/valgrind/inst/bin/valgrind --tool=fjalar <command-line args>
The actual executable is valgrind because Fjalar is implemented as a Valgrind tool (and your Fjalar tool is compiled together with Fjalar). This command can be fairly tedious to type, so you should probably make a shell script to alias it. The only mandatory command-line argument is the name of the target program (the program to analyze). Use --help as one of your arguments to view a list of command-line options.

In order for Fjalar to work, the target program must be compiled with DWARF2 debugging information (on an x86/Linux system). Look at basic-tool-test.c for a simple target program that exercises Fjalar's function entrance/exit tracking and array bounds checking features. First, compile it:

gcc -gdwarf-2 basic-tool-test.c -o basic-tool-test
(The -gdwarf-2 includes debugging information in the DWARF2 format.) Now you should be able to run Fjalar from this directory (assuming that you have successfully compiled and installed it) with the following command:
../../inst/bin/valgrind --tool=fjalar ./basic-tool-test
If all goes well, the tool should print out the name of each function during entrances and exits and the names of all variables visible at that point in execution (as well as array sizes, if relevant).

Here are some tips related to executing Fjalar tools:

Debugging Fjalar tools

If you run your tool with the --with-gdb option, Fjalar will pause in an infinite loop during initialization. You can then attach a symbolic debugger such as gdb to the running process in order to debug it:
  1. First start gdb with valgrind-3/valgrind/inst/lib/valgrind/x86-linux/fjalar as the target program (this is a bit counter-intuitive, but you need to run gdb on fjalar and NOT on valgrind).
  2. Now use the at command to attach gdb to the process that's stuck in the infinite loop. You can see its process ID enclosed in "==" next to the start-up banner (e.g., ==3839== ...), or simply ps for it.
      if (fjalar_with_gdb) {
        int x = 0;
        while (!x) {}
      }
    
  3. As shown in the code snippet above, Fjalar is stuck in an infinite loop because x is 0. Set x to a non-zero value, for instance by typing p x = 1, so that it can get out of the infinite loop.
  4. Now set whatever breakpoints and/or watchpoints you desire, and hit c to continue execution. You'll probably get a mysterious Segmentation fault shortly afterwards, but simply hit c to continue again, and things should work fine. Valgrind mucks around with signals, so some error messages sent to the debugger might not be accurate.
  5. You should now be able to debug as usual.

Fjalar command-line options

Fjalar provides a variety of command-line options to customize its behavior and the behavior of its tools. These options are all documented in the Kvasir section of the Daikon User Manual. To prevent duplication, these descriptions will not be repeated in this document. Kvasir is a value profiling tool built upon Fjalar, so many options in that section of the manual belong to Fjalar (some are Kvasir-specific, though). Useful sub-sections include ones that describe tracing only part of a program and pointer-type disambiguation, which are two ways of giving the user more control over run-time data structure traversals.
Philip Guo (pgbovine@mit.edu)
Last modified on March 21, 2006