Chapter 2.2 : How to use the debugger



This the command to be used to launch our hadamard_product program with gdb :

gdb ./hadamard_product
GNU gdb (Ubuntu 7.11.1-0ubuntu1~16.04) 7.11.1
Copyright (C) 2016 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.  Type "show copying"
and "show warranty" for details.
This GDB was configured as "x86_64-linux-gnu".
Type "show configuration" for configuration details.
For bug reporting instructions, please see:
<http://www.gnu.org/software/gdb/bugs/>.
Find the GDB manual and other documentation resources online at:
<http://www.gnu.org/software/gdb/documentation/>.
For help, type "help".
Type "apropos word" to search for commands related to "word"...
Reading symbols from ./hadamard_product...done.


Note that the last line shows you there are some debugging symbols in your program :


Reading symbols from ./hadamard_product...done.


If you forgot to turn on the debugging symbols gdb will tell you :


Reading symbols from ./hadamard_product...(no debugging symbols found)...done.


Now, we get in the gdb terminal and we can run our program with run or r command :

(gdb) r
Starting program: XXX/build/hadamard_product 
Hadamard product
tabResult[0] = 0
*** Error in `XXX/build/hadamard_product': double free or corruption (!prev): 0x0000000000615030 ***
======= Backtrace: =========
/lib/x86_64-linux-gnu/libc.so.6(+0x777e5)[0x7ffff77037e5]
/lib/x86_64-linux-gnu/libc.so.6(+0x7fe0a)[0x7ffff770be0a]
/lib/x86_64-linux-gnu/libc.so.6(cfree+0x4c)[0x7ffff770f98c]
XXX/build/hadamard_product(_Z23evaluateHadamardProductm+0x24f)[0x40119f]
XXX/build/hadamard_product(main+0x2c)[0x400c6c]
/lib/x86_64-linux-gnu/libc.so.6(__libc_start_main+0xf0)[0x7ffff76ac830]
XXX/build/hadamard_product(_start+0x29)[0x400cf9]
======= Memory map: ========
00400000-00402000 r-xp 00000000 08:01 6963418                            XXX/build/hadamard_product
00601000-00602000 r--p 00001000 08:01 6963418                            XXX/build/hadamard_product
00602000-00603000 rw-p 00002000 08:01 6963418                            XXX/build/hadamard_product
00603000-00635000 rw-p 00000000 00:00 0                                  [heap]
7ffff0000000-7ffff0021000 rw-p 00000000 00:00 0 
7ffff0021000-7ffff4000000 ---p 00000000 00:00 0 
7ffff716d000-7ffff7183000 r-xp 00000000 08:01 8651671                    /lib/x86_64-linux-gnu/libgcc_s.so.1
7ffff7183000-7ffff7382000 ---p 00016000 08:01 8651671                    /lib/x86_64-linux-gnu/libgcc_s.so.1
7ffff7382000-7ffff7383000 rw-p 00015000 08:01 8651671                    /lib/x86_64-linux-gnu/libgcc_s.so.1
7ffff7383000-7ffff748b000 r-xp 00000000 08:01 8652856                    /lib/x86_64-linux-gnu/libm-2.23.so
7ffff748b000-7ffff768a000 ---p 00108000 08:01 8652856                    /lib/x86_64-linux-gnu/libm-2.23.so
7ffff768a000-7ffff768b000 r--p 00107000 08:01 8652856                    /lib/x86_64-linux-gnu/libm-2.23.so
7ffff768b000-7ffff768c000 rw-p 00108000 08:01 8652856                    /lib/x86_64-linux-gnu/libm-2.23.so
7ffff768c000-7ffff784b000 r-xp 00000000 08:01 8652890                    /lib/x86_64-linux-gnu/libc-2.23.so
7ffff784b000-7ffff7a4b000 ---p 001bf000 08:01 8652890                    /lib/x86_64-linux-gnu/libc-2.23.so
7ffff7a4b000-7ffff7a4f000 r--p 001bf000 08:01 8652890                    /lib/x86_64-linux-gnu/libc-2.23.so
7ffff7a4f000-7ffff7a51000 rw-p 001c3000 08:01 8652890                    /lib/x86_64-linux-gnu/libc-2.23.so
7ffff7a51000-7ffff7a55000 rw-p 00000000 00:00 0 
7ffff7a55000-7ffff7bc7000 r-xp 00000000 08:01 10356490                   /usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.21
7ffff7bc7000-7ffff7dc7000 ---p 00172000 08:01 10356490                   /usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.21
7ffff7dc7000-7ffff7dd1000 r--p 00172000 08:01 10356490                   /usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.21
7ffff7dd1000-7ffff7dd3000 rw-p 0017c000 08:01 10356490                   /usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.21
7ffff7dd3000-7ffff7dd7000 rw-p 00000000 00:00 0 
7ffff7dd7000-7ffff7dfd000 r-xp 00000000 08:01 8652926                    /lib/x86_64-linux-gnu/ld-2.23.so
7ffff7fc2000-7ffff7fc7000 rw-p 00000000 00:00 0 
7ffff7ff5000-7ffff7ff8000 rw-p 00000000 00:00 0 
7ffff7ff8000-7ffff7ffa000 r--p 00000000 00:00 0                          [vvar]
7ffff7ffa000-7ffff7ffc000 r-xp 00000000 00:00 0                          [vdso]
7ffff7ffc000-7ffff7ffd000 r--p 00025000 08:01 8652926                    /lib/x86_64-linux-gnu/ld-2.23.so
7ffff7ffd000-7ffff7ffe000 rw-p 00026000 08:01 8652926                    /lib/x86_64-linux-gnu/ld-2.23.so
7ffff7ffe000-7ffff7fff000 rw-p 00000000 00:00 0 
7ffffffdd000-7ffffffff000 rw-p 00000000 00:00 0                          [stack]
ffffffffff600000-ffffffffff601000 r-xp 00000000 00:00 0                  [vsyscall]

Program received signal SIGABRT, Aborted. 0x00007ffff76c1428 in __GI_raise (sig=sig@entry=6) at ../sysdeps/unix/sysv/linux/raise.c:54 54 ../sysdeps/unix/sysv/linux/raise.c: Aucun fichier ou dossier de ce type.


Our program is complaining as before, but now we will have more information.

First we will use the command bt (or back trace) to get the call sequence of the functions which lead to the problem.



(gdb) bt
#0  0x00007ffff76c1428 in __GI_raise (sig=sig@entry=6) at ../sysdeps/unix/sysv/linux/raise.c:54
#1  0x00007ffff76c302a in __GI_abort () at abort.c:89
#2  0x00007ffff77037ea in __libc_message (do_abort=do_abort@entry=2, fmt=fmt@entry=0x7ffff781c2e0 "*** Error in `%s': %s: 0x%s ***\n") at ../sysdeps/posix/libc_fatal.c:175
#3  0x00007ffff770be0a in malloc_printerr (ar_ptr=<optimized out>, ptr=<optimized out>, str=0x7ffff781c410 "double free or corruption (!prev)", action=3) at malloc.c:5004
#4  _int_free (av=<optimized out>, p=<optimized out>, have_lock=0) at malloc.c:3865
#5  0x00007ffff770f98c in __GI___libc_free (mem=<optimized out>) at malloc.c:2966
#6  0x000000000040119f in evaluateHadamardProduct (nbElement=<optimized out>) at XXX/main.cpp:54
#7  0x0000000000400c6c in main (argc=<optimized out>, argv=<optimized out>) at XXX/main.cpp:65


We are now at the lower level in the back trace.

Here we can explore the function __GI_raise which is not very useful because we expect to have a bug in one of our function.



Each level of function call is described with a # :
#0  0x00007ffff76c1428 in function where the problem hapened
#1  0x00007ffff76c302a in function which calls the function at 0
#2  0x00007ffff77037ea in function which calls the function at 1
#3  0x00007ffff770be0a in function which calls the function at 2
...


In our case, we have to figure out what is going on in the evaluateHadamardProduct function at the line 54 of file main.cpp :

#6  0x000000000040119f in evaluateHadamardProduct (nbElement=<optimized out>) at XXX/main.cpp:54


So we have to go at level 6.

gdb provide us two functions to move up and down in the calls which are precisely up and down



Let's call up :
#1  0x00007ffff76c302a in __GI_abort () at abort.c:89
89	abort.c: Aucun fichier ou dossier de ce type.


Now, we are at the level 1. So let's do that again (or you can just push return to redo the last up or down move) :
(gdb) 
#2  0x00007ffff77037ea in __libc_message (do_abort=do_abort@entry=2, fmt=fmt@entry=0x7ffff781c2e0 "*** Error in `%s': %s: 0x%s ***\n") at ../sysdeps/posix/libc_fatal.c:175
175	../sysdeps/posix/libc_fatal.c: Aucun fichier ou dossier de ce type.
(gdb) 
#3  0x00007ffff770be0a in malloc_printerr (ar_ptr=<optimized out>, ptr=<optimized out>, str=0x7ffff781c410 "double free or corruption (!prev)", action=3) at malloc.c:5004
5004	malloc.c: Aucun fichier ou dossier de ce type.
(gdb) 
#4  _int_free (av=<optimized out>, p=<optimized out>, have_lock=0) at malloc.c:3865
3865	in malloc.c
(gdb) 
#5  0x00007ffff770f98c in __GI___libc_free (mem=<optimized out>) at malloc.c:2966
2966	in malloc.c
(gdb) 
#6  0x000000000040119f in evaluateHadamardProduct (nbElement=<optimized out>) at XXX/main.cpp:54
54		delete[] tabResult;


Here we are, at level 6.

We can print some value with the print function. For example tabResult :



(gdb) print tabResult
$1 = (float *) 0x615030


But we have some limitations. For example, if we want to print the variable nbElement :

print nbElement 
$2 = <optimized out>


We do not have its value because the compiler optimised its use in the program so we do not have feedback.