Simple use of GDB
Debug the arm program using GDB + gdbserver
1: simple use of GDB
GDB is a powerful Unix program debugging tool released by the GNU open-source organization. Maybe you like it.
Graphical interface, such as Vc, BCB, and other ide debugging, but if you are running software on a UNIX platform, you
It will be found that the gdb debugging tool has more powerful functions than the visual debugger of VC and BCB. The so-called "inch
Length, size is short "is this truth. In general, GDB helps you complete the following four aspects:
Yes:
1. Start your program and run it as needed according to your custom requirements.
2. The program to be debugged can be stopped at the breakpoint you specified. (The breakpoint can be a conditional expression)
3. When the program is stopped, you can check what happens in your program.
4. dynamically change the execution environment of your program. From the above perspective, there is no difference between GDB and general debugging tools.
Basically, these functions are also completed, but in details, you will find that the debugging tool GDB is powerful and big
You may be used to graphical debugging tools, but sometimes command line debugging tools have graphical tools
Functions that cannot be completed. Let's look at it one by one.
A debugging example
------ Source program: TST. c
#include <stdio.h>int func(int n){ int sum=0,i; for(i=0; i<n; i++) { sum+=i; } return sum; } main() { int i; long result = 0; for(i=1; i<=100; i++) { result += i; } printf("result[1-100] = %d \\n", result ); printf("result[1-250] = %d \\n", func(250) ); }
Compile and generate the execution file: (in Linux)
Hchen/test> CC-g tst. C-o TST
Debug with GDB:
Hchen/test> gdb tst <-- start GDB
Gnu gdb 5.1.1
Copyright 2002 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.
Www.linuxidc.com
Www.linuxidc.com
This GDB was configured as "i386-suse-linux "...
(GDB) L <-- l command is equivalent to list. The source code is obtained from the first line.
1 # include <stdio. h>
2
3 int func (int n)
4 {
5 Int sum = 0, I;
6 For (I = 0; I <n; I ++)
7 {
8 sum + = I;
9}
10 return sum;
(GDB) <-- press enter to repeat the previous command.
11}
12
13
14 main ()
15 {
16 int I;
17 long result = 0;
18 For (I = 1; I <= 100; I ++)
19 {
20 result + = I;
(GDB) break 16 <-- set the breakpoint at the source code line 16th.
Breakpoint 1 at 0x8048496: file TST. C, line 16.
(GDB) Break func <-- set the breakpoint at the entrance of the function func.
Breakpoint 2 at 0x8048456: file TST. C, line 5.
(GDB) info break <-- view the breakpoint information.
Num type disp ENB address what
1 breakpoint keep Y 0x08048496 in main
2 breakpoint keep y t0sx0t. 8c0: 4186456 in func
(GDB) r <-- O & M t sequence st., C: 5run command abbreviation
Starting program:/home/hchen/test/TST breakpoint 1, main () at TST. C: 17 <-- at the breakpoint
Stop.
17 long result = 0;
(GDB) n <-- execute a single statement. The next command is short for execution.
18 For (I = 1; I <= 100; I ++)
(GDB) N
20 result + = I;
(GDB) N
18 For (I = 1; I <= 100; I ++)
(GDB) N
20 result + = I;
(GDB) C <-- continue to run the program. The "continue" command is abbreviated.
Continuing.
Result [1-100] = 5050 <-- program output.
Breakpoint 2, func (n = 250) at TST. C: 5
5 Int sum = 0, I;
(GDB) N
6 For (I = 1; I <= N; I ++)
(GDB) p I <-- print the value of variable I, short for the print command.
$1 = 134513808
(GDB) N
8 sum + = I;
(GDB) N
6 For (I = 1; I <= N; I ++)
(GDB) P sum
$2 = 1
Www.linuxidc.com
Www.linuxidc.com
(GDB) N
8 sum + = I;
(GDB) p I
$3 = 2
(GDB) N
6 For (I = 1; I <= N; I ++)
(GDB) P sum
$4 = 3
(GDB) BT <-- view the function stack.
#0 func (n = 250) at TST. C: 5
#1 0x080484e4 in main () at TST. C: 24
#2 0x400409ed in _ libc_start_main () from/lib/libc. so.6
(GDB) finish <-- exit the function.
Run till exit from #0 func (n = 250) at TST. C: 5
0x080484e4 in main () at TST. C: 24
24 printf ("result [1-250] = % d \ n ",
Func (250); value returned is $6 = 31375
(GDB) C <-- continue running.
Continuing.
Result [1-250] = 31375 <-- program output.
Program exited with code 027. <------- the program exits and debugging is complete.
(GDB) q <-- exit GDB.
Hchen/test>
2: debug the arm program using GDB + gdbserver
【Abstract】: This article first introduces the concepts related to GDB + gdbserver, and then introduces its download, compilation, and installation.
Next, we will introduce how to use GDB + gdbserver to debug the application process and examples.
GDB + gdbserver FAQs during installation.
Key words: GDB, gdbserver, remote debugging
Directory
1. GDB + gdbserver overview... 1
Ii. Source Code download... 1 3. Configuration compilation and
Install and download... 1 4. GDB + gdbserver
NFS debugging process... 2. How to Use the serial port
Debugging... 3 6. Practical debugging... 3
7. gdbserver installation in Linux... 5
1. GDB + gdbserver Overview
The remote debugging environment consists of the host machine GDB and the target machine debugging stub. The two are connected through the serial port or TCP. Use GDB
The quasi-serial protocol works collaboratively to monitor and debug the system kernel and upper-layer applications on the target machine. Debugging stub is embedded
A piece of code in the inbound system exists as a medium between GDB on the host machine and the debugging program on the target machine. Currently
In the Linux system, there are three main remote debugging methods, which are suitable for debugging in different scenarios:
Use Rom monitor to debug the target program, use kgdb to debug the system kernel, and use gdbserver to debug the user space program.
The main difference between the three debugging methods is that the existence of stub for remote debugging on the target machine is different, and its design concept and
The implementation method is roughly the same.
The most common practice is to debug applications. Debugging is performed using GDB + gdbserver. In many cases
Users need to repeatedly debug an application, especially complex programs. The GDB method is used for debugging.
Limited resources. Generally, debugging on the target system is not allowed. GDB + gdbserver is usually used for debugging.
Ii. Source Code download
The GDB debugging environment in Embedded Linux consists of host and target. The host end uses arm-linuxgdb,
The target board uses gdbserver. In this way, the application runs on the embedded target system, while GDB debugs on
Therefore, remote debugging is required. For GDB debugging, the target system must include the gdbserver Program
Www.linuxidc.com
Www.linuxidc.com
(The host is successfully compiled on the hardware platform and then downloaded to the target machine), the host must also install the gdb program. Generally
Each row has a running GDB, but developers cannot directly use GDB in the release for remote debugging.
Take the source code package of GDB, make a simple configuration for the ARM platform, and re-compile the corresponding GDB. The source code package of GDB can be
To
Http://www.gnu.org/software/gdb/download/
Http://ftp.gnu.org/gnu/gdb/ 211.95.105.202: 3128 can go up, all versions have ah
Http: // ftp.cs.pu.edu.tw/linux/sourceware/gdb/releases/download
Ftp://ftp.gnu.org/gnu/gdb
I often don't go to FTP on the Internet. Download channels in common open-source communities in China usually download
Bytes
. Download to a directory and download it to/opt /. However, it should be noted that the gdb version must match the croostool version.
3. Configure compilation and installation and download
After the download, go to the/opt/directory and configure the compilation steps as follows:
# Tar jxvf gdb-6.5-tar-bz2
# Cd gdb-6.5
#./Configure -- target = arm-Linux -- prefix =/usr/local/ARM-GDB-V
(-- Target: configure the target platform of GDB, -- prefix: configure the installation path. Of course, other paths are also supported. It is consistent with the following configuration.
You can,
It must be declared in the environment variable to start arm-Linux-GDB. You can change/etc/profile or ~ /. Bash_profile or ~ /. Bashrc, add
Add
Export Path = $ path:/usr/local/ARM-GDB/bin)
# Make
# Make install
(Generate arm-Linux-GDB and save it to/usr/local/ARM-GDB/bin/for query confirmation.) You can also start arm-Linux-GDB.
Merit,
It proves that the installation is correct and enters the gdb/gdbserver directory)
[Root @ dding gdbserver] # pwd
/Opt/gdb-6.5/GDB/gdbserver
[Root @ dding gdbserver] #./configure -- target = arm-Linux-host = arm-Linux
(You must run the configuration command in the gdbserver directory to use the relative path.
-- Target = arm-Linux indicates the target platform, and -- Host indicates that the host runs arm-Linux-GDB without configuring-prefix,
Because
Gdbserver is not installed on the host)
# Make cc =/usr/local/ARM/2.95.3/bin/ARM-Linux-gcc
(In this step, you need to specify the absolute location of your arm-Linux-GCC. If I have tried it, the prompt "Make: Arm-Linux-GCC:" is displayed:
Command not found, which can be used by many people, that is, directly assigning values to arm-Linux-GCC. parameters can be passed when make is used.
You can also directly modify the environment variable CC in the MAKEFILE file under the gdbserver directory)
If there is no error, generate the gdbserver executable file in the gdbserver directory. Note that you need to change its properties at this time. Otherwise, you can
The chmod 777 gdbserver can be read and written to and executed by anyone. armlinux-
The strip command is used to process the gdbserver and delete unnecessary symbol information, which can simplify the ELF File.
The application is used for the final release. Then, it is written to/usr/bin of the root file system partition of Flash (in this directory ).
The system can automatically find the application, otherwise it must run in the directory where gdbserver is located), or through NFS
The Mount method is acceptable. You only need to ensure that gdbserver can run on the Development Board.
Iv. GDB + gdbserver NFS debugging process
Next we can use GDB + gdbserver to debug the program on our development board. Running gdbserver on the target board is actually
Under the minicom of the host machine. I made it after # Mount 192.168.2.100: // TMP under minicom (here the parameter-o
Nolock can be skipped and executed faster without this step). Hello and gdbserver are both located in the Linux root directory,
Mount the root directory of the host to the/tmp directory of the Development Board.
To debug GDB, start the gdbserver service on the target system. In the directory where gdbserver is located, enter
Input command: (under minicom)
# Cd/tmp
#./Gdbserver 192.168.2.100: 2345 hello
(192.168.2.100 is the host machine IP address, which is enabled on port 2345 of the target system (you can set other available values, of course, must be consistent with the host's GDB ).
Started a debugging process. Hello is the program to be debugged (the-G must be added to the debugging information )).
Prompt:
Process/tmp/Hello created: pid = 80
Www.linuxidc.com
Www.linuxidc.com
Listening on port 2345
(Under another Terminal)
# Cd/
# Export Path = $ path:/usr/local/ARM-GDB/bin
# Arm-Linux-GDB hello
The last line shows: This GDB was configured as "-- Host = i686-pc-linux-gnu, -- target = armlinux"
... If they are inconsistent, it indicates that there is a problem with arm-Linux-GDB. It means that GDB runs on the x86 host, but the debugging target is arm.
Code.
(GDB) target remote 192.168.2.223: 2345
(192.168.2.223 is the Development Board IP address)
Remote debugging using 192.168.2.223: 2345
[New thread 80]
[Switching to thread 80]
0x40002a90 in ?? ()
At the same time, the following message is displayed under minicom:
Remote debugging from host 192.168.2.100
(GDB)
Note: Your port number must be the same as the port number enabled by gdbserver for communication. After creating a link, you can
Debugging. Debugging on the host end is the same as the gdb debugging method. Note that "C" is used to execute commands.
"R ". Because the program has been started by gdbserver on the target board. The output result is in the target
And use a Super Terminal. After successful connection, you can enter various gdb commands, such as list, run, next,
Step, break, etc.
For the above methods, NFS mount and TFTP can only be debugged on the host and downloaded to the Development Board for running.
This process should be repeated for errors. Some programs can only be debugged on the Development Board. Therefore, the author uses
Remote debugging method. I hope it will be useful for debugging programs!
V. How to Use Serial Port debugging
If you use Serial Port 1 to debug hello, run the following command on the Board:
Gdbserver Hello/dev/ttys0
(For details, refer to the README file in the gdbserver directory). Then, gdbserver is waiting for the response signal of GDB .)
Then run the following command on the PC:
Xxx-Linux-GDB hello
Run the following command in XXX-Linux-GDB:
(GDB) set remotedevice/dev/ttys0
(Set Serial Port 1 here)
(GDB) set remote baud 9600
(Set the serial port baud rate here)
(GDB) set debug remote
(Optional)
(GDB) target remote/dev/ttys0
After the operation, GDB should contact gdbserver.
6. Practical debugging
1. edit the file
# Vi gdbtest. c
1 # include <stdio. h>
2
3 int
4 func (int n ){
5 Int sum = 0, I;
6 For (I = 0; I <n; I ++ ){
7 sum + = I;
8}
9 return sum;
10}
11
Www.linuxidc.com
Www.linuxidc.com
12 INT
13 main (void)
14 {
15 int I;
16 long result = 0;
17 For (I = 0; I <= 100; I ++ ){
18 result + = I;
19}
20
21 printf ("result [1-100] = % d \ n", result );
22 printf ("resutl [1-225] = % d \ n", func (255 ));
23
24 return 0;
25}
# Arm-Linux-gcc-G gdbtest. C-o gdbtest // cross-compile
2. download the file to the target board: gdbtest and gdbserver
Assume host pc ip: 192.168.1.45
Board IP: 192.168.1.180
A: copy the file to the target board:
(Copy the gdbtest and gdbserver files to the/tftpboot directory of the host. At this time, both the system host and the target machine must support NFS)
Run:
# Mount 192.168.1.108:/tftpboot/mnt/nfs
# Cd/mnt/nfs
# Ls
Check whether there are two files, gdbtest and gdbserver.
3. Run debugging
Client Board:
#./Gdbserver 192.168.1.45: 1234 gdbtest
(The target board runs gdbtest listening port 1234)
[Root @ at91rm9200dk arm] $./gdbserver 192.168.0.12: 2345 mainparacarm
./Gdbserver: Error in loading shared libraries: libthread_db.so.1: cannot open
[Root @ at91rm9200dk arm] $
Host PC:
# Cd/usr/local/ARM-GDB/bin/
(To Run arm-Linux-GDB, but this is not necessary. You can set this path in environment variables .)
# Copy gdbtest/usr/local/ARM-GDB/bin/
(Copy the previously compiled file gdbtest to this directory)
#./ARM-Linux-GDB gdbtest
(GDB) target remote 192.168.1.180: 1234
(After successfully connecting to the Development Board)
Debugging
(GDB) list or L
(GDB) Break func
(GDB) Break 22
(GDB) info br
(GDB) continue or C
(Run cannot be used here)
(GDB) next or N
(GDB) print or P result
(GDB) Finish
(Jump out of func function)
(GDB) Next
(GDB) quit
After the connection is established, the local debugging method of GDB is the same as that of GDB.
Www.linuxidc.com
Www.linuxidc.com
7. gdbserver installation in Linux
Toolchain version: the version of GDB may be closely related to the cross compiler.
Gccglibcbinutils-
2.15 this is croostool
Installation Steps: Download
Extract gdb-6.6
# Cd gdb-6.6
#./Configure -- target = arm-Linux -- prefix =/usr/local/ARM-GDB-V
# Make & make install
OK, and then:
# Export Path = $ path:/usr/local/ARM-GDB
Go to the gdbserver directory:
#./Configure -- target = arm-Linux -- Host = arm-Linux
# Make cc =/usr/local/armv5l // bin/armv5l-Linux-gcc
Error:
/Usr/local/armv5l // bin/armv5l-linux-gcc-C-wall-g-O2-I.-I ../regformats-
I./../include
-I ../BFD linux-arm-low.c
Linux-arm-low.c: 35: 21: SYS/Reg. H: No file or directory
Make: *** [linux-arm-low.o] Error 1
Then copy/usr/include/sys/Reg. h
/Usr/local/armv5l-2.6.x // armv5l-linux/include/sys/Reg. H,
Copy the file to the include directory of the cross compiler and make the file again. An error is displayed:
/Usr/local/armv5l // bin/armv5l-linux-gcc-C-wall-g-O2-I.-I ../regformats-
I./../include
-I ../BFD thread-db.c
Thread-db.c: In function 'thread _ db_err_str ':
Thread-db.c: 95: Error: 'td _ version' undeclared (first use in this
Function) thread-db.c: 95: Error: (each undeclared identifier is reported
Only once thread-db.c: 95: Error: for each function it appears in .)
Thread-db.c: In function 'thread _ db_get_tls_address ':
Thread-db.c: 336: Warning: Implicit declaration of function 'td _ thr_tls_get_addr'
Thread-db.c: 336: Warning: cast to pointer from INTEGER
Different Size thread-db.c: 340: Warning: Cast from pointer
Integer of different size make: *** [thread-db.o] Error 1
I wanted to continue to fix the error, but I don't feel quite right. Excuse me, what is the reason?
Is CC target wrong? Should it be arm-Linux or armv5l-linux?
1. Make: *** [linux-arm-low.o] Error 1
[Root @ dding gdbserver] #
[Root @ dding gdbserver] # gedit config. h
/* Define to 1 if you have the <sys/Reg. h> header file .*/
/* Define have_sys_reg_h 1 */
/* Have no <sys/Reg. h> header file. So undefine 20070402 dding */
2.
Thread-db.c: In function 'thread _ db_err_str ': gdb6.5
Thread-db.c: 95: 'td _ version' undeclared (first use in this function)
[Root @ dding gdbserver] # gedit config. h
94 # ifdef have_td_version
95 case td_version:
96 return "version mismatch between libthread_db and libpthread ";
97 # endif
/* Define if td_version is available .*/
/* # Define have_td_version 1 */
/* Have no td_version. So undefine 20070402 dding */
Gdb6.1 No problem
3.
[Root @ at91rm9200dk arm] $./gdbserver 192.168.0.12: 2345 mainparacarm gdb6.5
./Gdbserver: Error in loading shared libraries: libthread_db.so.1: cannot open
Www.linuxidc.com
Www.linuxidc.com
[Root @ at91rm9200dk arm] $./gdbserver 192.168.0.14: 2345 mainparacarm gdb6.1
./Gdbserver: Error in loading shared libraries: libthread_db.so.1: cannot open shared object
File:
No such file or directory
Why can't I open the libthread_db.so.1 shared library ???? Is the shared library related to the CPU type?
Gdbserver: Error while loading shared libraries: libthread_db.so.1: cannot open
Shared object file: no such file or director
* *** Compile GDB to make it static. I think there should be in the compilation options, or you should add cflags in makefile.
+ =
-Static
Ldflags + =-static
You can add one of the two.
* **/Lib there is no libthread_db.so.1 can I
Use NFS to copy libthread_db.so.1
/Lib? But now I cannot find this file, and is there any for cross?
Libpthread-0.8.so
Libpthread. So libpthread. sow.libresolv-. So
Libresolv. so.2 libstdc ++. libtermcap. so.2
[Root @ at91rm9200dk arm] $ CP libthread_db-1.0.so libthread_db.so.1
[Root @ at91rm9200dk arm] $ CP libthread_db.so.1/lib/
[Root @ at91rm9200dk arm] $./gdbserver 192.168.0.12: 2345 mainparacarm
./Gdbserver:/lib/libc. so.6: Version 'glibc _ 100' not found (required
/Lib/Li) Is it because the current version of GDB 6.5 is too high and requires matching between the kernel version and the cross compiler? No, just try it.
References for earlier versions of GDB
Www.linuxidc.com
Www.linuxidc.com