日韩黑丝制服一区视频播放|日韩欧美人妻丝袜视频在线观看|九九影院一级蜜桃|亚洲中文在线导航|青草草视频在线观看|婷婷五月色伊人网站|日本一区二区在线|国产AV一二三四区毛片|正在播放久草视频|亚洲色图精品一区

分享

GDB遠(yuǎn)程調(diào)試技術(shù)

 WUCANADA 2012-08-16


  GDB調(diào)試器提供了兩種不同的調(diào)試代理用于支持遠(yuǎn)程調(diào)試,即gdbserver方式和stub(插樁)方式。
   這兩種遠(yuǎn)程調(diào)試方式是有區(qū)別的。gdbserver本身的體積很小,能夠在具有很少存儲(chǔ)容量的目標(biāo)系統(tǒng)上獨(dú)立運(yùn)行,因而非常適合于嵌入式環(huán)境;而stub 方式則需要通過(guò)鏈接器把調(diào)試代理和要調(diào)試的程序鏈接成一個(gè)可執(zhí)行的應(yīng)用程序文件,如果程序運(yùn)行在沒(méi)有操作系統(tǒng)的機(jī)器上,那么stub需要提供異常和中斷處 理序,以及串口驅(qū)動(dòng)程序,如果程序運(yùn)行在有操作系統(tǒng)的嵌入式平臺(tái)上,那么stub需要修改串口驅(qū)動(dòng)程序和操作系統(tǒng)異常處理。顯然,對(duì)于在有嵌入式操作系統(tǒng) 支持下的開(kāi)發(fā)而言,gdbserver比stub程序更容易使用。這里使用的是GDB+gdbserver的方式,建立遠(yuǎn)程調(diào)試的環(huán)境。
   gdbserver是一個(gè)可以獨(dú)立運(yùn)行的控制程序,它可以運(yùn)行在類UNIX操作系統(tǒng)上,當(dāng)然,也可以運(yùn)行在Linux的諸多變種。gdbserver允許遠(yuǎn)程GDB調(diào)試器通過(guò)target remote命令與運(yùn)行在目標(biāo)板上的程序建立連接。
   GDB和gdbserver之間可以通過(guò)串口線或TCP/IP網(wǎng)絡(luò)連接通信,采用的通信協(xié)議是標(biāo)準(zhǔn)的GDB遠(yuǎn)程串行協(xié)議( Remote Serial Protocol RSP)。
   使用gdbserver調(diào)試方式時(shí),在目標(biāo)機(jī)端需要一份要調(diào)試的程序的拷貝,這通常是通過(guò)ftp或NFS下載到目標(biāo)機(jī)上的,宿主機(jī)端也需要這信一份拷貝。 由于gdbserver不處理程序符號(hào)表,所以如果有必要,可以用strip工具將要復(fù)制到目標(biāo)機(jī)上的程序中的符號(hào)表去掉以節(jié)省空間。符號(hào)表是由運(yùn)行在主 機(jī)端的GDB調(diào)試器處理的,不能將主機(jī)端的程序中的符號(hào)表去掉。
    雖然大部分的Linux發(fā)行版都已經(jīng)安裝了GDB,但是那都是基于PC的平臺(tái)的,我們要使用的是在ARM平臺(tái)上,所以要重新下載gdb的源碼,并修改以 適應(yīng)自己的目標(biāo)平臺(tái)。可以從http://www./software/gdb/download,獲得。這里使用的是GDB的最新的版本 7.1。首先將下載到的gdb-7.1.tar.bz2復(fù)制到/home/zfz/gdb目錄下。在控制臺(tái)下輸入下面的解包命令

#tar -jxvf gdb-7.1.tar.bz2

  解包之后會(huì)生成gdb-7.1/目錄,所有的源碼都在這個(gè)目錄下,在gdb目錄下新建立一個(gè)目錄arm-linux-gdb,把生成的可執(zhí)行文件都放在這個(gè)目錄下,
在gdb-7.1目錄下,輸入下面的命令,配置GDB源碼:

./configure --target=arm-linux --prefix=/home/frank/gdb --program-prefix=arm-linux-

   其中 --target=arm-linux選項(xiàng),表示針對(duì)的目標(biāo)平臺(tái)是運(yùn)行l(wèi)inux內(nèi)核的ARM體系結(jié)構(gòu)的平臺(tái),后面的選項(xiàng)--prefix=/home /frank/gdb 則是指定編譯完成后的安裝目錄,最后一個(gè)選項(xiàng)--program-prefix=arm-
linux-用來(lái)指定在編譯生成的二進(jìn)制可執(zhí)行文件名之前加上前綴,這里加上的前綴是arm-linux-。這樣就可以和宿主機(jī)上的調(diào)試文件相區(qū)別。

make

把源文件編譯成相應(yīng)的目標(biāo)文件,并連接成可執(zhí)行的二進(jìn)制文件 。然后,再執(zhí)行下面的命令,

make intall

   執(zhí)行完該命令后,就會(huì)在我們剛才建立的arm-linux-gdb目錄下生成bin/,lib/,share/這幾個(gè)子目錄,其中在bin下有三個(gè)可執(zhí)行 文件分別為:arm-linux-gdb. arm-linux-run ,arm-linux-gdbui.arm-linux-gdb,就是我們需要的調(diào)試器。
   編譯完arm-linux-gdb之后,接下來(lái)就需要編譯在目標(biāo)板上運(yùn)行的gdbserver了,在gdb/gdb7.1/gdb下有一個(gè)gdbserver的子目錄,這個(gè)目錄包括了編譯gdbserver所需要的所有的東西。
首先,進(jìn)行g(shù)dbserver目錄

./configure --target=arm-linux --host=arm-linux

此時(shí),如果要直接進(jìn)行編譯的話,會(huì)出現(xiàn)錯(cuò)誤,

linux-arm-low.c:26:21:sys/reg.h: 沒(méi)有那個(gè)文件 或目錄
make:*****[linux-arm-low.0] Error 1


這里的sys/reg.h是指/usr/include/sys/reg.h,在該文件中定義的寄存器都是針對(duì)x86平臺(tái)的,對(duì)于運(yùn)行
在ARM平臺(tái)上的gdbserver顯然是不對(duì)的,在configure后,將會(huì)生成一個(gè)config.h文件,在這個(gè)文件中定
義了相應(yīng)的宏,在config.h中我們可以看到這樣一個(gè)C語(yǔ)言的宏定義,


#define HAVE_SYS_REG_H 1
在linux-arm-low.c文件中出錯(cuò)的代碼行:
#ifdef HAVE_SYS_REG_H
#include <sys/reg.h>
#endif

這 里我們只需要把conifg.h文件中的#define HAVE_SYS_REG_H 1注釋掉就OK了。由于gdbserver是運(yùn)行在ARM-linux平臺(tái)上的,因此需要使用交叉編譯器arm-linux-gcc,這可以通過(guò)給 make加上CC參數(shù)來(lái)實(shí)現(xiàn)這里我使用的是默認(rèn)的,你也可以使用一個(gè)絕對(duì)的路徑來(lái)指定一個(gè)arm-linux-gcc.
   所有的工作都已經(jīng)完成了,只要把生成的gdbserver下載到目標(biāo)板上,或者是通過(guò)NFS掛載到目標(biāo)板上就可能進(jìn)行遠(yuǎn)程的調(diào)試了,如果就是足夠幸運(yùn)的 話,編譯中沒(méi)有出現(xiàn)什么錯(cuò)誤的話,這樣完全可以了,不過(guò)在我的系統(tǒng)上卻不是那么幸運(yùn)。我一直使用的是友善之臂的arm-linux-gcc-4.3.2交 叉編譯器,這個(gè)版本的編譯器中,已經(jīng)自帶了arm-linux-gdb.
在終端中輸入arm-linux-gdb -v 可以看到下面的信息

#make CC = arm-linux-gcc


GNU gdb (Sourcery G++ Lite 2008q3-72) 6.8.50.20080821-cvs

Copyright (C) 2008 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http:///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 "--host=i686-pc-linux-gnu --target=arm-none-linux-gnueabi".
For bug reporting instructions, please see:
<https:

   這里可以看出arm-linux-gcc-4.3.2自帶的arm-linux-gdb的版本是6.8版的,而我們一直編譯的是7.1版本的。一開(kāi)始我并 沒(méi)有注意arm-linux-gdb的版本信息,不過(guò)在使用過(guò)程中,我把用生成的gdbserver的7.1版本用NFS加載到目標(biāo)板上,而在宿主機(jī)上用 的arm-linux-gcc 6.8版本,一直出現(xiàn)下面的錯(cuò)誤:
先在目標(biāo)機(jī)上運(yùn)行下面的gdbserver,注意這里的IP地址是宿主機(jī)上的IP地址。

[root@Frankzfz]$gdbserver 10.27.10.48:9000 ./test_seg_fault
Process ./test_seg_fault created; pid = 760
Listening on port 9000
Remote debugging from host 10.27.10.48

然后在宿主機(jī)上運(yùn)行

arm-linux-gdb/bin$ arm-linux-gdb
GNU gdb (Sourcery G++ Lite 2008q3-72) 6.8.50.20080821-cvs
Copyright (C) 2008 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http:///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 "--host=i686-pc-linux-gnu --target=arm-none-linux-gnueabi".
For bug reporting instructions, please see:
<https://support.codesourcery.com/GNUToolchain/>.

(gdb) target remote 10.27.10.23:9000
Remote debugging using 10.27.10.23:9000
Malformed packet(b) (missing colon): ore:0;
Packet: 'T050b:00000000;0d:804ebdbe;0f:b0070040;thread:2f8;core:0;'

(gdb) symbol-file test_seg_fault
Reading symbols from /home/zfz/kernel/fs/arm-linux-gdb/bin/test_seg_fault...done.
(gdb) break main
Breakpoint 1 at 0x84a8: file test_seg_fault.c, line 7.
(gdb) info main
Undefined info command: "main". Try "help info".
(gdb) info b
Num Type Disp Enb Address What
1 breakpoint keep y 0x000084a8 in main at test_seg_fault.c:7
(gdb) c
The program is not being run.
(gdb)

輸入c命令時(shí)說(shuō)是程序沒(méi)有運(yùn)行,可是程序已經(jīng)在目標(biāo)板上運(yùn)行了,不用輸入run命令,當(dāng)輸入  target remote 10.27.10.23:9000結(jié)束后,在minicom中可以看到目標(biāo)板上的輸出信息有了變化.

[root@Frankzfz]$gdbserver 10.27.10.48:9000 ./test_seg_fault
Process ./test_seg_fault created; pid = 760
Listening on port 9000
Remote debugging from host 10.27.10.48
readchar: Got EOF
Remote side has terminated connection. GDBserver will reopen the connection.
Listening on port 9000

   在這里搗鼓了一整天沒(méi)有弄明白錯(cuò)誤在那里,看到了arm-linux-gdb 和gdbserver的版本不匹配,所以就變換arm-linux-gdb,這里要把a(bǔ)rm-linux-gdb加入到.profile文件中,或者environment文件中,

PATH="/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/lib/jvm/j
dk1.6.0_17/bin:/home/zfz/kernel/fs/arm-linux-gdb/bin:/home/zfz/linux-
tool/usr/local/arm/4.3.2/bin"

   當(dāng)時(shí)一直在,arm-linux-gdb/bin目錄下執(zhí)行,其實(shí)執(zhí)行的也都是arm-linux-gcc-4.3.2中的arm-linux-gdb, 如果這樣你看到的版本信息還是6.8版本的話,也可以直接在arm-linux-gcc-4.3.2中把a(bǔ)rm-linux-gdb文件刪除掉。
   這樣再一次查看arm-linux-gdb的信息。

GNU gdb (GDB) 7.1
Copyright (C) 2010 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http:///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 "--host=x86_64-unknown-linux-gnu --target=arm-linux".
For bug reporting instructions, please see:
<http://www./software/gdb/bugs/>.

   使用GDB進(jìn)行調(diào)試,首先,我的宿主機(jī)的IP 10.27.10.48,開(kāi)發(fā)板上的IP 10.27.10.23在開(kāi)發(fā)板上運(yùn)行g(shù)dbserver 10.27.10.48:9000 test,這里是通過(guò)NFS,把要調(diào)試的程序加載到目標(biāo)版上面的。這樣就可從在宿主機(jī)上運(yùn)行。

zfz@zfz:~/kernel/fs/arm-linux-gdb/bin$ ./arm-linux-gdb test
./arm-linux-gdb: Symbol `acs_map' has different size in shared object, consider re-linking
GNU gdb (GDB) 7.1
Copyright (C) 2010 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http:///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 "--host=x86_64-unknown-linux-gnu --target=arm-linux".
For bug reporting instructions, please see:
<http://www./software/gdb/bugs/>...
Reading symbols from /home/zfz/kernel/fs/arm-linux-gdb/bin/test...done.
(gdb) target remote 10.27.10.23:9000
Remote debugging using 10.27.10.23:9000
warning: Unable to find dynamic linker breakpoint function.
GDB will be unable to debug shared library initializers
and track explicitly loaded dynamic code.
0x400007b0 in ?? ()
(gdb) l
Cannot access memory at address 0x0
1    #include <stdio.h>
2    int main( void )
3    {
4     int i=2;
5     int x, y;
6    
7     x=(++i);
8     printf(" %d %d\n", i,x);
9     x+=(++i);
10     printf(" %d %d\n", i,x);
(gdb) l
11     x+=(++i);
12     printf(" %d %d\n", i,x);
13     i=2;
14     y=(i++)+(i++)+(i++);
15     printf(" %d %d\n", i,y);
16    
17     return 0;
18    }
19    
(gdb) break 9
Breakpoint 1 at 0x83b8: file test.c, line 9.
(gdb) c
Continuing.
Error while mapping shared library sections:
`/lib/libc.so.6'
: not in executable format: File format not recognized
Error while mapping shared library sections:
/lib/ld-linux.so.3: No such file or directory.

Breakpoint 1, main () at test.c:9
9     x+=(++i);
(gdb) step
10     printf(" %d %d\n", i,x);
(gdb) next
11     x+=(++i);
(gdb) next
12     printf(" %d %d\n", i,x);
(gdb) next
13     i=2;
(gdb) next
14     y=(i++)+(i++)+(i++);
(gdb) next
15     printf(" %d %d\n", i,y);
(gdb) next
17     return 0;
(gdb) next
18    }
(gdb) next

在目標(biāo)板上的輸出:

[root@Frankzfz]$gdbserver 10.27.10.48:9000 ./test
Process ./test created; pid = 746
Listening on port 9000
Remote debugging from host 10.27.10.48
 3 3
 4 7
 5 12
 5 6

補(bǔ)充:前面還有庫(kù)文件錯(cuò)誤的問(wèn)題,這里可以通過(guò)下面這樣的方法的來(lái)解決。需要說(shuō)明的是,遠(yuǎn)程調(diào)試,可能程序動(dòng)態(tài)庫(kù),我們可以這樣設(shè)置:

set solib-absolute-prefix /nfsroot/rootfs
set solib-search-path /nfsroot/rootfs/lib

調(diào)試找不到源代碼,如下設(shè)置:

directory xfer-1.0.0/src/

下面是調(diào)試的情況:

(gdb) set solib-absolute-prefix /home/kernel/fs/root_nfs
(gdb) set solib-search-path /home/kernel/fs/root_nfs/lib
(gdb) target remote 10.27.10.23:9000
Remote debugging using 10.27.10.23:9000
Reading symbols from /home/kernel/fs/root_nfs/lib/ld-linux.so.3...(no debugging symbols

found)...done.
Loaded symbols for /home/kernel/fs/root_nfs/lib/ld-linux.so.3
0x400007b0 in ?? () from /home/kernel/fs/root_nfs/lib/ld-linux.so.3
(gdb) l
3    {
4     int i=2;
5     int x, y;
6    
7     x=(++i);
8     printf(" %d %d\n", i,x);
9     x+=(++i);
10     printf(" %d %d\n", i,x);
11     x+=(++i);
12     printf(" %d %d\n", i,x);
(gdb) l
13     i=2;
14     y=(i++)+(i++)+(i++);
15     printf(" %d %d\n", i,y);
16    
17     return 0;
18    }
19    
(gdb) b 8
Note: breakpoint 1 also set at pc 0x83a8.
Breakpoint 2 at 0x83a8: file test.c, line 8.
(gdb) c
Continuing.

Breakpoint 1, main () at test.c:8
8     printf(" %d %d\n", i,x);
(gdb) n
9     x+=(++i);
(gdb) b 12
Breakpoint 3 at 0x8400: file test.c, line 12.
(gdb) n
10     printf(" %d %d\n", i,x);
(gdb) n
11     x+=(++i);
(gdb) n

Breakpoint 3, main () at test.c:12
12     printf(" %d %d\n", i,x);
(gdb) n
13     i=2;
(gdb) n
14     y=(i++)+(i++)+(i++);
(gdb) n
15     printf(" %d %d\n", i,y);
(gdb) n
17     return 0;
(gdb) n
18    }
(gdb) n
0x4003b004 in __libc_start_main ()
   from /home/kernel/fs/root_nfs/lib/libc.so.6
(gdb)

    本站是提供個(gè)人知識(shí)管理的網(wǎng)絡(luò)存儲(chǔ)空間,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點(diǎn)。請(qǐng)注意甄別內(nèi)容中的聯(lián)系方式、誘導(dǎo)購(gòu)買等信息,謹(jǐn)防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請(qǐng)點(diǎn)擊一鍵舉報(bào)。
    轉(zhuǎn)藏 分享 獻(xiàn)花(0

    0條評(píng)論

    發(fā)表

    請(qǐng)遵守用戶 評(píng)論公約

    類似文章 更多