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
如图

这里写图片描述
启动后终于成功了!

猜你喜欢

转载自blog.csdn.net/ktigerhero3/article/details/80026306
今日推荐