Original position http://www.unknownroad.com/rtfm/gdbtut/gdbsegfault.html
How to save breakpoint information by GDB
(1) create a file;
(2) Add DGB breakpoint information to a, for example, B xcassit. cpp: 666;
(3) load the breakpoint information in DGB: GDB./xcassist-X ./;
We plan to use GDB to solve the problem of segment errors caused by the following program (the file is segfault. C. The following program reads a line of text string from the user and then displays it on the screen. However, the following current program will not be executed as scheduled...
[CPP]
View plaincopyprint?
- <Span style = "font-size: 18px;" >#include <stdio. h>
- # Include <stdlib. h>
- Int main (INT argc, char ** argv)
- {
- Char * Buf;
- Buf = malloc (1 <31 );
- Fgets (BUF, 1024, stdin );
- Printf ("% s \ n", Buf );
- Return 1;
- } </Span>
The first step is to compile the code using the debugging flags method, as shown below:
~ # Gcc-G segfault. c
Then run:
~ # A. Out
Hello world!
Segmentation fault
This is not what we expect. It is time to start powerful GDB.
~# gdb a.outGNU gdb 5.0Copyright 2000 Free Software Foundation, Inc.GDB is free software, covered by the GNU General Public License, and you arewelcome 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 "i686-pc-linux-gnu"...(gdb)
Let's run it directly to see what happened:
(gdb) runStarting program: /home/dgawd/cpsc/363/a.out test stringProgram received signal SIGSEGV, Segmentation fault.0x4007fc13 in _IO_getline_info () from /lib/libc.so.6
We received a SIGSEGV signal from the operating system. This means we are trying to access an invalid memory. Let's try the backtrace (= BT) command:
(gdb) backtrace#0 0x4007fc13 in _IO_getline_info () from /lib/libc.so.6#1 0x4007fb6c in _IO_getline () from /lib/libc.so.6#2 0x4007ef51 in fgets () from /lib/libc.so.6#3 0x80484b2 in main (argc=1, argv=0xbffffaf4) at segfault.c:10#4 0x40037f5c in __libc_start_main () from /lib/libc.so.6
Here we only care about our own code, so we switch to stack frame 3 to see where the program crashes:
(gdb) frame 3#3 0x80484b2 in main (argc=1, argv=0xbffffaf4) at segfault.c:1010 fgets(buf, 1024, stdin)
Oh, it turned out to be a crash caused by calling fgets. In general, we all assume that library functions such as fgets can work correctly (if not, we will be in a lot of trouble ). Therefore, the cause of this problem must be one of our parameter problems. You may not know that 'stdin 'is a global variable created by the stdio library. Therefore, we assume that this parameter is correct. Then the rest can only be 'buf', and then view the current value of the Buf:
(gdb) print buf$1 = 0x0
The Buf value is 0x0, that is, the NULL pointer. This is not what we expect from the lock-The Buf should point to the memory allocated by the 8th-line code. Therefore, we need to return the 8th rows and see where it happened. First, kill the call currently run by our program:
(gdb) killKill the program being debugged? (y or n) y
(Note: you do not need to use quit to exit GDB directly, which is troublesome. Kill the current program call)
Then set a breakpoint in row 8th:
(gdb) break segfault.c:8Breakpoint 1 at 0x8048486: file segfault.c, line 8.
Run the program again:
(gdb) runStarting program: /home/dgawd/cpsc/363/a.out Breakpoint 1, main (argc=1, argv=0xbffffaf4) at segfault.c:88 buf = malloc(1<<31);
We check whether the Buf value changes before and after the malloc call. Before initializing a Buf, its value should be a random garbage, as shown in the following figure:
(GDB) print Buf $2 = 0xbffffaa8 "Gill? \ 177 \ 003 @ t' \ 001 @ \ 001"
We call the malloc step over (one-step execution) and check the Buf value again:
(gdb) next10 fgets(buf, 1024, stdin);(gdb) print buf$3 = 0x0
It can be seen that after calling malloc, The Buf is null. If you view the malloc manual page, you will find that malloc will return NULL if it cannot allocate enough memory. Therefore, it is determined that our malloc failed. Let's return to the code and check again:
7 : buf = malloc(1<<31);
Oh, expression 1 <31 (integer 1 shifted to 31 times, the original text is mistakenly written to the right shift) is 429497295, or 4 GB (gigabytes ). few machines have such memory-most of which is only 256 MB (apparently this article has been around for years, and it is estimated that the memory operating system will be suspended in half of its startup ). Therefore, malloc will inevitably fail. In addition, we read only 1024 bytes in fgets. All extra space will be wasted, even though we can allocate it. Here we change 1 <31 to 1024 (OR 1 <9) so that the program runs as expected:
~# a.outHello World!Hello World!
In this way, you can know how to use GDB to debug segment errors, which is very useful. This example also illustrates a very important principle: Always check the return value of malloc! Have a good day (to be honest, I make a mistake a day. But it should not be disgusting in the future. It will be nice every day in the future ^_^ ).