Creating high-quality software without the proper tools is cumbersome. This article concentrates on memory debugging on Linux for System z using the dynamic program analysis framework, Valgrind. A proven technology, Valgrind has been used successfully for more than 10 years on multiple platforms, and is used by developers of the Firefox Web browser and Linux desktop GNOME. The Valgrind package is available under the GNU Public License (GPL). It’s been available for Linux on System z since November 2011.
Program Analysis Overview
Software development today is a thorough, mature process, developed through decades of computer programming. No matter what methodology you apply, whether an integrated approach such as the Rational Unified Process, or a more informal approach based on Agile Development principles, the process of creating a large application is still error-prone and difficult to manage. After the program code is created, a test phase must ensure the program works as specified. Program errors that creep into a production environment may generate application outages or, worse, they may allow malicious exploitation of a software vulnerability.
Program analysis is the process of automatically analyzing computer program behavior to ensure its correctness and find areas that could be optimized. Our focus is on memory debugging, so a short recap on the C memory model is in order. Program code and (non-constant) data are separated; there are three data areas:
• Static/global contains variables available for the lifetime of the program.
• Stack contains information about routine linkage and local variables available for the duration of a function.
• Heap is allocated and freed on behalf of the program; the lifetime is beyond function lifetime.
The main approaches in program analysis are static and dynamic program analysis. Static analysis operates on a static representation of the program (source code) and considers all possible behavior. As no program executable is used during static analysis, it may have already been applied in the implementation phase.
The first stop for syntactic and semantic analysis is the compiler. Make it a habit to use gcc with warning option “-Wall” to catch most common programming errors. For additional checks not covered by “-Wall,” see the gcc compiler description.
Splint (Secure Programming Lint) is a standard programming tool for statically checking C programs; it’s based on Lint, the ancestor of all static code checkers on UNIX. To exploit the full value of Splint, the program must be augmented with annotations that document assumptions on variables, functions, and parameters.
Dynamic program analysis analyzes only the observed behavior (i.e., the test case applied must provoke the error so it can be detected). Besides program debugging, dynamic program analysis can deliver profiling data for program optimization.
Both methods reveal programming errors such as: