zflGt, ;'zf;g, ljsf; / ;d[l4sf] cfsf+Iff k"/f ug{ ;+ljwfg ;efaf6 kfl/t. u/L of] ;+ljwfg hf/L ub{5f}+ . Page 2 of 280. Pa
G
D
B
In addition to offering specific advice for debugging with each tool, authors Norm Matloff and Pete Salzman cover general strategies for improving the process of finding and fixing coding errors, including how to: • Inspect variables and ./mtrace1 points to 0x8049a58 points to 0x804968c
If you look at the contents of mtrace.log , it makes no sense at all. However, running the Perl script mtrace() produces understandable output: $ cat mtrace.log = Start @ ./mtrace1:(mtrace+0x120)[0x80484d4] + 0x8049a58 0x4 @ ./mtrace1:(mtrace+0x157)[0x804850b] - 0x804968c p@satan$ mtrace mtrace.log - 0x0804968c Free 3 was never alloc'd 0x804850b Memory not freed: ----------------Address Size 0x08049a58 0x4
Caller at 0x80484d4
However, this is only slightly helpful, because although mtrace() found the problems, it reported them as pointer addresses. Fortunately, mtrace() can do better. The mtrace() script also takes the executable’s filename as an optional argument. Using this option, you get line numbers along with the associated problems. - 0x0804968c Free 3 was never alloc'd /home/p/codeTests/mtrace1.c:15 Memory not freed: ----------------Address Size 0x08049a58 0x4
Caller at /home/p/codeTests/mtrace1.c:11
Now this is what we wanted to see! Like the MALLOC_CHECK_ and mcheck() utilities, mtrace() won’t prevent your program from crashing. It simply checks for problems. If your program crashes, some of the output of mtrace() may become lost or garbled, which could produce puzzling error reports. The best way to cope with this is to catch and handle seg faults in order to give mtrace() a shot at shutting down gracefully. The following example illustrates how to do so. 232
Chapter 7
www.it-ebooks.info
void sigsegv_handler(int signum); int main(void) { int *p; signal(SIGSEGV, sigsegv_handler); mtrace(); p = (int *) malloc(sizeof(int));
raise(SIGSEGV); return 0; } void sigsegv_handler(int signum) { printf("Caught sigsegv: signal %d. Shutting down gracefully.\n", signum); muntrace(); abort(); }
Listing 7-12: mtrace2.c
Other Tools
www.it-ebooks.info
233
www.it-ebooks.info
8 U S I N G G D B / D D D/ E CLI PS E F O R OTHER LANGUAGES
GDB and DDD are commonly known as debuggers for C/C++ programs, but they can be used for development in other languages, as well. Eclipse was originally designed for Java development, but it has plug-ins for many other languages. This chapter will show you how to use this multilanguage capability. GDB/DDD/Eclipse are not necessarily the “best” debuggers for any particular language. A large number of excellent debugging tools are available for specific languages. What we are saying, though, is that it would be nice to be able use the same debugging interface no matter which language you are writing in, whether it be C, C++, Java, Python, Perl, or other languages/debuggers that these tools can be used with. DDD has been “ported” to all of them. For example, consider Python. The Python interpreter includes a simple, text-based debugger of its own. Again, a number of excellent Pythonspecific GUI debuggers and IDEs do exist, but another option is to use DDD as an interface to Python’s built-in debugger. This enables you to achieve the
www.it-ebooks.info
convenience of a GUI while still using the interface that you are familiar with from your C/C++ coding (DDD). How does the multilanguage versatility of these tools come about? •
Though GDB was originally created as a debugger for C/C++, the GNU people later offered a Java compiler too, GCJ.
•
Recall that DDD is not a debugger in its own right, but rather a GUI through which you can issue commands to an underlying debugger. For C and C++, that underlying debugger is typically GDB. However, DDD can be, and often is, used as a frontend for debuggers specific to other languages.
•
Eclipse is also just a frontend. The plug-ins for various languages give it the power to manage the development and debugging of code in those languages.
In this chapter, we’ll give an overview of debugging in Java, Perl, Python, and assembly language with these tools. It should be noted that in each case there are additional features not covered here, and we urge you to explore the details for the language you are using.
8.1
Java As an example, let’s consider an application program that manipulates a linked list. Here objects of class Node represent the nodes in a linked list of numbers, which are maintained in order of ascending key value. The list itself is an object of class LinkedList. The test program TestLL.java reads in numbers from the command line, builds up a linked list consisting of those numbers in sorted order, and then prints out the sorted list. Here are the source files: TestLL.java 1
// usage:
[java] TestLL list_of_test_integers
2 3 4 5
// simple example program; reads integers from the command line, // storing them in a linear linked list, maintaining ascending order, // and then prints out the final list to the screen
6 7 8 9 10 11 12 13 14 15 16
236
public class TestLL { public static void main(String[] Args) { int NumElements = Args.length; LinkedList LL = new LinkedList(); for (int I = 1; I