工作需要用到跨平台开发,原来都是先在windows下用vs2010开发,调试,调试好之后直接使用linux虚拟机进行编译,然后在目标机上部署,但是遇到只在linux下才能运行的代码就比较麻烦,有限的调试手段就是printf,有诸多的不便。
在逐渐摸索使用工具对目标机进行在线调试的过程中遇到很多的问题,记录下来
从几个方面进行尝试。
1.使用vs进行跨平台开发。
使用vs2019进行跨平台开发,见另一篇文章
2.使用vscode配合gdb和gdbserver进行调试
我的想法是在目标机上运行gdbserver,然后使用vscode配合gdb进行调试。但是由于版本问题,遇到了非常多的问题,将问题记录下来。
参考之前一篇 GDB和GDBServer
https://blog.csdn.net/jewelsu/article/details/102801789
我直接使用编译环境的系统连接目标机使用gdb可以调试了。但是因为是命令行工具,所以不太方便,所以希望挂上vscode来用
2.1 版本问题
为什么会有版本问题呢?因为历史原因,目标机使用的是centos6.4 x86架构。编译环境也是一样的,我称为编译机。这两个都不可更改。下面慢慢来将为什么这会成为障碍
2.2vscode远程调试
vscode是有远程调试功能的,就是代码可以在远程,使用本地的vscode来编辑。如果这样的话就可以使用vscode调用编译环境下的代码,然后直接使用编译环境下的gdb配合目标机上的gdbserver调试了。
但是悲催的是vscode这个功能需要centos7+.
于是想到另一个方案,使用vscode remote wsl,在本机的wsl上运行gdb,目标机运行gdbserver。
2.3vscode使用remote wsl
https://blog.csdn.net/jewelsu/article/details/102811559
2.3.1 64位和32位的问题
使用wsl编译了一个简单的程序,在wsl上调试都没有问题。但是我需要在wsl上运行可以在目标机上运行的程序,于是我用编译机重新编了这个程序,在wsl上运行,失败,报错:
cannot execute binary file: Exec format error
后来想到,我的wsl是64位系统,而目标机和编译机都是32位的,64位系统是不能直接执行32位程序的。
2.3.2在64位ubuntu上安装32位库
参考Ubuntu 14.04 64位系统兼容32位库 https://blog.csdn.net/hpu11/article/details/81381246
dpkg --print-architecture 查看架构
dpkg --print-foreign-architectures 查看是否开启32位兼容架构
sudo dpkg --add-architecture i386 增加32位架构
sudo apt-get update 更新列表
sudo apt-get -f dist-upgrade 更新程序
sudo apt-get install libc6:i386 libstdc++6:i386 安装32位库
仍然没法运行。
2.3.3在64位ubuntu上编译32位程序
经过一番折腾,我现在怀疑是不是因为编译环境的原因,编译用到的库版本不一致导致wsl执行不了我在目标机上运行的程序,那么我直接在wsl上面编译个32位程序,自己运行试一下呢
参考 看我linux(ubuntu)下的64位编译器编译32位程序 https://blog.csdn.net/msdnwolaile/article/details/50185103
sudo apt-get install gcc-multilib g++-multilib 安装gcc的多平台支持,否则会报错找不到文件
编译时增加选项-m32,编译出来使用file命令查看就可以看到是32位的程序了
2.3.4让wsl64位支持32位库
非常悲催的是,经过了以上的折腾,还是运行不了,同样的错误,这时候才想到是不是因为是wsl的原因。
查到一篇文章 WSL问题之32位程序运行 https://blog.csdn.net/u012742966/article/details/70307691
上面写着
-------------------------------------------
普通的64位linux是有办法运行32位的程序的
但是我经过大量的实验,发现WSL上无法运行ELF 32-bit LSB executable 等32位程序
在这里有官方说明
https://github.com/Microsoft/BashOnWindows/issues/390
Currently WSL only supports amd64 (native 64bit).
————————————————
这可如何是好,但是当我要灰心的时候,又看到一篇
让win10的WSL子系统支持32bit程序 https://blog.csdn.net/shengerjianku/article/details/82290482
看来还是有希望的。
Presuming a fresh Ubuntu WSL instance, you'll need to install the qemu-user-static package, add the i386 binfmt, enable the i386 architecture, update your package lists, and install some i386 packages:
Install qemu and binfmt
-
sudo apt update
-
sudo apt install qemu-user-static
-
sudo update-binfmts --install i386 /usr/bin/qemu-i386-static --magic '\x7fELF\x01\x01\x01\x03\x00\x00\x00\x00\x00\x00\x00\x00\x03\x00\x03\x00\x01\x00\x00\x00' --mask '\xff\xff\xff\xff\xff\xff\xff\xfc\xff\xff\xff\xff\xff\xff\xff\xff\xf8\xff\xff\xff\xff\xff\xff\xff'
[Edit: whoops, need to update package lists, added sudo apt update
]
This will activate i386 support by causing them to be executed through qemu-i386-static, and drop a config file into /var/lib/binfmts/
for future reactivation.
You will need to reactivate this every time you restart WSL and want i386 support:
sudo service binfmt-support start
Enable i386 architecture and packages
-
sudo dpkg --add-architecture i386
-
sudo apt update
-
sudo apt install gcc:i386
显然后面的步骤在2.3.2已经做了,
经过这个步骤,终于可以运行我的32位程序了。
2.3.5 wsl上运行gdb调试目标机程序
我在wsl上运行gdb,在目标机上运行gdbserver,开始能进去,但是打断点之后运行,gdbserver就崩了,据我推测,gdb调用本机的信息来打断点,但是远端运行的库与本机并不一致,所以就挂了。这个还需要进一步学习研究。
这条路又没走通。
3.直接在编译环境上安装图形界面的gdb工具来调试
看到这篇GDB图形界面大PK https://blog.csdn.net/shenyuflying/article/details/53931865
筛选了可以用gdbserver的,准备使用insight试试。试用之后再补