目的
最近在使用gem5做一些体系结构的实验,代码出现了一些bug,一直得不到解决,需要进行调试。由于gem5是用C++和python写的,其中C++描述了基本的硬件建模,而python主要是为了连线和传递参数,所以就想尝试用gdb去调试,解决遇到的bug
gdb安装
gdb的安装分为两种,一种是在线安装或者有网络的情况下,另一种是离线安装或者无网络的情况下,由于我所用的服务器没有连接网络,所以我用的是离线安装的方法,但我也会顺带提一下在线安装的方法。一般而言,对于环境配置,在线安装总是比离线安装要简单,因为在线安装可能简单几行命令就ok了,但是离线安装通常会遇到很多版本不匹配的问题。
我是在docker 容器中搭了一套独立的gem5运行环境,linux系统用的是ubuntu 20.04,所以并不是在本地电脑上运行gem5的。如果直接在docker容器中进行gdb 的安装调试,应该会报如下错误(至少我的错误是这样):
[Inferior 1 (process 11131) exited with code 02]
或者
warning: Error disabling address space randomization: Operation not permitted
Cannot create process: Operation not permitted
During startup program exited with code 127.
(gdb)
由于linux 内核为了安全起见,采用了Seccomp(secure computing)的沙箱机制来保证系统不被破坏。它能使一个进程进入到一种“安全”运行模式,该模式下的进程只能调用4种系统调用(system calls),即read(), write(), exit()和sigreturn(),否则进程便会被终止。
Docker默认情况下为每个容器都设置了一个默认的seccom profile。一般情况下无需修改。但是docker依然支持
docker create或者docker run时候通过–security-opt seccomp=xxx参数来设置docker容器的seccomp策略。
xxx可以是一个json格式文件,里面定义了docker容器每个具体的seccomp规则。也可以是字符unconfined表示关闭默认的docker seccomp 规则。
可以通过下面命令彻底关闭docker默认seccomp引入的任何限制
docker只有以–security-opt seccomp=unconfined的模式运行container才能利用GDB调试
踩坑
因此为了顺利在docker中使用gdb进行调试,在创建docker容器时加入必要选项,具体命令如下:
docker run -it --security-opt seccomp=unconfined ubuntu:lastes
相关原因可以查看这篇文章,在此不再赘述docker中运行gdb为什么会报错
gdb在线安装
gdb的在线安装较为简单,只需要简单几行命令即可
apt-get update
apt-get install gdb
有的系统可能需要提供超级管理员权限才能在系统中安装软件,只需加上sudo即可
gdb离线安装
gdb的离线安装较为麻烦,其实原理与在线安装一样,不同之处是需要事先将各种软件包下载好,并放入docker中。
将本地文件放入docker容器的命令如下:
docker cp /host/path/to/file docker_container_name:/docker/path/file
其中 /host/path/to/file 是本地文件所处位置的路径,可以是相对路径也可以是绝对路径,取决于当前命令所处的位置,
docker_container_name是指你要放入的docker容器的名字或者ID,因为可能你同时创建了多个docker容器,所以需要指定你要放入的docker 容器的名字或id,这个ID是系统分配的,但是名字是你创建容器时可以指定的,如果没有指定,docker会根据你的镜像文件给你起一个相关的名字
/docker/path/file是指你要将文件放入docker容器中的位置的路径
在这个过程中,可能还会遇到徐多版本问题,经过多次的尝试,我找到了互相匹配的压缩包,放在了我的资源中,有需要者可以自行下载
拥有了安装包之后,就进行解压,解压命令
tar -xzvf
然后进入gdb所在文件夹,执行
mkdir build
cd build
../configure
主要是为了生成安装所需的makefile,然后
make install
安装过程中可能会出现版本问题,再安装我所提供的对应的安装包就可以,安装过程一样,在此不再赘述
使用gdb调试gem5
使用gdb调试gem5,首先需要生成debug文件
scons -j17 build/RISCV/gem5.debug
然后通过gdb调试gem5.debug
gdb --args ./build/RISCV/gem5.debug [gem5选项]
具体的gem5选项和你具体的处理器有关,而自行查阅gem5的官网
具体的gdb调试命令可以查阅相关博客,在此不再赘述
总结
使用gdb调试不仅可以找出代码中存在的bug,更有助于理解整个gem5的模拟过程,是个非常不错的工具,如果有图形界面,gdbgui可以更方便得进行调试,我就不再详细描述了,因为我觉得还是命令行看起来更加舒服。