gdb和qtcreator遠程調試(遠程調試電腦和嵌入式linux)

最近在嵌入式平臺裏面跑程序,出現段錯誤,由於用的是release版,沒有相關調試信息,因此,學會用debug版本進行遠程調試調試就是當前需要學習的.

1.實驗1 兩臺linux系統遠程調試

首先有臺臺式機名字爲pc,筆記本名字爲notebook.
將pc作爲服務器

1.1gdb安裝和gdbserver安裝

由於兩臺電腦都安裝的ubantu14,因此自帶了gdb

1.2新建測試工程

新建remotedebug工程,工程目的是在調試的時候設置斷點查看下變量k.
main.cpp

#include <iostream>
using namespace std;
int main()
{
    int k=0;
    cout << "Hello World remote debug!" << endl;
    k++;
    return 0;
}

CMakeLists.txt加上debug選項add_compile_options(-g)

project(remotedebug)
cmake_minimum_required(VERSION 2.8)
add_compile_options(-g)
aux_source_directory(. SRC_LIST)
add_executable(${PROJECT_NAME} ${SRC_LIST})

1.3遠程調試

1.3.1使用qtcreator進行遠程調試

參考博客
https://blog.csdn.net/aristolto/article/details/52045217
注意,我在pc機上進行以下操作,遠程控制notebook
(1)首先獲取ip地址
ifconfig
pc機ip 爲192.168.233.138 notebook ip 爲192.168.233.115
(2)切換到編譯好的程序文件目錄,把編譯好的程序romotedebug放到notebook的主文件夾/home/rootroot/下

scp remotedebug rootroot@192.168.233.115:/home/rootroot/

(3)使用ssh登錄到notebook

ssh rootroot@192.168.233.115

發現能夠成功.
(4)在notebook中啓動gdb server

gdbserver 192.168.233.138:8888 /home/rootroot/remotedebug 

192.168.233.138是pc的IP,8888是通信端口/home/rootroot/remotedebug是要調試的可執行程序.

提示沒有安裝gdbserver
notebook安裝gdbserver

sudo apt-get install gdbserver

再次執行
輸出
這裏寫圖片描述

4.在Qtcreator中進行設置
Debug—>Start Debugging—>Attach to Rmote Debug Server..
這裏寫圖片描述

server port填入端口,override server address填入notebook ip地址,local executable填入本地的編譯好的文件remotedebug
點擊調試後就可以開始調試了

2.實驗2 嵌入式系統OpenWRT遠程調試

參考https://blog.csdn.net/srf1986/article/details/47428021
在嵌入式中開發過程中使用gdb遠程調試一定要分清楚gdb的類型
gdb有三種:
(1) 安裝到目標機上,在目標機上運行的gdb。(通過SSH在目標機上運行gdb調試)
(2)運行在開發機上,用於調試目標機上程序的。(通過SSH在目標機上運行gdbserver開啓調試服務,在開發機上啓動平臺對應的gdb連接gdbserver進行調試)
(3)運行在開發機上,用於調試開發機程序的(ubantu14.04LTS自帶的)。
我的ubantu14.04LTS自帶的版本爲gdb-7.7.1
而OpenWRT 中的版本爲gdb-7.10.1,因此不能使用自帶的版本來調試,版本不對應會出現Connecting to remote server failed: Remote ‘g’ packet reply is too long錯誤.
注意:本實驗我的目標機爲OpenWRT,開發機爲pc

2.1開發機上gdb和gdbserver安裝

2.1.1 下載gdb-7.10.1.tar.gz

wget http://ftp.gnu.org/gnu/gdb/gdb-7.10.1.tar.gz

2.1.2編譯安裝pc版本的gdb

(1) tar xvzf gdb-7.10.1.tar.gz
(2)./configure –target=arm-openwrt-linux –prefix==/home/rootroot/ProgramFiles/gdbOpenwrt
(其中編譯、安裝後的可執行文件放到/home/rootroot/ProgramFiles/gdbOpenwrt,這個目錄可自定義)
(3)make
(4)make install
編譯安裝完後在/home/rootroot/ProgramFiles/gdbOpenwrt/bin/看到文件arm-openwrt-linux-gdb

2.1.3編譯openwrt上運行的gdb和gdbserver

由於我沒有編譯通過openwrt上運行的gdb和gdbserver,用的是別人編譯好的這個版本,所以以下步驟僅供參考
(1)還是進入解壓完的gdb-7.10.1下的gdb/gdbserver/
(2)./configure –target=arm-openwrt-linux –prefix=/home/rootroot/ProgramFiles/gdbOpenwrtR16
(3)make CC=arm-openwrt-linux-gcc(其中arm-openwrt-linux-gcc爲我的編譯器)
(4)make install 安裝到gdbOpenwrtR16中
(5)將 gdb和gdbserver拷貝到OpenWRT

2.2新建測試工程

測試工程threaddebugtest啓動兩個線程,World()線程當k==10時,給一個空地址賦值,出現個段錯誤.目標是遠程調試時發現程序死的位置.
main.cpp

#include <iostream>
#include<thread>
#include<unistd.h>
#include<mutex>
using namespace std;
std::mutex mymutex;
class Hello{
public:
    Hello();
    ~Hello();
void  RunSayHello();
};
Hello::Hello(){

}
void Hello::RunSayHello()
{
    while(1)
    {
        {
            unique_lock<mutex> lock(mymutex);
        }
        cout<<endl<<"hello"<<endl;
        sleep(1);
    }
}

class World{
public:
    World();
    ~World();
void  RunSayWorld();
};
World::World(){

};
void World::RunSayWorld()
{
    int k=0;
    while(1)
    {
        {
            unique_lock<mutex> lock(mymutex);
        }    
         cout<<endl<<"k= "<<k<<" world"<<endl;
         k++;
         if(k==10)
         {
             char *p;
             p = NULL;
             *p = 'x';
             printf("%c", *p);
         }
         sleep(1);
    }
}

int main()
{
    Hello* hello=new Hello();
    World* world=new World();

     thread threadHello(&Hello::RunSayHello,hello);
     thread threadWorld(&World::RunSayWorld,world);
     threadHello.join();
     threadWorld.join();
   return 0;
}

CMakeLists.txt 加上嵌入式編譯器參數

project(threaddebugtest)
cmake_minimum_required(VERSION 2.8)
SET(CMAKE_C_COMPILER arm-openwrt-linux-gcc)
SET(CMAKE_CXX_COMPILER arm-openwrt-linux-g++)
add_compile_options(-Os -pipe -march=armv7-a -mtune=cortex-a7 -mfpu=neon -fno-caller-saves -fno-plt -mfloat-abi=hard
-Wformat -Werror=format-security -fstack-protector -D_FORTIFY_SOURCE=1 -Wl,-z,now -Wl,-z,relro -Wno-virtual-dtor -std=c++11
 -D__ANDROID__ -pthread -g)
aux_source_directory(. SRC_LIST)
add_executable(${PROJECT_NAME} ${SRC_LIST})

2.3嵌入式遠程調試

2.3.1 gdb調試

(1)首先獲取ip地址
ifconfig
pc機ip 爲192.168.233.138 arm ip 爲192.168.233.103
(2)編譯工程,切換到編譯好的程序文件目錄,把編譯好的程序threaddebugtest放到openwrt的文件夾/mnt/UDISK/下

scp threaddebugtest root@192.168.233.103:/mnt/UDISK/

(3)使用ssh登錄到openwrt

ssh rootroot@192.168.233.103

發現能夠成功.
(4)在openwrt中啓動gdb server

gdbserver 192.168.233.138:8888 /mnt/UDISK/threaddebugtest

192.168.233.138是pc的IP,8888是通信端口,/mnt/UDISK/threaddebugtest是要調試的可執行程序.
輸出爲
Process /mnt/UDISK/threaddebugtest created; pid = 708
Listening on port 8888
(5)在pc中啓動gdb 遠程調試程序
切換到pc機的threaddebugtest目錄,
執行pc機上的arm-openwrt-linux-gdb

 ~/ProgramFiles/gdbOpenwrt/bin/arm-openwrt-linux-gdb threaddebugtest

在gdb中輸入

target remote 192.168.233.103:8888

192.168.233.103爲openwrt ip地址
這裏寫圖片描述
在gdb中輸入continue運行程序
如圖可以看到k=9是出現錯誤信息
這裏寫圖片描述

2.3.2使用Qtcreator調試

(1)首先要增加一個kits
這裏寫圖片描述
如圖,add 一個名字爲OpenWRT的kit, 設置編譯器爲
arm-openwrt-linux-gcc
調試器爲剛剛在電腦上編譯的gdb
arm-openwrt-linux-gdb
注意下面的
Qt version一定要選NONE否則kit增加失敗,前面會是紅色警告

(2)進行遠程調試
選擇Debug—>Start Debugging—>Attach to Rmote Debug Server..
kit 選擇OpenWRT ,server port填入端口,override server address填入openwrt ip地址,local executable填入本地的編譯好的文件threaddebugtest
如圖

這裏寫圖片描述
啓動後終於成功了!

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章