最近在嵌入式平臺裏面跑程序,出現段錯誤,由於用的是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
如圖
啓動後終於成功了!