GDB
中可以用 list
命令显示源码,但是 list
命令显示没有代码高亮,也不能一眼定位到正在执行的那行代码在整个代码中的位置。可以毫不夸张地说,这个问题是阻止很多人长期使用 GDB
的最大障碍,如此不便,以至于 GNU
都想办法解决了——使用 GDB
自带的 GDB TUI
。
1. 开启 GDB TUI 模式
开启 GDB TUI
模式有两个方法。
方法一:使用 gdbtui
命令或者 gdb-tui
命令开启一个调试。
gdbtui -q 需要调试的程序名
方法二:直接使用 GDB
调试代码,在需要的时候使用切换键 Ctrl + X + A
调出 GDB TUI
。
默认情况下,GDB TUI
模式会显示 command
窗口和 source
窗口,如上图所示,还有其他窗口,如下列举的四个常用的窗口:
(cmd) command
命令窗口,可以输入调试命令(src) source
源代码窗口, 显示当前行、断点等信息(asm) assembly
汇编代码窗口(reg) register
寄存器窗口
可以通过 layout + 窗口类型
命令来选择自己需要的窗口,例如,在 cmd
窗口输入 layout asm
则可以切换到汇编代码窗口。
layout
命令还可以用来修改窗口布局,在 cmd
窗口中输入 help layout
,常见的有:
Usage: layout prev | next | <layout_name>
Layout names are:
src : Displays source and command windows.
asm : Displays disassembly and command windows.
split : Displays source, disassembly and command windows.
regs : Displays register window. If existing layout
is source/command or assembly/command, the
register window is displayed. If the
source/assembly/command (split) is displayed,
the register window is displayed with
the window that has current logical focus.
另外,可以通过 winheight
命令修改各个窗口的大小,如下所示:
(gdb) help winheight
Set the height of a specified window.
Usage: winheight <win_name> [+ | -] <#lines>
Window names are:
src : the source window
cmd : the command window
asm : the disassembly window
regs : the register display
# 将代码窗口的高度扩大 5 行代码
winheight src + 5
# 将代码窗口的高度减小 4 代码
winheight src - 4
当前 GDB TUI
窗口放大或者缩小以后,窗口中的内容不会自己刷新以适应新的窗口尺寸,我们可以通过 space
键强行刷新 GDB TUI
窗口。
2. 窗口焦点切换
在默认设置下,方向键和 PageUp/PageDown
都是用来控制 GDB TUI
的 src
窗口的,因此,我们常用上下键显示前一条命令和后一条命令的功能就没有了,不过可以通过 Ctrl + N/Ctrl + P
来获取这个功能。
注意:通过方向键调整了GDB TUI
的 src
窗口以后,可以用 update
命令重新把焦点定位到当前执行的代码上。
我们可以通过 focus
命令来调整焦点位置,默认情况下焦点是在 src
窗口,通过 focus next
命令可以把焦点移到 cmd
窗口,这时候就可以像以前一样,通过方向键来切换上一条命令和下一条命令。同理,也可以使用 focus prev
切回到源码窗口,如果焦点不在 src
窗口,我们就不必使用方向键来浏览源码了。
(gdb) help focus
help focus
Set focus to named window or next/prev window.
Usage: focus {<win> | next | prev}
Valid Window names are:
src : the source window
asm : the disassembly window
regs : the register display
cmd : the command window
2. CGDB
2.1 安装
先安装依赖库
sudo apt install libncurses5-dev
sudo apt install libncursesw5-dev
sudo apt install flex
sudo apt install texinfo
sudo apt install libreadline-dev
如果报错:
The following packages have unmet dependencies:
libncurses5-dev : Depends: libtinfo5 (= 6.1-1ubuntu1) but 6.1-1ubuntu1.18.04 is to be installed
Depends: libncurses5 (= 6.1-1ubuntu1) but 6.1-1ubuntu1.18.04 is to be installed
Depends: libtinfo-dev (= 6.1-1ubuntu1) but it is not going to be installed
E: Unable to correct problems, you have held broken packages.
打开源文件
sudo vim /etc/apt/sources.list
在末尾增加
deb http://cz.archive.ubuntu.com/ubuntu bionic-updates main
然后执行
sudo apt-get update
再重新安装。
安装命令:
$ wget https://cgdb.me/files/cgdb-0.8.0.tar.gz
$ tar -xvf cgdb-0.8.0.tar.gz
$ cd cgdb-0.8.0/
$ sudo ./configure --prefix=/usr/local
$ sudo make
$ sudo make install
2.2 使用
安装成功以后,就可以使用 CGDB
了,在命令行输入 cgdb
命令启动 CGDB
,启动后界面如下:
界面分为上下两部分:上部为代码窗口,显示调试过程中的代码;下部就是 GDB
原来的命令窗口。默认窗口焦点在下部的命令窗口,如果想将焦点切换到上部的代码窗口,按键盘上的 Esc
键,之后再次按字母 i
键将使焦点回到命令窗口。
注意:这个“焦点窗口”的概念很重要,它决定着你当前可以操作的是上部代码窗口还是命令窗口( 和GDB TUI
一样)。
我们用 demo
程序启动后,输入以下命令启动调试:
添加断点以后,代码窗口的行号将会以红色显示,另外有一个绿色箭头指向当前执行的行,并且绿色箭头始终指向当前执行的行数。