新聞中心

        EEPW首頁 > 嵌入式系統 > 設計應用 > 建立ARM平臺上的交叉調試器gdb和gdbserver

        建立ARM平臺上的交叉調試器gdb和gdbserver

        作者: 時間:2016-11-11 來源:網絡 收藏
        (有的時候執行環境的權限真的是很重要的)

        gdb-6.6使用了autoconf/automake,因此通過設置configure腳本的--target,--host,--prefix參數就可以方便的移植到別的平臺。

        本文引用地址:http://www.104case.com/article/201611/316783.htm

        --target指定編譯后的文件針對的是什么目標板,一般設置為交叉編譯器的前綴,比如--target=arm-linux, --target=mips-linux,--target=armv5-linux-uclibc, --target的缺省值為i386-linux, 也就是PC機。

        --host指定編譯后的文件的運行環境,取值可以是i386-linux或者交叉編譯器的前綴,缺省為i386-linux,

        --prefix指定要安裝的目錄。

        1、到http://www.gnu.org/software/gdb下載gdb-6.6.tar.gz到/tmp解壓到/opt下
        #cd /opt
        #tar xzvf /tmp/gdb-6.6.tar.gz

        2、建立配置文件、編譯
        gdb允許把編譯配置和編譯結果放到任意的目錄,因此可以在gdb目錄之外建立一個專門放編譯文件的目錄。
        #cd /opt
        #mkdir -p arm-gdb/build
        #cd arm-gdb/build

        #/opt/gdb-6.6/configure --host=i386-linux --target=armv5-linux-uclibc --prefix=/opt/arm-gdb
        #make
        #make install
        其中:host指定了運行環境為i386機器,target指定了需要調試的目標機環境(我使用的ARM toolchain是armv5-linux-uclibc-gcc,因此這樣指定,如果是用arm-linux-gcc,則 --target=arm-linux),prefix指定了編譯后的結果存放的位置,也就是安裝目錄。
        如果在編譯arm-linux-low.c這個文件時提示找不到“sys/reg.h”, 則修改arm-linux-low.c,注釋掉#include "sys/reg.h"。

        可以在/opt/arm-gdb/bin下找到可執行的armv5-linux-uclibc-gdb, armv5-linux-uclibc-gdbtui, armv5-linux-uclibc-run。

        3、gdbserver的移植
        gdbserver要用到gdb源碼目錄下的一些頭文件,因此無法在gdb源碼目錄之外建立編譯文件。

        #cd /opt/gdb-6.6/gdb/gdbserver
        #vi build.arm
        內容如下:
        ./configure --target=armv5-linux-uclibc --host=armv5-linux-uclibc --prefix=/opt/arm-gdb/gdbserver
        make
        make install
        #chmod +x build.arm
        #./build.arm

        注意:此處target參數和host參數都要設置為armv5-linux-uclibc,因為gdbserver是放在目標板上運行的。
        編譯后,可以在/opt/arm-gdb/gdbserver/bin下找到armv5-linux-uclibc-gdbserver,下載該文件到目標板并重命名為gdbserver,
        同時要下載gdbserver需要的庫文件libthread_db-x.x.x.so,再建立兩個符號鏈接libthread_db.so和libthread_db.so.1。


        4、使用gdbserver
        在目標板上運行gdbserver
        #./gdbserver 192.168.0.2:2345 hello

        其中192.168.0.2為目標板的IP,可以寫localhost,也可以不寫。2345為gdbserver打開的端口,可以自己設置。
        #./gdbserver :2345 hello

        在宿主機上運行
        #armv5-linux-uclibc-gdb hello
        (gdb)target remote 192.168.0.2:2345
        (gdb)b main
        (gdb)continue

        使用X-Windows下的DDD
        #ddd --debugger armv5-linux-uclibc-gdb

        在DDD的GDB終端控制窗口中健入:
        (gdb) target 192.168.0.2:2345

        6、問題
        移植的gdbserver可以和Host上的mips-linux-gdb連接上,但是run的時候gdbserver出現
        Killing inferior錯誤
        解決方法:因為執行完target命令后,目標板程序已經在運行,所有應該用continue命令而不是run命令。


        7、附1:GDB的基本指令:

        load:裝入一個程序
        symbol-file:裝入符號庫文件,可以是用-g參數編譯的可執行文件。
        f(ile):指定一個可執行文件進行調試,gdb將讀取些文件的調試訊息,如f a.exe
        l(ist):列程序出源文件
        r(un) :裝載完要調試的可執行文件后,可以用run命令運行可執行文件
        b(reak):設置斷點(break point),如b 25,則在源程序的第25行設置一個斷點,當程序執行到第25行時,就會產生中斷;也可以使用b funcname,funcname為函數的名稱,

        當程序調用些函數時,則產生中斷
        c(ontinue):c命令可以另中斷的程序繼續執行,直到下一個中斷點或程序結束
        p(rint):輸入某個變量的值,如程序定義了一個int aa的就是,p aa就會輸出aa的當前值
        n(ext):程序執行到斷點時中斷執行,可以用n指令進行單步執行
        s(tep):程序執行到斷點時中斷執行,可以用s指令進行單步執行進某一函數
        q(uit):退出GDB

        8、附2:調試驅動程序和共享庫

        (1)調試LKM(Loadable Kernel Module)
        .在目標板上插入模塊并輸出map信息,查看.text入口地址:
        #insmod -m hello.ko > map
        #grep .text map
        比如為0xc68c0060
        .在gdb中轉入LKM的調試信息:
        (gdb) add-symbol-file hello.ko 0xc68c0060 /*注意必須是LKM .text的入口地址)
        .正常調試

        (2)調試共享庫
        .樣例程序:
        test.c:
        #include
        int test(int a, int b)
        {
        int s = a b;
        printf("%dn", s);
        return s;
        }

        main.c:
        #include
        extern int test(int a, int b);
        int main(int argc, char* argv[])
        {
        int s = test(10, 20);
        return s;
        }

        Makefile:
        all: so main
        so:
        armv5-linux-uclibc-gcc -g test.c -shared -o libtest.so
        main:
        armv5-linux-uclibc-gcc -g main.c -L./ -ltest -o test.exe
        clean:
        rm -f *.exe *.so

        .編譯并設置環境變量
        #make

        在目標板上:
        #export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:./
        #gdbserver localhost:2345 ./test.exe

        .運行gdb客戶端
        #armv5-linux-uclibc-gdb
        (gdb)symbol-file test.exe
        (gdb)target remote 192.168.0.2:2345
        (gdb)b main
        (gdb)c

        .查看libtest.so的代碼在內存中的位置。
        (從gdbserver的輸出或者用ps可以得到test.exe的進程ID,這里假設PID是11547)
        在目標板上:
        #cat /proc/11547/maps
        輸出:

        .........
        0076a000-0076c000 rwxp 0076a000 00:00 0
        00bbe000-00bbf000 r-xp 00bbe000 00:00 0
        00fcc000-00fcd000 r-xp 00000000 03:01 1238761 /root/test/gdbservertest/libtest.so
        00fcd000-00fce000 rwxp 00000000 03:01 1238761 /root/test/gdbservertest/libtest.so
        08048000-08049000 r-xp 00000000 03:01 1238765 /root/test/gdbservertest/test.exe
        08049000-0804a000 rw-p 00000000 03:01 1238765 /root/test/gdbservertest/test.exe
        ........

        由此可以知道:libtest.so的代碼在00fcc000-00fcd000之間。

        .查看libtest.so的.text段在內存中的偏移位置:
        armv5-linux-uclibc-objdump -h libtest.so |grep .text
        輸出:
        .text 00000130 00000450 00000450 00000450 2**4
        即偏移位置為0x00000450

        .回到板子上的gdb窗口,加載libtest.so的符號表。
        (gdb)add-symbol-file libtest.so 0x00fcc450
        (這里0x00fcc450 = 0x00fcc000 0x00000450)

        .在共享庫的函數中設置斷點
        (gdb)b test

        .繼續調試共享庫



        評論


        技術專區

        關閉
        主站蜘蛛池模板: 新昌县| 百色市| 防城港市| 乃东县| 仲巴县| 安乡县| 交城县| 垫江县| 津南区| 安岳县| 吕梁市| 桓台县| 河源市| 讷河市| 宁波市| 溧水县| 阳谷县| 南昌市| 来安县| 井冈山市| 桐城市| 仪征市| 台南县| 门源| 平凉市| 衡阳县| 辽阳县| 洛南县| 禹城市| 福州市| 甘谷县| 鹤山市| 阳城县| 齐河县| 抚宁县| 嘉善县| 威信县| 景谷| 宿州市| 江孜县| 灵石县|