linux断点调试的一些问题
- 1 案例程序
- 1.1 基本代码
- 1.2 手动编译
- 1.3 一次性Makefile
- 1.4 中间过程Makefile
- 2 gdb
- 2.1 安装方法
- 2.2 【gdb命令】
- 2.3 gdb调试
- 3 cgdb
- 3.1 安装方法
- 3.2 【cgdb快捷键】【也是EGDB快捷键】
- 3.3 cgdb环境变量
- 3.4 cgdb调试
- 4 gdbgui
- 4.1 安装方法
- 4.2 gdbgui调试
- 5 Emacs最终版(egdb)
- 5.1 安装方法
- 5.2 配置~/.emacs
- 5.3 配置后的快捷键【egdb快捷键】
- 5.4 egdb
- 5.5 purcell的emacs.d
- 6 gdb多文件调试
- 6.1 案例程序
- 6.2 手动编译
- 6.3 MakeFile
- 6.4 简单Makefile
- 6.5 egdb或cgdb调试
- 6.6 更简单Makefile
- Reference
1 案例程序
1.1 基本代码
【demo.cpp】
#include <stdio.h>
long func(int a){
long sum = 0;
for(int j=1;j<=a;j++){
sum += j;
}
return sum;
}
int main(void){
int a =100;
long sum = func(a);
printf("%ld",sum);
return 0;
}
1.2 手动编译
g++ -g demo.cpp -o demo
1.3 一次性Makefile
# 直接生成最终文件
demo: demo.cpp
g++ -g -o demo demo.cpp
clean:
rm demo demo.o -rf
1.4 中间过程Makefile
# 生成最终文件,二者都需要 -g
demo: demo.o
g++ -g -o demo demo.o
# 生成.o临时文件
demo.o: demo.cpp
g++ -g -c demo.cpp
clean:
rm demo demo.o -rf
最后在当前目录下make即可。
【切记注意】g++后面都加了-g,用于可以让gdb调试,且,MakeFile中g++前面是Tab键
2 gdb
2.1 安装方法
yum install gdb
2.2 【gdb命令】
【切记】gdb可以什么都不输直接敲回车,gdb提供了一个很方便功能,在提示符下直接敲回车表示重复上一条命令
命令 | 简写 | 含义 |
---|---|---|
list |
l |
显示源代码 |
break |
b |
b 行号,添加指定行号断点 |
break if |
b if |
b 行号 if (i==10),设置循环顶部满足指定条件时断点 |
delete |
d |
删除断点 |
info |
i |
描述程序状态,如 i break 显示有哪些断点,i thread 哪些线程,i locals显示局部变量值 |
run |
r |
开始 或 继续 运行程序,cgmd 快捷键F5 |
print |
p |
打印内部变量值如,p 变量名 ,p *数组名@数组长度 如 p *a10 |
display |
一边step或next,一边立马显示某变量值 |
|
step |
s |
单行运行,进入函数行, step in ,cgmd 快捷键F10 |
next |
n |
单行运行,跳过函数行 ,cgmd 快捷键F8 |
finish |
从进入函数中jump out ,cgmd 快捷键F7 |
|
continue |
c |
执行到断点 ,cgmd 快捷键F6 |
until |
u |
执行到指定行,u 行号 ,cgmd 快捷键F9 |
start |
st |
开始执行程序,在main函数中的第一条语句前停下 |
disable |
禁用断点 | |
enable |
允许断点 | |
watch |
监视变量值新旧的变化 | |
backtrace |
bt |
查看函数调用信息(堆栈) |
frame |
f |
查看栈帧,比如 frame 1 查看1号栈帧 |
set var name | 设置变量的值 | |
quit | q |
离开gdb |
edit | 在gdb中进行编辑 | |
whatis | 查看变量的类型 | |
file | 装入需要调试的程序 |
2.3 gdb调试
gdb demo
3 cgdb
3.1 安装方法
http://cgdb.github.io/
https://github.com/cgdb/cgdb
#yum isntall cgdb
wget https://cgdb.me/files/cgdb-0.7.1.tar.gz
tar zxvf cgdb-0.7.1.tar.gz
cd cgdb-0.7.1
./autogen.sh
./configure --prefix=/usr/local/cgdb
make -j${npoc}
make install
ln -s /usr/local/cgdb/bin/cgdb /usr/bin/cgdb
3.2 【cgdb快捷键】【也是EGDB快捷键】
命令 | 简写 | 含义 |
---|---|---|
按ESC键 |
进入代码窗口 |
|
按i键 |
进入调试窗口 |
|
break |
b |
b 行号,设置指定行号断点 ,(在代码窗口用空格键设置断点,再次按取消断点) |
上下左右键 |
代码窗口可以切换行,也可以用j键,k键 |
|
step |
s |
egdb或cgmd 快捷键F10 ,单行运行,进入函数行, step in |
next |
n |
egdb或cgmd 快捷键F8 ,单行运行,跳过函数行 |
finish |
egdb或cgmd 快捷键F7 ,从进入函数中跳出 |
|
continue |
c |
egdb或cgmd 快捷键F6 ,执行到断点 |
until |
u |
egdb或cgmd 快捷键F9 ,执行到指定行,u 行号 |
run |
r |
egdb或cgmd 快捷键F5 ,开始运行 |
break |
b |
egdb 快捷键F11 ,设置选中行断点 |
3.3 cgdb环境变量
【注意】若发现cgdb环境变量配置怎么也不起作用,用github上的最新版去编译安装即可
# 进入cgdbrc下设置如下
vim ~/.cgdb/cgdbrc
设置搜索大小写不敏感、tab 大小、左右分屏、搜索高亮、F9快捷键跳出循环
set ignorecase
set ts=4
set wso=vertical
set eld=shortarrow
set hls
map <F9> :until<cr>
3.4 cgdb调试
cgdb demo
4 gdbgui
4.1 安装方法
#使用此命令在自己用户下安装后会自动添加到PATH变量中
python3 -m pip install --user pipx
python3 -m userpath append ~/.local/bin
pipx install gdbgui
# installed package gdbgui 0.13.2.0, Python 3.7.7
# These apps are now globally available
# - gdbgui
# done!
4.2 gdbgui调试
gdbgui -p 10001 -r demo
然后在http://局域网ip:10001去访问吧,右上角还有鼠标可以点击呢。可视化明显。
5 Emacs最终版(egdb)
emacs26.3 更新下载地址 http://mirrors.ustc.edu.cn/gnu/emacs
5.1 安装方法
yum install gtk2 gtk2-devel gtk2-devel-docs
yum install libXpm libXpm-devel libjpeg libjpeg-devel libgif libgif-devel libungif libungif-devel libtiff libtiff-devel
wget http://mirrors.ustc.edu.cn/gnu/emacs/emacs-26.3.tar.xz
xz emacs-26.3.tar.xz
tar xvf tar xvf emacs-26.3.tar
cd emacs-26.3
./autogen.sh
./configure --prefix=/usr/local/emacs-26.3
make -j${npoc}
make install
ln -s /usr/local/emacs-26.3/bin/emacs-26.3 /usr/bin/emacs
【注意】这里最靠谱的该方法还是yum install emacs,发现用最新版emacs用gdb打断点调试无法输入信息
5.2 配置~/.emacs
·windows下是 ~/_emacs,添加如下内容,设定 ALT+方向键就可以在窗口中跳转,默认打开gdb-many-windows
(global-set-key [M-left] 'windmove-left)
(global-set-key [M-right] 'windmove-right)
(global-set-key [M-up] 'windmove-up)
(global-set-key [M-down] 'windmove-down)
(global-set-key [f5] 'gud-run)
(global-set-key [f6] 'gud-cont)
(global-set-key [S-f7] 'gud-jump)
(global-set-key [S-f6] 'gud-print)
(global-set-key [f10] 'gud-step)
(global-set-key [f8] 'gud-next)
(global-set-key [S-f10] 'gud-stepi)
(global-set-key [S-f8] 'gud-nexti)
(global-set-key [f11] 'gud-break)
(global-set-key [S-11] 'gud-remove)
(global-set-key [f9] 'gud-until)
(global-set-key [f7] 'gud-finish)
(global-set-key [f4] 'gud-up)
(global-set-key [S-f4] 'gud-down)
(setq gdb-many-windows t)
增加下面一段,允许鼠标点击切换窗口,点击按钮,用滚轮上下查看源代码
,
(require 'xt-mouse)
(xterm-mouse-mode)
(require 'mouse)
(xterm-mouse-mode t)
(defun track-mouse (e))
(setq mouse-wheel-follow-mouse 't)
(defvar alternating-scroll-down-next t)
(defvar alternating-scroll-up-next t)
(defun alternating-scroll-down-line ()
(interactive "@")
(when alternating-scroll-down-next
(scroll-down-line))
(setq alternating-scroll-down-next (not alternating-scroll-down-next)))
(defun alternating-scroll-up-line ()
(interactive "@")
(when alternating-scroll-up-next
(scroll-up-line))
(setq alternating-scroll-up-next (not alternating-scroll-up-next)))
(global-set-key (kbd "<mouse-4>") 'alternating-scroll-down-line)
(global-set-key (kbd "<mouse-5>") 'alternating-scroll-up-line)
5.3 配置后的快捷键【egdb快捷键】
在Emacs的界面,就直接用这些快捷键调试和运行即可,也可以配合gdb
见上面的cgdb快捷键,设置成一样了。
5.4 egdb
【.bashrc中增加】
egdb () { emacs --eval "(gdb \"gdb --annotate=3 -i=mi $*\")";}
以后就直接在终端egdb demo即可
5.5 purcell的emacs.d
https://github.com/purcell/emacs.d
【安装方法】
git clone https://github.com/purcell/emacs.d.git ~/.emacs.d
# 然后去启动emacs,会去下载很多插件,速度有点慢,下载好就行了
# 备份
zip -r purcell.zip ~/.emacs.d
Upon starting up Emacs for the first time, further third-party packages will be automatically downloaded and installed. If you encounter any errors at that stage, try restarting Emacs, and possibly running M-x package-refresh-contents before doing so
【更换国内源】
https://mirror.tuna.tsinghua.edu.cn/help/elpa/
或者参考
http://mirrors.ustc.edu.cn/help/elpa.html
# 在~/.emacs中最前面添加下面内容
vim ~/.emacs
(setq package-archives '(("gnu" . "http://mirrors.tuna.tsinghua.edu.cn/elpa/gnu/")
("melpa" . "http://mirrors.tuna.tsinghua.edu.cn/elpa/melpa/")
("melpa-stable" . "http://mirrors.tuna.tsinghua.edu.cn/elpa/melpa-stable/")
("org" . "http://mirrors.tuna.tsinghua.edu.cn/elpa/org/")))
(package-initialize) ;; You might already have this line
然后输入emacs后,进入界面:按ESC键盘+X
或者 alt+X
,输入命令:
package-refresh-contents
6 gdb多文件调试
在gdb窗口输入r/run之后,将需要添加的源文件目录执行以下该命令即可
dir(/data1/kaldi/kaldi-trunk/src/)
6.1 案例程序
以下代码放到/data1/kaldi/test文件夹下
【test.h】头文件
#pragma once
#include<stdio.h>
#include <sys/types.h>
#include <sys/ipc.h>
int add(int a,int b);
【test.cpp】实现文件
#include "test.h"
int add(int a, int b){
return a + b;
}
【main.cpp】主函数
#include "test.h"
int main()
{
printf("%d\n",add(1,2));
return 0;
}
6.2 手动编译
g++ -g -c main.cpp -o main.o
g++ -c test.cpp -o test.o
g++ main.o test.o -o main
#执行
./main
若用都了不同目录下的h文件和lib库,用以下方式:
g++ main.cpp -o main -I/data1/kaldi/test/include -L/data1/kaldi/test/lib -lworld
-I/data1/kaldi/test/include:将/data1/kaldi/test/include目录作为第1个寻找头文件目录:
寻找顺序:data1/kaldi/test/include–>/usr/include–>/usr/local/include,找不到则查找默认目录
-L/home/hello/lib:将/data1/kaldi/test/lib目录作为第1个寻找库文件目录:
寻找顺序:/data1/kaldi/test/lib–>/lib–>/usr/lib–>/usr/local/lib
-lworld :寻找动态链接库文件libword.so(是文件名去掉前缀和后缀所代表的库文件)
CFLAGS = -Wall -O -g
-Wall :打开警告开关
-O:默认优化,可选:-O0不优化,-O1低级优化,-O2中级优化,-O3高级优化,-Os代码空间优化
-g:生成调试信息,生成的可执行文件具有和源代码关联的可调试的信息。
该选项可以在g++ 后面如 g++ ${CFLAGS}配合使用
6.3 MakeFile
main:test.o main.o
g++ -g -o main main.o test.o
test.o:test.cpp
g++ -c test.cpp -o 1.o -g
main.o:main.cpp
g++ -c main.c -o main.o -g
clean:
rm -rf *o
rm -f all
rm main
6.4 简单Makefile
CC=g++
EXEC=main
OBJS=main.o test.o
CFLAGS=-Wall -O -g
$(EXEC):$(OBJS)
$(CC) $(CFLAGS) $(OBJS) -o $(EXEC)
test.o:test.cpp
$(CC) $(CFLAGS) -c test.cpp -o test.o
main.o:main.cpp
$(CC) $(CFLAGS) -c main.cpp -o main.o
clean:
rm -rf *o
rm -f all
rm main
6.5 egdb或cgdb调试
# 支持鼠标拖动窗口分界线,和gdb命令一样去运行即可
# 鼠标点击中间行,按F11,增加断点
egdb main
6.6 更简单Makefile
【注意】这里的main和test就没调试信息了,如果简写
CC=g++
EXEC=main
OBJS=main.o test.o
CFLAGS=-Wall -O -g
$(EXEC):$(OBJS)
$(CC) $(CFLAGS) $(OBJS) -o $(EXEC)
test.o:test.cpp test.h
main.o:main.cpp
clean:
rm -rf *o main
Reference
终端调试哪家强?
Makefile使用及多文件gdb 调试
Makefile案例分析