1. 程式人生 > >GDB遠端除錯技術---基於mini2440

GDB遠端除錯技術---基於mini2440

GDB偵錯程式提供了兩種不同的除錯代理用於支援遠端除錯,即gdbserver方式和stub(插樁)方式。
   這兩種遠端除錯方式是有區別的。gdbserver本身的體積很小,能夠在具有很少儲存容量的目標系統上獨立執行,因而非常適合於嵌入式環境;而stub方式則需要通過連結器把除錯代理和要除錯的程式連結成一個可執行的應用程式檔案,如果程式執行在沒有作業系統的機器上,那麼stub需要提供異常和中斷處理序,以及串列埠驅動程式,如果程式執行在有作業系統的嵌入式平臺上,那麼stub需要修改串列埠驅動程式和作業系統異常處理。顯然,對於在有嵌入式作業系統支援下的開發而言,gdbserver比stub程式更容易使用。這裡使用的是GDB+gdbserver的方式,建立遠端除錯的環境。
   gdbserver是一個可以獨立執行的控制程式,它可以執行在類UNIX作業系統上,當然,也可以執行在Linux的諸多變種。gdbserver允許遠端GDB偵錯程式通過target remote命令與執行在目標板上的程式建立連線。
   GDB和gdbserver之間可以通過串列埠線或TCP/IP網路連線通訊,採用的通訊協議是標準的GDB遠端序列協議( Remote Serial Protocol RSP)。
   使用gdbserver除錯方式時,在目標機端需要一份要除錯的程式的拷貝,這通常是通過ftp或NFS下載到目標機上的,宿主機端也需要這信一份拷貝。由於gdbserver不處理程式符號表,所以如果有必要,可以用strip工具將要複製到目標機上的程式中的符號表去掉以節省空間。符號表是由執行在主機端的GDB偵錯程式處理的,不能將主機端的程式中的符號表去掉。
    雖然大部分的Linux發行版都已經安裝了GDB,但是那都是基於PC的平臺的,我們要使用的是在ARM平臺上,所以要重新下載gdb的原始碼,並修改以適應自己的目標平臺。可以從http://www.gnu.org/software/gdb/download,獲得。這裡使用的是GDB的最新的版本7.1。首先將下載到的gdb-7.1.tar.bz2複製到/home/zfz/gdb目錄下。在控制檯下輸入下面的解包命令

#tar -jxvf gdb-7.1.tar.bz2

  解包之後會生成gdb-7.1/目錄,所有的原始碼都在這個目錄下,在gdb目錄下新建立一個目錄arm-linux-gdb,把生成的可執行檔案都放在這個目錄下,
在gdb-7.1目錄下,輸入下面的命令,配置GDB原始碼:

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

   其中 --target=arm-linux選項,表示針對的目標平臺是執行linux核心的ARM體系結構的平臺,後面的選項--prefix=/home/frank/gdb 則是指定編譯完成後的安裝目錄,最後一個選項--program-prefix=arm-
linux-用來指定在編譯生成的二進位制可執行檔名之前加上字首,這裡加上的字首是arm-linux-。這樣就可以和宿主機上的除錯檔案相區別。

make

把原始檔編譯成相應的目標檔案,並連線成可執行的二進位制檔案 。然後,再執行下面的命令,

make intall

   執行完該命令後,就會在我們剛才建立的arm-linux-gdb目錄下生成bin/,lib/,share/這幾個子目錄,其中在bin下有三個可執行檔案分別為:arm-linux-gdb. arm-linux-run ,arm-linux-gdbui.arm-linux-gdb,就是我們需要的偵錯程式。
   編譯完arm-linux-gdb之後,接下來就需要編譯在目標板上執行的gdbserver了,在gdb/gdb7.1/gdb下有一個gdbserver的子目錄,這個目錄包括了編譯gdbserver所需要的所有的東西。
首先,進行gdbserver目錄

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

此時,如果要直接進行編譯的話,會出現錯誤,

linux-arm-low.c:26:21:sys/reg.h: 沒有那個檔案 或目錄
make:*****[linux-arm-low.0] Error 1


這裡的sys/reg.h是指/usr/include/sys/reg.h,在該檔案中定義的暫存器都是針對x86平臺的,對於執行
在ARM平臺上的gdbserver顯然是不對的,在configure後,將會生成一個config.h檔案,在這個檔案中定
義了相應的巨集,在config.h中我們可以看到這樣一個C語言的巨集定義,


#define HAVE_SYS_REG_H 1
在linux-arm-low.c檔案中出錯的程式碼行:
#ifdef HAVE_SYS_REG_H 
#include <sys/reg.h>
#endif

這裡我們只需要把conifg.h檔案中的#define HAVE_SYS_REG_H 1註釋掉就OK了。由於gdbserver是執行在ARM-linux平臺上的,因此需要使用交叉編譯器arm-linux-gcc,這可以通過給make加上CC引數來實現這裡我使用的是預設的,你也可以使用一個絕對的路徑來指定一個arm-linux-gcc.
   所有的工作都已經完成了,只要把生成的gdbserver下載到目標板上,或者是通過NFS掛載到目標板上就可能進行遠端的除錯了,如果就是足夠幸運的話,編譯中沒有出現什麼錯誤的話,這樣完全可以了,不過在我的系統上卻不是那麼幸運。我一直使用的是友善之臂的arm-linux-gcc-4.3.2交叉編譯器,這個版本的編譯器中,已經自帶了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://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 "--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版本的。一開始我並沒有注意arm-linux-gdb的版本資訊,不過在使用過程中,我把用生成的gdbserver的7.1版本用NFS載入到目標板上,而在宿主機上用的arm-linux-gcc 6.8版本,一直出現下面的錯誤:
先在目標機上執行下面的gdbserver,注意這裡的IP地址是宿主機上的IP地址。

[[email protected]]$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

然後在宿主機上執行

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://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 "--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命令時說是程式沒有執行,可是程式已經在目標板上運行了,不用輸入run命令,當輸入  target remote 10.27.10.23:9000結束後,在minicom中可以看到目標板上的輸出資訊有了變化.

[[email protected]]$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

   在這裡搗鼓了一整天沒有弄明白錯誤在那裡,看到了arm-linux-gdb 和gdbserver的版本不匹配,所以就變換arm-linux-gdb,這裡要把arm-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"

   當時一直在,arm-linux-gdb/bin目錄下執行,其實執行的也都是arm-linux-gcc-4.3.2中的arm-linux-gdb,如果這樣你看到的版本資訊還是6.8版本的話,也可以直接在arm-linux-gcc-4.3.2中把arm-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://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 "--host=x86_64-unknown-linux-gnu --target=arm-linux".
For bug reporting instructions, please see:
<http://www.gnu.org/software/gdb/bugs/>.

   使用GDB進行除錯,首先,我的宿主機的IP 10.27.10.48,開發板上的IP 10.27.10.23在開發板上執行gdbserver 10.27.10.48:9000 test,這裡是通過NFS,把要除錯的程式載入到目標版上面的。這樣就可從在宿主機上執行。

[email protected]:~/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://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 "--host=x86_64-unknown-linux-gnu --target=arm-linux".
For bug reporting instructions, please see:
<http://www.gnu.org/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

在目標板上的輸出:

[[email protected]]$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

補充:前面還有庫檔案錯誤的問題,這裡可以通過下面這樣的方法的來解決。需要說明的是,遠端除錯,可能程式動態庫,我們可以這樣設定:

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

除錯找不到原始碼,如下設定:

directory xfer-1.0.0/src/

下面是除錯的情況:

(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++)+

相關推薦

GDB遠端除錯技術---基於mini2440

GDB偵錯程式提供了兩種不同的除錯代理用於支援遠端除錯,即gdbserver方式和stub(插樁)方式。    這兩種遠端除錯方式是有區別的。gdbserver本身的體積很小,能夠在具有很少儲存容量的目標系統上獨立執行,因而非常適合於嵌入式環境;而stub方式則需要通過

GDB遠端除錯程式 & 生成core檔案便於除錯

# GDB遠端除錯程式 **該檔案是用於遠端除錯gdb,資料夾中的gdbserver和arm-linux-gdb的版本已經保持一致均為6.4** 1. target:`./gdbserver6.4 192.168.100.101:8888 ./test_scale`  2. hos

GDB遠端除錯(二)之用gdb解決segmentation-fault段錯誤,看gdb的使用(嵌入式)

最近在除錯程式碼的時候鬧人的segmentation-fault段錯誤,又來煩人了,不過程式碼都是自己寫的 ,有事也是作繭自縛,自作自受,先自責下。 來看看在串列埠段錯誤給了我們什麼資訊: 可以看出 Fault addr=0x328,出錯的地址在 0x328,這個哪 啊

Ubuntu下使用gdb遠端除錯android native程式筆記

使用gdb遠端除錯android native程式1.準備工作:android native程式:demoandroid 上執行的除錯工具:gdbserver,該程式位於ndk目錄/prebuilt/a

GDB遠端除錯程式 & 生成core檔案便於除錯

# GDB遠端除錯程式 **該檔案是用於遠端除錯gdb,資料夾中的gdbserver和arm-linux-gdb的版本已經保持一致均為6.4** 1. target:`./gdbserver6.4 192.168.100.101:8888 ./test_scale`  2

GDB遠端除錯錯誤解決 使用GDB 7.2版本進行遠端除錯時出現:Remote ‘g’ packet reply is too long錯誤

GDB遠端除錯錯誤解決使用GDB 7.2版本進行遠端除錯時出現:Remote ‘g’ packet reply is too long錯誤,需要修改gdb程式碼解決,辦法是:修改gdb/remote.c檔案,遮蔽process_g_packet函式中的下列兩行:if (bu

一種基於TLS的高階反除錯技術

盜版行為日益猖獗,嚴重影響到軟體開發者和開發商的智慧財產權及利益,反盜版技術的重要性也越來越引起人們的重視。在反盜版技術中,起最大作用的當屬反除錯技術。然而傳統的反除錯技術都存在一個弱點:他們都在程式真正開始執行之後才採取反除錯手段。實際上在反除錯程式碼被執行前,偵錯程式有大量的時間來影響程式的執行,甚至可以

Intellij IDEA基於Springboot的遠端除錯

簡介 本篇部落格介紹一下在Intellij IDEA下對Springboot型別的專案的遠端除錯功能。所謂的遠端除錯就是服務端程式執行在一臺遠端伺服器上,我們可以在本地服務端的程式碼(前提是本地的程式碼必須和遠端伺

遠端WEB控制MP3播放器設計(基於mini2440

網上有很多 基於mini2440的MP3播放器設計的資料,多是按鍵控制,這裡博主做了些輕微改動,利用遠端WEB來控制MP3播放,具體怎麼實現,下面會給出,大家先看看效果: WEB介面: 後臺執行: 因為不是什麼課程設計報告,博主就不闡述的那麼詳細,這個設計主要有三部分組

交叉編譯gdb+gdbserver實現遠端除錯

 總結一下linux下交叉編譯gdb並遠端除錯程式的知識  1.配置交叉編譯工具鏈到系統環境變數PATH下 export PATH=$PATH:'交叉編譯工具鏈的絕對路徑‘ 2.編譯主機端執行的gdb,但是處理的程式碼是arm平臺 ./configure --target=

Qt可用的gdb編譯,以及交叉編譯gdbserver,以及配置QtCreator遠端除錯

專案中用了ARM的板,希望配置gdbserver進行遠端除錯,結果卻遇到了很多問題。先把坑說了:1)要支援遠端除錯,arm板需要支援ssh2)要gdb能在Qt上用,必須在configure gdb的時候使用--with-python選項啟用python支援3)需要安裝pyth

基於遠端除錯閱讀Nomad原始碼_環境搭建

Nomad原始碼閱讀的遠端除錯環境搭建 簡要記錄遠端除錯環境搭建,方便除錯,閱讀Nomad原始碼。 環境 Remote VMWare 14 - 虛擬機器 Ubuntu 18.04 虛擬機器名local-dev2,IP地址192.168.2

arm-linux-gdb & gdbserver 遠端除錯工具的搭建與使用

     由於嵌入式系統資源有限性,一般不能直接在ARM上進行除錯,通常採用arm-linux-gdb+gdbserver的方式進行遠端除錯。Target端(ARM)使用 Gdbserver,host端(PC主機)使用arm-linux-gdb,雙方最好統一編譯工具鏈。在應用

PHP團隊開發和基於xdebug進行多人遠端除錯 for eclipse phpstorm

使用netbeans進行PHP團隊開發和基於xdebug進行多人遠端除錯 [2012/03/27 10:02] 不少的非單純PHP架構的網站系統中,PHP開發的Web系統,往往對特定的伺服器環境有依賴,例如使用php開發某些面向開放平臺的系統,或者帶有支付介面功能的系

遠端除錯spark原始碼(基於java的除錯工具)

開發人員在進行程式編碼的過程中,不可避免的需要對程式碼進行除錯,其目的是能精確定位程式的執行狀況。本文對spark原始碼進行除錯,此除錯方式可以除錯任何JVM相關的程式,如:普通的命令列程式、web程式等。 1、實驗環境 IP hostname maste

Qt 5.11.0使用gdb遠端部署和除錯

操作環境 PC: OS Debian9.4.0, Qt 5.11.0, IP: 192.168.1.10 BeagleBone Black: Debian 9.3.0, IP:

移植gdb工具-遠端除錯qt程式

轉自http://blog.163.com/[email protected]/blog/static/8725911920137685232272/ 一開始是根據此教程編譯http://www.qtcn.org/bbs/read-htm-tid-58074-ds

Java技術_基礎技術(0004)_eclipse遠端除錯tomcat

基礎技術: 遠端除錯tomcat步驟:  1==遠端登入至伺服器,開啟tomcat的bin/catalina檔案;  2==在JAVA_OPTS變數後增加:-Xdebug -Xrunjdwp

gdb除錯及gdbserver遠端除錯

     gdb偵錯程式是一款GNU開發組織併發布的UNIX/Linux下的程式除錯工具,具有強大的功能,足有與Visual Stido媲美,當然友好的介面是沒法相比的,呵呵。      開始編譯程式將除錯資訊包含進去,gdb偵錯程式執行在shell中輸入gdb就好,也可以輸

gdb 遠端qemu-arm除錯

把 c 編譯成 arm 指令的可執行檔案  /usr/bin/arm-linux-gnueabi-g++ hello.cpp  cat hello.cpp #include <stdio.h> void crash(){ char *a=0;