linux断点调试的一些问题

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
    • 7 Spacemacs
    • Reference

1 案例程序

1.1 基本代码

【demo.cpp】

#include 
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键
linux断点调试的一些问题_第1张图片

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 incgmd 快捷键F10
next n 单行运行,跳过函数行cgmd 快捷键F8
finish 从进入函数中jump outcgmd 快捷键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  :until

3.4 cgdb调试

cgdb demo

linux断点调试的一些问题_第2张图片

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去访问吧,右上角还有鼠标可以点击呢。可视化明显。
linux断点调试的一些问题_第3张图片

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.nju.edu.cn/gnu/emacs/emacs-25.3.tar.gz
tar zxvf emacs-25.3.tar.gz
cd emacs-25.3
./autogen.sh
./configure --prefix=/usr/local/emacs-25.3 --with-x-toolkit=lucid --with-modules
make bootstrap -j${npoc}
make install
ln -s /usr/local/emacs-25.3/bin/emacs-25.3 /usr/bin/emacs

【注意】这里最靠谱的该方法还是yum install emacs或安装25、24系列版本,这里用的是25.3,发现用最新版emacs26以上版本用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 "") 'alternating-scroll-down-line)
(global-set-key (kbd "") '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
#include 
#include 

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

linux断点调试的一些问题_第4张图片

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

7 Spacemacs

https://github.com/syl20bnr/spacemacs
这个挺好用

Reference

终端调试哪家强?
Makefile使用及多文件gdb 调试
Makefile案例分析

你可能感兴趣的:(工程trick)