Qt可用的gdb编译,以及交叉编译gdbserver,以及配置QtCreator远程调试

1 篇文章 0 订阅
1 篇文章 0 订阅

项目中用了ARM的板,希望配置gdbserver进行远程调试,结果却遇到了很多问题。先把坑说了:

1)要支持远程调试,arm板需要支持ssh

2)要gdb能在Qt上用,必须在configure gdb的时候使用--with-python选项启用python支持

3)需要安装python-dev(2.7的包,不是3的),但是即使装了也可能链接失败,报PyUnicodeUCS2_????函数没有找到,需要define Py_UNICODE_WIDE

4)要成功启动远程调试,gdb和gdbserver必须是同一份源码编译出来的,而且make install之后的share目录也是必须的,否则gdb就不能正常启动


步骤一:编译gdb

python支持是gdb自带的,但是默认不开启,而python支持是Qt要求的,所以configure的时候使用--with-python将python支持打开,具体命令如下:

./configure CFLAGS="-O3" CXXFLAGS="-O3" --target=arm-linux --prefix=/opt/arm-linux-gdb/ --with-python     ————————命令(1)

这里--target后面是交叉编译工具链的前缀,比如交叉编译工具链的gcc是arm-linux-gcc,那就是arm-linux,--prefix是make install的目录。另外加了-O3增强了编译优化,而且没有了-g,取消了调试信息的生成。

但是configure之后make却可能报PyUnicodeUCS2_????函数没有找到的链接错误,这是因为python-dev的库里的函数是PyUnicodeUCS4_????。在include/python-2.7/unicodeobject.h里根据是否有定义Py_UNICODE_WIDE,将PyUnicode_???定义为PyUnicodeUCS2_????或PyUnicodeUCS4_????。但是,unicodeobject.h用的可能是交叉编译工具链目录下的文件,而不是python-dev包里的文件,所以直接改文件并不好,既然知道是根据否有定义Py_UNICODE_WIDE控制的函数名,在CFLAGS和CXXFLAGS中使用-D选项定义Py_UNICODE_WIDE就好了。所以,命令变为

./configure CFLAGS="-DPy_UNICODE_WIDE -O3" CXXFLAGS="-DPy_UNICODE_WIDE -O3"  --target=arm-linux --prefix=/opt/arm-linux-gdb/ --with-python     ————————命令(2)

如果没报链接错误,那么so中的函数就是PyUnicodeUCS2_????的了。如果需要先判断python-dev里的函数到底是2还是4,不想出错之后再来折腾,就需要找到libpython2.7.so的绝对路径,然后使用nm -D ???/libpython2.7.so | grep PyUnicode来查看so中的函数名是2还是4了。我在Ubuntu 14.04中的路径是/usr/lib/x86_64-linux-gnu/libpython2.7.so。

文末给出了完整的编译脚本,脚本是通过输出一个check.c,编译后执行,程序使用dlopen打开libpython2.7.so,并且尝试获取PyUnicodeUCS4_Decode的函数地址,如果能拿到就代表so的函数名是4,否则就是2。

建议使用make -j4或者-j8进行并发编译,虽然GDB的源码包不大(8.1的是37M),但是编译却需要出奇长的时间。make完之后make install,可以在/opt/arm-linux-gdb看到gdb的程序


步骤二:编译gdbserver

编译gdbserver,先切换目录到gdb/gdbserver,然后使用如下命令configure:

./configure CFLAGS="-O3" CXXFLAGS="-O3" --target=arm-linux --prefix=/opt/arm-linux-gdb/ --host=arm-linux  ----命令(3)

这里多了--host,代表gdbserver是在arm中运行的。configure之后可以make -j4和make install,没什么坑。最后arm-linux-gdbserver也是放到/opt/arm-linux-gdb/bin中,改名为gdbserver。


步骤三:建议压缩编译出来的可执行文件

切换到/opt/arm-linux-gdb/bin中,执行如下语句压缩可执行文件:

strip arm-linux-gdb arm-linux-run   ----命令(4)
arm-linux-strip gdbserver           ----命令(5)

strip是gcc套装里的一个工具,肯定有的,压缩运行在本地的arm-linux-gdb和arm-linux-run,arm-linux-strip在交叉编译工具链里,压缩运行在arm环境里的gdbserver。


步骤四:将新的gdb和gdbserver放入交叉编译工具链

这一步,将/opt/arm-linux-gdb/bin中arm-linux-gdb和arm-linux-run都拷贝到交叉编译工具链的bin目录,然后重点是要将/opt/arm-linux-gdb/share的内容也拷贝放入交叉编译工具链的share目录,否则gdb无法运行。然后下载gdbserver到arm系统的/usr/bin目录,gdbserver就成了命令可以直接运行了,不需要用/usr/bin/gdbserver或者./gdbserver来运行,或者设置链接了。


步骤五:配置QtCreator

首先配置调试器,找到新编译出来的arm-linux-gdb:


然后是配置构建套件,在调试器里选刚才配置的调试器名称


配置arm板的设备,确保arm板支持ssh,填好信息之后点test看看能不能连上


然后就可以开始调试了


最后给出完整的编译脚本,将gdb源码解压出来,把脚本放进去,使用chmod 777设置好权限,一键做完全部步骤,当然配置QtCreator还是要自己做的。编译脚本的make install目录就是/opt/arm-linux-gdb,交叉编译工具链的前缀是arm-linux,如果需要自定义的可以自己改。脚本的提示绿色是成功,红色是失败,黑色是其他的输出出问题再看吧。

#!/bin/bash
echo -e "\033[32m 正在执行步骤一:检查python-dev包 \033[0m"
chkpydev=$(dpkg -l | grep python-dev)
if [ "$chkpydev" == "" ]; then
	sudo apt-get install python-dev --force-yes
fi

echo "#include <stdio.h>" > check.c
echo "#include <dlfcn.h>" >> check.c
echo "int main() { void *handle; void *pPyUnicodeUCS4_Decode = NULL; handle = dlopen(\"libpython2.7.so\", RTLD_LAZY); if (!handle)return 1; dlerror(); pPyUnicodeUCS4_Decode = dlsym(handle, \"PyUnicodeUCS4_Decode\"); if (dlerror() != NULL)return 2; dlclose(handle); return 3; }" >> check.c
gcc -rdynamic -o check check.c -ldl && ./check
checkpy=$?
rm check
rm check.c

echo -e "\033[32m 正在执行步骤二:gdb的configure \033[0m"
case $checkpy in
    1)
	echo "没有找到libpython2.7.so"
	exit
    ;;
    2)
	./configure CFLAGS="-O3" CXXFLAGS="-O3" --target=arm-linux --prefix=/opt/arm-linux-gdb/ --with-python
    ;;
    3)
	./configure CFLAGS="-DPy_UNICODE_WIDE -O3" CXXFLAGS="-DPy_UNICODE_WIDE -O3" --target=arm-linux --prefix=/opt/arm-linux-gdb/ --with-python
    ;;
esac

echo -e "\033[32m 正在执行步骤三:编译和安装gdb \033[0m"
make -j8
if [ $? -eq 0 ]; then
    make install
    echo -e "\033[32m gdb已安装到/opt/arm-linux-gdb/目录下 \033[0m"
else
    echo -e "\033[31m gdb编译失败 \033[0m"
    exit
fi

echo -e "\033[32m 正在执行步骤四:gdbserver的confiure \033[0m"
cd gdb/gdbserver
./configure CFLAGS="-O3" CXXFLAGS="-O3" --target=arm-linux --prefix=/opt/arm-linux-gdb/ --host=arm-linux
 
echo -e "\033[32m 正在执行步骤五:编译和安装gdbserver \033[0m"
make -j8
if [ $? -eq 0 ]; then
    make install
    echo -e "\033[32m gdbserver已安装到/opt/arm-linux-gdb/目录下 \033[0m"
else
    echo -e "\033[31m gdbserver编译失败 \033[0m"
    exit
fi

echo -e "\033[32m 正在执行步骤六:压缩可执行文件,将gdb放入交叉编译工具链 \033[0m"
cd /opt/arm-linux-gdb/bin/
cp arm-linux-gdbserver gdbserver
arm-linux-strip gdbserver
echo "arm-linux-strip gdbserver"
strip arm-linux-gdb arm-linux-run
echo "strip arm-linux-gdb arm-linux-run"
gdb_path=$(which arm-linux-gdb)
cross_path=${gdb_path%/*}/..
mv $(which arm-linux-gdb) $cross_path/bin/arm-linux-gdb.bk
echo "mv $cross_path/bin/arm-linux-gdb $cross_path/bin/arm-linux-gdb.bk"
cp arm-linux-gdb $cross_path/bin
echo "cp arm-linux-gdb $cross_path/bin"
mv $(which arm-linux-run) $cross_path/bin/arm-linux-run.bk
echo "mv $cross_path/bin/arm-linux-run $cross_path/bin/arm-linux-run.bk"
cp arm-linux-run $cross_path/bin
echo "cp arm-linux-run $cross_path/bin"
cd ..
cp -rf share $cross_path
echo "cp -rf share $cross_path"
echo -e "\033[32m 已经将新的arm-linux-gdb放入交叉编译工具链目录$cross_path/bin \033[0m"
echo -e "\033[32m 完成 \033[0m"


### 回答1: gdbgdbserver远程调试技术的意义在于提供了一种方便有效的方式来调试运行在远程目标设备上的程序。这对于嵌入式系统或远程服务器等分布式系统的开发和调试非常有用。 首先,gdbgdbserver远程调试技术允许开发人员在不在本地环境下的目标设备上进行调试。这意味着开发人员可以通过网络连接到远程设备,并使用本地的gdb客户端来远程控制和调试目标设备上的程序。这样,不再需要将全部的代码和调试环境放在开发人员的本地机器上,大大节省了开发人员的时间和资源。 其次,远程调试技术提供了实时调试的能力。开发人员可以监控目标设备上的程序执行过程,并在运行时观察程序的状态和变量的值。这对于发现和解决运行时错误和异常非常重要。通过远程调试,开发人员可以更直接地了解程序在实际环境下的行为,从而更有效地修复问题。 此外,远程调试技术还提供了一个更加安全且可靠的调试方法。使用gdbgdbserver进行远程调试,可以避免将敏感的代码或数据复制到本地环境中,减少了潜在的安全风险。同时,由于远程调试是通过网络进行的,即使目标设备处于远程位置,也能够进行调试,减少了物理上接触设备的需求,提高了效率。 总而言之,gdbgdbserver远程调试技术的意义在于提供了一种方便、实时、安全的方法来远程控制和调试目标设备上的程序,使开发人员能够更有效地进行嵌入式系统和分布式系统的开发和调试工作。 ### 回答2: gdb gdbserver远程调试技术是一种用于在线调试嵌入式系统的工具。它的意义在于提供了一种便捷和高效的方式来调试远程的嵌入式设备。 首先,gdb gdbserver远程调试技术可以节省时间和资源。在传统的调试方式中,如果想要调试远程的嵌入式设备,通常需要将设备连接到开发服务器并使用串口进行调试。这种方式不仅繁琐,还占用了宝贵的硬件资源。而gdb gdbserver远程调试技术可以直接在目标设备上运行gdbserver,并通过网络连接到开发服务器上的gdb,使得调试变得更加方便快捷。 其次,gdb gdbserver远程调试技术可以提高团队协作效率。在实际的嵌入式系统项目中,通常会有多个开发人员同时开展工作。使用gdb gdbserver远程调试技术,不同的开发人员可以同时连接到同一个目标设备上进行调试,而不会相互干扰。这样可以提高团队成员之间的协作效率,加快问题解决和软件开发的速度。 此外,gdb gdbserver远程调试技术还提供了更灵活的调试方式。通过gdb gdbserver的支持,开发人员可以在目标设备上进行远程程序的调试,包括断点设置、变量查看、程序运行控制等。这种方式可以更加直观地观察到程序的实际执行情况,帮助开发人员更好地理解和解决问题。 总之,gdb gdbserver远程调试技术的意义在于提供了一种便捷、高效和灵活的嵌入式系统调试方式,节省了时间和资源,提高了团队协作效率,同时也方便开发人员更好地理解和解决问题。
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值