嵌入式Linux系統的GDB調試__Linux

來源:互聯網
上載者:User
標題:嵌入式Linux的GDB遠端偵錯的實現 2008-01-11 11:22:08
嵌入式Linux的GDB遠端偵錯的實現

Author: Vicky 

遠端偵錯環境由宿主機GDB和目標機調試stub共同構成,兩者通過串口或TCP串連。使用GDB標準遠程串列協議協同工作,實現對目標機上的系統核心和上層應用的監控和調試功能。調試stub是嵌入式系統中的一段代碼,作為宿主機GDB和目標機偵錯工具間的一個媒介而存在。

就目前而言,嵌入式Linux系統中,主要有三種遠端偵錯方法,分別適用於不同場合的調試工作:用ROM Monitor偵錯目標機程式、用KGDB調試系統核心和用gdbserver調試使用者空間程式。這三種調試方法的區別主要在於,目標機遠端偵錯stub的存在形式的不同,而其設計思路和實現方法則是大致相同的。
而我們最常用的是調試應用程式。就是採用gdb+gdbserver的方式進行調試。在很多情況下,使用者需要對一個應用程式進行反覆調試,特別是複雜的程式。採用GDB方法調試,由於嵌入式系統資源有限性,一般不能直接在目標系統上進行調試,通常採用gdb+gdbserver的方式進行調試。Gdbserver在目標系統中運行,gdb則在宿主機上運行。

要進行GDB調試,目標系統必須包括gdbserver程式,宿主機也必須安裝gdb程式。一般linux發行版中都有一個可以啟動並執行gdb,但開發人員不能直接使用該發行版中的gdb來做遠端偵錯,而要擷取gdb的原始碼包,針對arm平台作一個簡單配置,重新編譯得到相應gdb。gdb的原始碼包可以從

http://ftp.cs.pu.edu.tw/Linux/sourceware/gdb/releases/下載,最新版本為gdb-6.4。下載到某個目錄,筆者下載到自己的使用者目錄:/home/vicky。
下載完後,進入/home/vicky目錄,配置編譯步驟如下:
#tar jxvf gdb-6.4-tar-bz2
#cd gdb-6.4
#./configure --target=arm-linux --prefix=/usr/local/arm-gdb -v
#make
(這一步的時候可能會有問題,提示一個函數中(具體函數名不記得了)parse error,就是unsigned前邊多了一個”}”,你用vi進入那一行把它刪掉就行了。)
#make install
#export PATH=$PATH:/usr/local/arm-gdb
進入gdbserver目錄:
#./configure --target=arm-linux –host=arm-linux
#make CC=/usr/local/arm/2.95.3/bin/arm-linux-gcc
(這一步要指定arm-linux-gcc的位置,可能跟你的不一樣)
沒有錯誤的話就在gdbserver目錄下產生gdbserver可執行檔,把它燒寫到flash的根檔案系統分區,或通過nfs mount的方式都可以。只要保證gdbserver能在開發板上運行就行。
下面就可以用gdb+gdbserver調試我們開發板上的程式了。在目標板上運行gdbserver,其實就是在宿主機的minicom下,我的red hat linux裝在vmware下的。我是在minicom下#mount 192.168.2.100:/ /tmp後做的(這裡參數-o nolock可以不加,不加這一步執行得反而更快些),hello和gdbserver都是位於linux根目錄下,把主機根目錄掛在到開發板的/tmp目錄下。
要進行gdb調試,首先要在目標系統上啟動gdbserver服務。在gdbserver所在目錄下輸入命令:
(minicom下)
#cd /tmp
#./gdbserver 192.168.2.100:2345 hello
192.168.2.100為宿主機IP,在目標系統的2345連接埠開啟了一個調試進程,hello為要調試的程式。
出現提示:
Process /tmp/hello created: pid=80
Listening on port 2345

(另一個終端下)
#cd /
#export PATH=$PATH:/usr/local/arm-gdb/bin
#arm-linux-gdb hello
(gdb) target remote 192.168.2.223:2345
(192.168.2.223為開發板IP)
出現提示:
Remote debugging using 192.168.2.223:2345
[New thread 80]
[Switching to thread 80]
0x40002a90 in ??()
同時在minicom下提示:
Remote debugging from host 192.168.2.100
(gdb)
串連成功,這時候就可以輸入各種gdb命令如list、run、next、step、break等進行程式調試了。

以上針對通過nfs mount和tftp的方式,只能在主機上調試好後下載到開發板上運行,如果有錯誤要反覆這個過程,繁瑣不說,有些程式只能在開發板上調試。所以筆者採用了gdbserver的遠端偵錯方式。希望對大家偵錯工具有用。

摘自華恒支援人員論壇嵌入式技術園地

本文引用地址:http://lionwq.spaces.eepw.com.cn/articles/trackback/item/16810


CROSS-GDB 嵌入式linux的 交叉調試 2009-12-02 0:11

從http://ftp.gnu.org/gnu/gdb下載GDB原始碼--gdb-6.2.1.tar.bz2
1-編譯GDB用戶端:
#cd gdb-6.2.1
#./configure --target=arm-linux --prefix=/root/arm-gdb -v
#make                          //期間有可能會有錯誤,見上面

Iwmmxt.c: 在函數 ‘WMAC’ 中:
iwmmxt.c:2117: 錯誤:賦值運算中的左值無效
iwmmxt.c:2133: 錯誤:賦值運算中的左值無效
iwmmxt.c: 在函數 ‘WMADD’ 中:
iwmmxt.c:2169: 錯誤:賦值運算中的左值無效
iwmmxt.c:2177: 錯誤:賦值運算中的左值無效
iwmmxt.c:2186: 錯誤:賦值運算中的左值無效
iwmmxt.c:2191: 錯誤:賦值運算中的左值無效
iwmmxt.c: 在函數 ‘WSLL’ 中:
iwmmxt.c:2840: 警告:對 ‘long’ 類型而言整數常量太大
iwmmxt.c: 在函數 ‘WSRA’ 中:
iwmmxt.c:2917: 警告:對 ‘long’ 類型而言整數常量太大
iwmmxt.c:2917: 警告:對 ‘long’ 類型而言整數常量太大
iwmmxt.c:2919: 警告:對 ‘long’ 類型而言整數常量太大
iwmmxt.c: 在函數 ‘WSRL’ 中:
iwmmxt.c:2988: 警告:對 ‘long’ 類型而言整數常量太大
iwmmxt.c: 在函數 ‘WUNPCKEH’ 中:
iwmmxt.c:3290: 警告:對 ‘long’ 類型而言整數常量太大
iwmmxt.c: 在函數 ‘WUNPCKEL’ 中:
iwmmxt.c:3357: 警告:對 ‘long’ 類型而言整數常量太大
iwmmxt.c: 在函數 ‘Fetch_Iwmmxt_Register’ 中:
iwmmxt.c:3707: 警告:隱式聲明與內建函數 ‘memcpy’ 不相容
iwmmxt.c:3712: 警告:隱式聲明與內建函數 ‘memcpy’ 不相容
iwmmxt.c: 在函數 ‘Store_Iwmmxt_Register’ 中:
iwmmxt.c:3722: 警告:隱式聲明與內建函數 ‘memcpy’ 不相容
iwmmxt.c:3727: 警告:隱式聲明與內建函數 ‘memcpy’ 不相容
make[2]: *** [iwmmxt.o] 錯誤 1
make[2]: Leaving directory `/root/Documents/gdb-6.2.1/sim/arm'
make[1]: *** [all] 錯誤 2
make[1]: Leaving directory `/root/Documents/gdb-6.2.1/sim'
make: *** [all-sim] 錯誤 2


根據上面的提示找到錯誤的檔案和在檔案的那一行:
c:2117: error: invalid lvalue in assignment
c:2133: error: invalid lvalue in assignment
c:2169: error: invalid lvalue in assignment
c:2177: error: invalid lvalue in assignment
c:2186: error: invalid lvalue in assignment
c:2191: error: invalid lvalue in assignment

方法同上,都是改gdb壓縮包的檔案,這次改的是
gdb-6.2.1/sim/arm/iwmmxt.c檔案裡的:

第2117、2133、2169、2177、2186、2191行;

方法如下:

將2117行的    (signed long long) t += s;   
改成        (signed long long)t;    t = (signed long long)(t + s);


將2133行的    (signed long long) wR[BITS (12, 15)] += (signed long long) t;   
改成    {(signed long long) wR[BITS (12, 15)];    wR[BITS (12, 15)] = (signed long long)(wR[BITS (12, 15)] + t);}


將2169行的    (signed long) s1 = a * b;   
改成    (signed long) s1;    s1 =(signed long)(a * b);


將2177行的    (signed long) s2 = a * b;
改成    (signed long) s2;    s2 =(signed long)(a * b);


將2186行的    (unsigned long) s1 = a * b;
改成    (unsigned long) s1;    s1 =(unsigned long)(a * b);


將2191行的    (signed long) s2 = a * b;
改成    (unsigned long) s2;    s2 =(unsigned long)(a * b);



編譯Gdbserver:

linux-arm-low.c:26:21: error: sys/reg.h: No such file or directory
make: *** [linux-arm-low.o] 錯誤 1

根據在linux-arm-low.c中:
#ifdef HAVE_SYS_REG_H
#include <sys/reg.h>
#endif

在gdb/gdbserver/config.h修改如下:
/* Define if you have the <sys/reg.h> header file.  */
#define HAVE_SYS_REG_H 1

/* Define if you have the <sys/reg.h> header file.  */
//#define HAVE_SYS_REG_H 1 省略


#make install
#vi ~/.bash_profile        修改:PATH=$PATH:/root/arm-gdb/bin
#source ~/.bash_profile
#arm-linux-gdb -v

2-編譯Gdbserver
#cd gdb-6.2.1
#./configure --target=arm-linux --host=arm-linux
#cd gdb/server
#./configure --target=arm-linux --host=arm-linux
修改 gdb/gdbserver/config.h   :      #define HAVE_SYS_REG_H 1    --> //#define HAVE_SYS_REG_H 1
#make CC=arm-linux-gcc
把gdb/gdbserver目錄下的gdbserver複製到開發板系統(嵌入式linux)的/bin下
執行個體:
//hello.c
#include<stdio.h>
#include<string.h>
int main()
{
char *str=NULL;
strcpy(str,"hello");
printf("str is %s\n",str);
return 0;
}    

#arm-linux-gcc -g hello.c -o hello
設定主機IP地址為:192.168.1.10,開發板系統IP地址為:192.168.1.230(一般只需設定成同一個網段就行),
在開發板中:
#gdbserver 192.168.1.230:1234 hello
Process test created:pid=80   //使gdbserver在1234連接埠監聽。
在主機中:
#arm-linux-gdb
(gdb) target remote 192.168.1.230:1234    //若連結成功,開發板的串口終端會顯示如下:
Remote debugging from host 192.168.1.10
(gdb) symbol file  hello                               //此處的hello是PC機上的所在路徑的hello
(gdb) list
(gdb) break 5
(gdb) continuing
(gdb) step                //會提示出現段錯誤(通常有記憶體的非法訪問引起的)


常用的gdb調試命令:(某些唯一開頭字母的命令可用開頭字母直接替代,也可用Tab來顯示其完整的命令名)
file 檔案名稱        在gdb中載入某可執行檔                    symbol file hello
break n            設定斷點                                break 5
info                 查看和可執行程式相關的各種資訊      info breakpoint   delete/disable/enable breakpoint num
kill                終止正在調試的程式
print                顯示變數或者運算式的值
set args         設定偵錯工具的運行參數
watch                在程式中設定觀測點(如果資料改變,將給出變化前後的情況)
delete            刪除設定的某個斷點或觀測點
clear                刪除設定的某個斷點或觀測點
continue            從斷點處繼續執行程式
list                列出gdb中載入的可執行程式的代碼
run                運行在gdb中載入的可執行程式
next                逐步執行所載入的程式
step                單步,可進入函數內,查看執行情況(用finish回到調用處)
whatis            查看變數或函數類型
pype                顯示資料結構定義情況
make                在不退出gdb情況下,編譯器
quit                退出gdb

gdb調試帶參數的程式

gdb --args ./testprg arg1 arg2

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

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.