In my recent article "Bad software quality: Using IBM Rational PurifyPlus to avoid development problems," I managed to exclude a growing and vital portion of the software development community: Linux users. I intend to make it up to these users here.
Linux is, in my opinion, one of the "unsung heros" of modern software development. It has evolved from a novelty platform into a very powerful environment from which to work for very little starting cost. When I first started writing software, to have a Sparc5 on your desk (yes, this is a nod to all the old-time Sun users out there) meant you had a "real job," because your company thought you were important enough to outlay actual funds for a high-powered UNIXÂ® development machine. For the money that you'll pay for a proprietary UNIX machine today, you can outfit your shop with a significant number of Linux machines, each almost as powerful as the brand-name machine you would have purchased, if not more so. Lots of third-party companies market very stable versions of Linux, so you don't have to worry about updates and support for the platform -- all you need to do is install, configure, and start coding!
In short, Linux is a viable platform, one that IBM fully supports. In my continuing effort to underscore the value of software quality throughout your software development projects, I offer this article to introduce you to IBMÂ® RationalÂ® PurifyÂ® for Linux, part of the IBMÂ® RationalÂ® PurifyPlusÂ® toolset for Linux and UNIX. I'm not going to bore you with why you should use Purify, because you probably already know why (especially if you read my recent article). Instead, let's look at a couple of examples of Purify in action in a Linux environment.
Editor's Note: This article uses PurifyPlus for UNIX and Linux Version 2003.06.12 and is based on the Red Hat 2.4.20-28.8 version of Linux. Make sure to check your release notes for the most up-to-date product changes. At this time, PurifyPlus for Linux doesn't support JavaÂ® or the LD_PRELOAD environment variable.
Before we delve into something meaty for Purify to tackle, let's see it in action on a very simple C program. The analysis of our sample program will do two things: (1) make sure that we've installed Purify correctly on our Linux machine, and (2) illustrate the point that even small, simple programs are prone to errors and may need to be fixed.
Listing 1 is our sample program, conv.c, a Fahrenheit-to-Celsius conversion program written in C that's been slightly modified from one supplied by Kernighan and Ritchie in The C Programming Language.
|Listing 1: A simple Fahrenheit-to-Celsius conversion program, conv.c|
To analyze this program using Purify, there are a couple of things that you need to do. You're required to give Purify the names of the compiler you want to use and the program you'd like to analyze, in this form on the command line:
purify <name of compiler> <name of program>
Here's how the command line would look for the program in Listing 1:
purify gcc conv.c
You can also see this in Figure 1.
|Figure 1: Running conv.c with the gcc compiler and Rational Purify|
Incidentally, Rational PurifyPlus for Linux and UNIX works only with specific compilers. For the Red Hat 2.4.20-28.8 version of Linux, they're as follows:
- gcc 2.96-112
- gcc 3.2-7
- gcc 3.2.2
- gcc 3.2.3 (only tested on RHEL 3.0)
- gcc 3.3.1
- gcc 3.3.2
Check the release notes for Purify to be sure your program will compile properly.
As the program compiles, you'll see that Purify is instrumenting the source code, as well as linking to the executable. When the program has finished compiling, you'll need to run the executable to see the results. While the results are being displayed (in this example) on the command line (Figure 2), the Purify window appears on the screen to show the results (Figure 3).
|Figure 2: Results of the initial run displayed on the command line|
|Figure 3: Results of the initial run displayed on the command line|
When the Purify window appears on your screen, you'll notice that it looks very similar to the main Purify display in the Windows version of the product. A listing of errors that Purify has found in the program is displayed, as well as all of the memory leaks detected during runtime.
If you're accessing your Linux machine remotely, make sure that your Xserver is running and the Xwindows settings are properly set, so that remote windows can be displayed on your local desktop (most third-party packages have easy-to-use Xserver programs -- if not, please consult with your IT organization). Otherwise, you won't see the Xwindow displayed by Purify.
To take a closer look at the errors and leaks detected, expand the corresponding menu item, as shown in Figure 4. Purify will show you exactly where the problems in the program reside.
|Figure 4: Detailed view of the problems found in the conv.c program|
If you need assistance in determining how to resolve an error message, select the error (in Figure 4, "UMR: Uninitialized memory read") and then click the question mark icon. You'll get helpful information on fixing the problem. You can also go to the Actions menu, as shown in Figure 5, and select Explain message.
|Figure 5: Items on the Actions menu|
The resulting explanation of the UMR error message is shown in Figure 6.
|Figure 6: Explanation of the UMR error message|
Using help, you can determine that to fix the problems with our sample program identified by Purify, you'll need to do the following:
- Remove the offending
celsiusvariable assignment line, which uses the lower variable before it's been defined. (You could also move the
celsiusassignment to a location after the
lowervariable has been defined, but it's not really needed.) This fixes the UMR that Purify found in its analysis.
- Free the memory allocated with the
fahrvariable, by adding a call to the
freefunction. This fixes the memory leak, or MLK, that Purify found.
After fixing the problems, run Purify again to ensure that all of the issues in the sample program have been cleaned up. You'll see the results displayed in the Purify window as shown in Figure 7.
|Figure 7: Results of the final run displayed in the Purify window|
Errors fixed, all leaks plugged! The program is good to go.
Now that we've looked at how Purify works on the Linux platform with a small C program, let's look at something a bit more complex -- a slightly larger program written in C++.
I took a good look around the Linux world in search of an excellent toolset that could showcase essential functionality for the platform, as well as one that a lot of Linux users take advantage of. I wasn't having a whole lot of luck, simply because there were a lot of toolsets to choose from. And then a simple game program created with a well-known graphical toolset fell right into my lap from an errant find command.
One of the most popular games around is a simple game known as Tetris (created by Alexey Pazhitnov in 1985 at the Moscow Academy of Science's Computer Center). The objective of the game is to complete colored lines on your screen by putting together matching blocks as they fall from the top of the screen to the bottom. When the unmatched blocks hit the top of the screen, the game is over. The creation of this game spawned an industry revolution; variants of Tetris are still being created and played all around the world. During my search, I discovered that an analogy to Tetris named Tetrix (shown in Figure 8) was listed as example code on my Linux machine. That's the code we'll use as our sample program in this section.
|Figure 8: The Tetrix example program in action|
Chasing down the references in the sample program, I learned that the graphical toolset it was created with is known as Qt, from a company named Trolltech. Qt is a well-known C++ framework available on many platforms, with an open-source version available on Linux. The example in this section uses Qt Version 3.3.3 on the Red Hat distribution.
In the previous example, we ran our sample program with Rational Purify from the command line. You can also run Purify from within a Linux makefile, in this case the Tetrix makefile shown in Figure 9. You don't have to do anything complex in the makefile; you just prefix the specific compiler command with the purify statement.
|Figure 9: The Tetrix makefile altered to include the purify command|
Purify's command line options can help you a great deal when incorporating it into your make (build) environment. For examples and options, check the online help. (In Figure 9, I used the -g++ option to show how it's done.)
Figure 10 shows Purify instrumenting the Tetrix program.
|Figure 10: Purify instrumenting the Tetrix program|
As the Tetrix executable runs, the Purify window appears, giving you a runtime update of the error messages and memory leaks generated during program execution. Figure 11 shows you some of the errors found while Tetrix is running.
|Figure 11: UMR errors from the execution of Tetrix, displayed in Purify|
Figure 12 gives you a more detailed look at an uninitialized memory read (UMR) and a memory leak (MLK) found after the Tetrix program has finished execution.
|Figure 12: A closer look at a UMR and an MLK found after exiting the program|
In the more detailed view of the UMR, you can see that Purify is noting errors with individual threads in the Tetrix program. This should give you confidence that as you use Purify for larger and more complex projects, you'll be receiving a very accurate picture of what's happening in your code at every level, from the smallest function to the most complex algorithm.
In my previous article on Rational PurifyPlus and software quality, I asserted that you really have to do all you can to assure that your programs are the best they can be. This tenet is key, regardless of software platform or size of program. In the Linux environment, Rational Purify provides a comprehensive solution for finding errors and memory leaks. I hope that the small snippets I've shown of Rational Purify in action have given you a good idea of how you can successfully integrate it into your Linux development environment with very little effort.
- "Bad software quality: Using IBM Rational PurifyPlus to avoid development problems" by Aaron (Rusty) Lloyd (developerWorks, July 2004) provides an overview of how to use PurifyPlus to improve software development efforts on platforms other than Linux.
- The C Programming Language 2nd edition by Brian W. Kernighan and Dennis M. Ritchie (Prentice-Hall, 1988) is the source of the example C program used in this article.
- For more information on how your organization can adopt principles of efficient software development, take a look at both the Linux and the Rational sections of the IBM developerWorksÂ® Web site. These sections are filled with information on software best practices and on how users succeed in using our products and open source technologies in their environment.
- Learn about the IBM Software Development Platform and why Rational products are an important component of it.
- Share your questions and views on the topics covered in this article with the author and other readers in the Rational discussion forums.
- Browse for books on these and other technical topics.
Aaron (Rusty) Lloyd knows how to handle a broadsword as well as he handles technology. He is currently the Technology Evangelist for the developerWorks: Rational Web site. If you have a question or want to see him address something on developerWorks, you can contact him by e-mail.