Running Linux, 5th Edition - Matthias Kalle Dalheimer [395]
papaya$ gdb cross core
GDB is free software and you are welcome to distribute copies of it
under certain conditions; type "show copying" to see the conditions.
There is absolutely no warranty for GDB; type "show warranty" for details.
GDB 4.8, Copyright 1993 Free Software Foundation, Inc...
Core was generated by `cross'.
Program terminated with signal 11, Segmentation fault.
#0 0x2494 in crossings (image=0xc7c8) at cross.c:31
31 if ((image[i][j] >= 0) &&
(gdb)
gdb tells us that the core file was created when the program terminated with signal 11. A signal is a kind of message that is sent to a running program from the kernel, the user, or the program itself. Signals are generally used to terminate a program (and possibly cause it to dump core). For example, when you type the interrupt character, a signal is sent to the running program, which will probably kill the program.
In this case, signal 11 was sent to the running cross process by the kernel when cross attempted to read or write to memory to which it did not have access. This signal caused cross to die and dump core. gdb says that the illegal memory reference occurred on line 31 of the source file cross.c:
(gdb) list
26 xmax = imGetWidth(image)-1;
27 ymax = imGetHeight(image)-1;
28
29 for (j=1; j 32 (image[i-1][j-1] < 0) || 33 (image[i-1][j] < 0) || 34 (image[i-1][j+1] < 0) || 35 (image[i][j-1] < 0) || (gdb) Here, we see several things. First of all, there is a loop across the two index variables i and j, presumably in order to do calculations on the input image. Line 31 is an attempt to reference data from image[i][j], a two-dimensional array. When a program dumps core while attempting to access data from an array, it's usually a sign that one of the indices is out of bounds. Let's check them: (gdb) print i $1 = 1 (gdb) print j $2 = 1194 (gdb) print xmax $3 = 1551 (gdb) print ymax $4 = 1194 (gdb) Here we see the problem. The program was attempting to reference element image[1][1194]; however, the array extends only to image[1550][1193] (remember that arrays in C are indexed from 0 to max - 1). In other words, we attempted to read the 1195th row of an image that has only 1194 rows. If we look at lines 29 and 30, we see the problem: the values xmax and ymax are reversed. The variable j should range from 1 to ymax (because it is the row index of the array), and i should range from 1 to xmax. Fixing the two for loops on lines 29 and 30 corrects the problem. Let's say that your program is crashing within a function that is called from many different locations, and you want to determine where the function was invoked from and what situation led up to the crash. The backtrace command displays the call stack of the program at the time of failure. If you are like the author of this section and are too lazy to type backtrace all the time, you will be delighted to hear that you can also use the shortcut bt. The call stack is the list of functions that led up to the current one. For example, if the program starts in function main, which calls function foo, which calls bamf, the call stack looks like this: (gdb) backtrace #0 0x1384 in bamf () at goop.c:31 #1 0x4280 in foo () at goop.c:48 #2 0x218 in main () at goop.c:116 (gdb) As each function is called, it pushes certain data onto the stack, such as saved registers, function arguments, local variables, and so forth. Each function has a certain amount of space allocated on the stack for its use. The chunk of memory on the stack for a particular function is called a stack frame, and the call stack is the ordered list of stack frames . In the following example, we are looking at a core file for an X-based animation program. Using backtrace gives us the following: (gdb) backtrace #0 0x602b4982 in _end () #1 0xbffff934