Debugging Segmentation Faults Across Multiple Files

Overview

This debugging session goes across functions that are physically located in different source files, so we have to reference the function name when using the list 'l' or breakpoint 'p' debugger commands.

Example:

l 10  (lists 10 lines of the source file being debugged)

1 main.c: 10 (list 10 lines if the main.c source file)

- same holds for breakpoints -

b 25 (sets a breakpoint at line 25)

b slinked.c: 25 (sets a breakpoint at line 25 in the source file slinlked.c)


Starting with the buggy version of slinked.c: push() where we caused a segfault by doing a string copy to an unitialized char* pointer (we forgot to do the malloc!)

bash-4.4$ make
gcc -g -c slinked.c
gcc -g -o slinked slinked.o main.o
bash-4.4$ ./slinked
Segmentation fault (core dumped)
bash-4.4$ gdb slinked
GNU gdb 6.3
Copyright 2004 Free Software Foundation, Inc.
GDB is free software, covered by the GNU General Public License, and you are
welcome to change it and/or 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.
This GDB was configured as "amd64-unknown-openbsd6.2"...
(gdb) r
Starting program: /home/tjr/work/2175/swen250/C/CLinkedList/Slist/slinked

Program received signal SIGSEGV, Segmentation fault.   // seg fault occurs in strncpy, but who called strncpy?

_libc_strncpy (dst=0x0, src=0x1d5457b00d2d "Oscar", n=6) at /usr/src/lib/libc/string/strncpy.c:49
49      /usr/src/lib/libc/string/strncpy.c: No such file or directory.
        in /usr/src/lib/libc/string/strncpy.c
Current language:  auto; currently minimal
(gdb)
(gdb) bt        // need to do a back trace (bt) to see the calling sequence that got us to strncpy

#0  _libc_strncpy (dst=0x0, src=0x1d5457b00d2d "Oscar", n=6) at /usr/src/lib/libc/string/strncpy.c:49
#1  0x00001d5457a005ce in push (name=0x1d5457b00d2d "Oscar", grade=65 'A') at slinked.c:26
#2  0x00001d5457a006ae in main () at main.c:10
(gdb)
#0  _libc_strncpy (dst=0x0, src=0x1d5457b00d2d "Oscar", n=6) at /usr/src/lib/libc/string/strncpy.c:49
#1  0x00001d5457a005ce in push (name=0x1d5457b00d2d "Oscar", grade=65 'A') at slinked.c:26
#2  0x00001d5457a006ae in main () at main.c:10

(gdb) l main.c: 5,15                // started in main at line 10, which called push()

5
6       struct node* head = NULL;
7       main(){
8               struct node entry;
9
10              push( "Oscar", 'A' );    // main() called push()
11              printList(head);
12
13              push("Betty",'B');
14              printList(head);
15
(gdb) l slinked.c: 20,30            // push() called strncpy() at slinked.c:line 26
20      void push(char *name, char grade) {
21
22        /* YOUR CODE HERE */
23
24        struct node *newNode = (struct node*)malloc(sizeof(struct node));
25        newNode->grade = grade;
26        strncpy( newNode->name, name, strlen(name)+1);   // push() called strncpy()
27        newNode->next = head;
28        head = newNode;
29
30      }
(gdb) p name
No symbol "name" in current context.
(gdb) p slinked.c: name
No symbol "slinked" in current context.    // can't see value of name in this context

(gdb) b 26
Breakpoint 1 at 0x1d5457a005b1: file slinked.c, line 26.   // so we'll set a breakpoint here and restart
(gdb) r
The program being debugged has been started already.
Start it from the beginning? (y or n) y

Starting program: /home/tjr/work/2175/swen250/C/CLinkedList/Slist/slinked
Breakpoint 1 at 0x19b405b005b1: file slinked.c, line 26.

Breakpoint 1, push (name=0x19b405c00d2d "Oscar", grade=65 'A') at slinked.c:26
26        strncpy( newNode->name, name, strlen(name)+1);    // here we are at the call to strncpy

Current language:  auto; currently c
(gdb) p name
$1 = 0x19b405c00d2d "Oscar"
(gdb) p newNode->name                     // oops, trying to copy 6 characters to memory location 0
$2 = 0x0
(gdb) p strlen(name)+1
$3 = 6
(gdb)
$4 = 6
(gdb) q
The program is running.  Exit anyway? (y or n) y    // let's go fix that by adding a malloc() prior to copy

bash-4.4$ nano slinked.c
bash-4.4$ make
gcc -g -c slinked.c
gcc -g -o slinked slinked.o main.o
bash-4.4$ gdb slinked
GNU gdb 6.3
Copyright 2004 Free Software Foundation, Inc.
GDB is free software, covered by the GNU General Public License, and you are
welcome to change it and/or 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.
This GDB was configured as "amd64-unknown-openbsd6.2"...

(gdb) l slinked.c: 20,30                // slinked,c after our fix has been made at line 26
20      void push(char *name, char grade) {
21
22        /* YOUR CODE HERE */
23
24        struct node *newNode = (struct node*)malloc(sizeof(struct node));
25        newNode->grade = grade;
26        newNode->name = (char*)malloc(strlen(name)+1);  // allocate space to copy name to
27        strncpy( newNode->name, name, strlen(name)+1);
28        newNode->next = head;
29        head = newNode;
30
(gdb) b slinked.c: 26            // set a breakpoint BEFORE running to verify fix
Breakpoint 1 at 0x5b1: file slinked.c, line 26.
(gdb) r
Starting program: /home/tjr/work/2175/swen250/C/CLinkedList/Slist/slinked
Breakpoint 1 at 0xd3514f005b1: file slinked.c, line 26.

Breakpoint 1, push (name=0xd3515000d4d "Oscar", grade=65 'A') at slinked.c:26
26        newNode->name = (char*)malloc(strlen(name)+1);  // allocate space to copy name to

(gdb) p newNode->name                    // examine parameters prior to malloc()
$1 = 0x0
(gdb) p name
$2 = 0xd3515000d4d "Oscar"
(gdb) n
27        strncpy( newNode->name, name, strlen(name)+1);
 

(gdb) p newNode->name                   
// examine parameters after malloc(), but prior to strncpy()
$3 = 0xd379074b850 ""
(gdb) p newNode->name                    // this looks better!
$4 = 0xd379074b850 ""
(gdb) p strlen(name)+1
$5 = 6
(gdb) n
28        newNode->next = head;
(gdb) p newNode->name
$6 = 0xd379074b850 "Oscar"
(gdb) c
Continuing.
List:
Name = Oscar
Grade = A


Breakpoint 1, push (name=0xd3515000d53 "Betty", grade=66 'B') at slinked.c:26
26        newNode->name = (char*)malloc(strlen(name)+1);  // allocate space to copy name to
(gdb) q
The program is running.  Exit anyway? (y or n) y
bash-4.4$

Success!!