GDB single-step execution and function Tracing

Source: Internet
Author: User

Http://learn.akae.cn/media/ch10s01.html

1. Single-step execution and function Tracing

See the following program:

Example 10.1. Function debugging example

#include <stdio.h>int add_range(int low, int high){int i, sum;for (i = low; i <= high; i++)sum = sum + i;return sum;}int main(void){int result[100];result[0] = add_range(1, 10);result[1] = add_range(1, 100);printf("result[0]=%d\nresult[1]=%d\n", result[0], result[1]);return 0;}

 

add_rangeFunction slavelowAddhigh, InmainIn the function, first add 1 to 10, save the result, then add 1 to 100, and then save the result. The two results are printed as follows:

result[0]=55result[1]=5105

The first result is correct [20], and the second result is obviously incorrect. in elementary school, we heard about the story of Gauss's childhood. The story from 1 to 100 should be 5050. For a piece of code, the first running result is correct, but the second running is incorrect. This is a common type of error. In this case, you should not doubt the Code but the data, because the first and second run is the same piece of code. If the code is wrong, why is the first result correct? However, the data related to the first and second run may be different. Wrong data may lead to incorrect results. Before you start debugging, you should first try to see if the code can tell the cause of the error. As long as the previous chapters are well-developed, you should be able to see the cause.

Add-gOption to generate an executable file.gdbSource code-level debugging:

$ gcc -g main.c -o main$ gdb mainGNU gdb 6.8-debianCopyright (C) 2008 Free Software Foundation, Inc.License GPLv3+: GNU GPL version 3 or later 

-gThe option is used to add source code information to the executable file. For example, the number of machine commands in the executable file corresponds to the number of lines in the source code, however, the entire source file is not embedded into the executable file, so it must be ensured during debugging.gdbFind the source file.gdbProvides a shell-like command line environment.(gdb)Is a prompt. EnterhelpYou can view the command category:

(gdb) helpList of classes of commands:aliases -- Aliases of other commandsbreakpoints -- Making program stop at certain pointsdata -- Examining datafiles -- Specifying and examining filesinternals -- Maintenance commandsobscure -- Obscure featuresrunning -- Running the programstack -- Examining the stackstatus -- Status inquiriessupport -- Support facilitiestracepoints -- Tracing of program execution without stopping the programuser-defined -- User-defined commandsType "help" followed by a class name for a list of commands in that class.Type "help all" for the list of all commands.Type "help" followed by command name for full documentation.Type "apropos word" to search for commands related to "word".Command name abbreviations are allowed if unambiguous.

You can also view the commands in a category, for examplefilesWhich commands are available under the category:

(gdb) help filesSpecifying and examining files.List of commands:add-shared-symbol-files -- Load the symbols from shared objects in the dynamic linker's link mapadd-symbol-file -- Load symbols from FILEadd-symbol-file-from-memory -- Load the symbols out of memory from a dynamically loaded object filecd -- Set working directory to DIR for debugger and program being debuggedcore-file -- Use FILE as core dump for examining memory and registersdirectory -- Add directory DIR to beginning of search path for source filesedit -- Edit specified file or functionexec-file -- Use FILE as program for getting contents of pure memoryfile -- Use FILE as program to be debuggedforward-search -- Search for regular expression (see regex(3)) from last line listedgenerate-core-file -- Save a core file with the current state of the debugged processlist -- List specified function or line...

Try nowlistCommand to list the source code from the first line:

(gdb) list 11#include <stdio.h>23int add_range(int low, int high)4{5int i, sum;6for (i = low; i <= high; i++)7sum = sum + i;8return sum;9}10

Only 10 rows are listed at a time. If you want to continue with the source code of the column from row 11th, you can enter

(gdb) list

Or press enter without losing anything,gdbA convenient function is provided. Directly press enter at the prompt to repeat the previous command.

(GDB) (Press ENTER) 11int main (void) 12 {13int result [100]; 14 result [0] = add_range (1, 10 ); 15 result [1] = add_range (1,100); 16 printf ("result [0] = % d \ nresult [1] = % d \ n", result [0], result [1]); 17 return 0; 18}

gdbFor examplelistThe command can be writtenlTo list the source code of a function, you can also use the function name as a parameter:

(gdb) l add_range1#include <stdio.h>23int add_range(int low, int high)4{5int i, sum;6for (i = low; i <= high; i++)7sum = sum + i;8return sum;9}10

Exit nowgdbEnvironment:

(gdb) quit

We will conduct an experiment to rename the source code or move it elsewhere for reuse.gdbDebugging, so that the source code is not listed:

$ mv main.c mian.c$ gdb main...(gdb) l5main.c: No such file or directory.in main.c

VisiblegccOf-gThe option is not to embed the source code into the executable file, and the source file is also required during debugging. Now we have restored the source code to its original state, so we can continue debugging. UsestartRun the following command to run the program:

$ gdb main...(gdb) startBreakpoint 1 at 0x80483ad: file main.c, line 14.Starting program: /home/akaedu/main main () at main.c:1414result[0] = add_range(1, 10);(gdb)

gdbStopmainThe first statement after the variable definition in the function waits for us to issue a command,gdbThis statement is the next statement to be executed. We can usenextCommand (abbreviatedn) Control the execution of these statements one by one:

(GDB) n15result [1] = add_range (1,100); (GDB) (Press ENTER) 16 printf ("result [0] = % d \ nresult [1] = % d \ n", result [0], result [1]); (GDB) (Press enter directly) result [0] = 55 result [1] = 510517 return 0;

UsenCommand to execute two rows of value assignment statement and one line of print statement, the result is immediately printed when the print statement is executed, and then stopreturnBefore the statement. Although we fully control the execution of the program, we still cannot see any errors because the errors are notmainIn the functionadd_rangeFunction, now usestartCommand again.stepCommand (abbreviateds) Drillingadd_rangeFunction to trace and execute:

(gdb) startThe program being debugged has been started already.Start it from the beginning? (y or n) yBreakpoint 2 at 0x80483ad: file main.c, line 14.Starting program: /home/akaedu/main main () at main.c:1414result[0] = add_range(1, 10);(gdb) sadd_range (low=1, high=10) at main.c:66for (i = low; i <= high; i++)

Stopped this time.add_rangeThe first statement after the variable definition in the function. There are several ways to view the status in the function,backtraceCommand (abbreviatedbt) You can view the stack frame of the function call:

(gdb) bt#0  add_range (low=1, high=10) at main.c:6#1  0x080483c1 in main () at main.c:14

The currentadd_rangeThe function ismainFunction call,mainThe input parameter islow=1, high=10.mainThe function stack frame number is 1,add_rangeStack frame number is 0. Now you can useinfoCommand (abbreviatedi) Viewadd_rangeValue of the local variable of the function:

(gdb) i localsi = 0sum = 0

If you want to viewmainThe value of the current local variable of the function can also be used.frameCommand (abbreviatedf) Select stack 1 and then check the local variables:

(gdb) f 1#1  0x080483c1 in main () at main.c:1414result[0] = add_range(1, 10);(gdb) i locals result = {0, 0, 0, 0, 0, 0, 134513196, 225011984, -1208685768, -1081160480, ...  -1208623680}

NotesresultMany elements in the array have disordered values. We know that uninitialized local variables have undefined values. So far, everything is normal. UsesOrnTake a few steps down, and then useprintCommand (abbreviatedp) Print out the variablesumValue:

(GDB) s7sum = sum + I; (GDB) (Press ENTER) 6For (I = low; I <= high; I ++) (GDB) (Press ENTER) 7sum = sum + I; (GDB) (Press ENTER) 6For (I = low; I <= high; I ++) (GDB) P sum $1 = 3

First cycleiIs 1, the second cycleiIt's 2. it's 3 in total. That's right. Here$1IndicatesgdbSave these intermediate results, and the number after $ will automatically increase. You can use$1,$2,$3. Because we knew that the result of the first call was correct, it makes no sense to follow it down. You can usefinishCommand to keep the program running until the current function returns:

(gdb) finishRun till exit from #0  add_range (low=1, high=10) at main.c:60x080483c1 in main () at main.c:1414result[0] = add_range(1, 10);Value returned is $2 = 55

The return value is 55. The value assignment operation is currently being executed.sCommand assignment, and then viewresultArray:

(gdb) s15result[1] = add_range(1, 100);(gdb) p result$3 = {55, 0, 0, 0, 0, 0, 134513196, 225011984, -1208685768, -1081160480, ...  -1208623680}

The first value 55 is indeed assignedresultThe array contains 0th elements. UsesCommand to enter the secondadd_rangeCall. First, check the parameters and local variables:

(gdb) sadd_range (low=1, high=100) at main.c:66for (i = low; i <= high; i++)(gdb) bt#0  add_range (low=1, high=100) at main.c:6#1  0x080483db in main () at main.c:15(gdb) i locals i = 11sum = 55

Due to local variablesiAndsumNot initialized, so there are uncertain values, and because the two calls are close to each other,iAndsumThe value of the last call is exactly the same as that of example 3.7 "verifying the allocation and release of the local variable bucket", except that I tried to make the local variablesumThe initial value for the first call is 0.iIt does not matter if the initial valuesforIn the loopiAssignedlowButsumIf the initial value is not 0, the result is incorrect. Now, we have found the cause of the error. You can exit.gdbModified the source code. If we don't want to waste this debugging opportunity, you cangdbAttachsumChange the initial value to 0 to continue running. check whether there are any other bugs after this change:

(GDB) set var sum = 0 (GDB) finishrun till exit from #0 add_range (Low = 1, high = 100) at main. c: 60x08048db in main () at main. c: 1515 result [1] = add_range (1,100); value returned is $4 = 5050 (GDB) n16printf ("result [0] = % d \ nresult [1] = % d \ n", result [0], result [1]); (GDB) (Press ENTER) result [0] = 55 result [1] = 505017 return 0;

The result is correct. To modify the value of a variablesetYou can also useprintCommand, becauseprintThe command is followed by an expression, and we know that both the value assignment and function call are expressions, so you can also useprintCommand to modify the value of a variable or call a function:

(gdb) p result[2]=33$5 = 33(gdb) p printf("result[2]=%d\n", result[2])result[2]=33$6 = 13

As we have said,printfThe return value indicates the number of characters actually printed, so$6The result is 13. Summarize the information used in this section.gdbCommand:

Table 10.1. GDB basic command 1

Command Description
Backtrace (or BT) View function calls and parameters at all levels
Finish Run until the current function returns, and then stop and wait for the command.
Frame (or F) frame number Stack frame selection
Info (or I) locals View the value of the local variable of the current stack frame
List (or L) The source code is listed, followed by 10 lines in each column at the following position.
List row number List source code starting from the first line
List function name List the source code of a function
Next (or N) Execute the next statement
Print (or p) Print the expression value. You can use the expression to modify the value of a variable or call a function.
Quit (or Q) ExitgdbDebugging environment
Set VaR Modify the value of a Variable
Start Start executing the program and stopmainWait for the command before the first line of the function statement
STEP (or S) Execute the next statement. If a function is called, it enters the function.

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.