linux断点调试的一些问题

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提供了一个很方便功能,在提示符下直接敲回车表示重复上一条命令

命令简写含义
listl显示源代码
breakbb 行号,添加指定行号断点
break ifb ifb 行号 if (i==10),设置循环顶部满足指定条件时断点
deleted删除断点
infoi描述程序状态,如 i break 显示有哪些断点,i thread 哪些线程,i locals显示局部变量值
runr开始 或 继续 运行程序,cgmd 快捷键F5
printp打印内部变量值如,p 变量名p *数组名@数组长度 如 p *a10
display一边step或next,一边立马显示某变量值
steps单行运行,进入函数行, step incgmd 快捷键F10
nextn单行运行,跳过函数行cgmd 快捷键F8
finish从进入函数中jump outcgmd 快捷键F7
continuec执行到断点cgmd 快捷键F6
untilu执行到指定行,u 行号cgmd 快捷键F9
startst开始执行程序,在main函数中的第一条语句前停下
disable禁用断点
enable允许断点
watch监视变量值新旧的变化
backtracebt查看函数调用信息(堆栈)
framef查看栈帧,比如 frame 1 查看1号栈帧
set var name设置变量的值
quitq离开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
#ubuntu安装上述之前需要安装
apt-get install texinfo flex ncurses-dev

3.2 【cgdb快捷键】【也是EGDB快捷键】

命令简写含义
按ESC键进入代码窗口
按i键进入调试窗口
breakbb 行号,设置指定行号断点(在代码窗口用空格键设置断点,再次按取消断点)
上下左右键代码窗口可以切换行,也可以用j键,k键
stepsegdb或cgmd 快捷键F10单行运行,进入函数行, step in
nextnegdb或cgmd 快捷键F8单行运行,跳过函数行
finishegdb或cgmd 快捷键F7从进入函数中跳出
continuecegdb或cgmd 快捷键F6执行到断点
untiluegdb或cgmd 快捷键F9执行到指定行,u 行号
runregdb或cgmd 快捷键F5,开始运行
breakbegdb 快捷键F11,设置选中行断点

3.3 cgdb环境变量

【注意】若发现cgdb环境变量配置怎么也不起作用,用github上的最新版去编译安装即可

# 进入cgdbrc下设置如下
vim ~/.cgdb/cgdbrc

【注意】如果发现设置不管用,请升级你的cgdb
设置搜索大小写不敏感、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.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打断点调试无法输入信息

# ubuntu安装方法
apt install emacs egdb

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 -Wno-sign-compare -Wno-unused-local-typedefs -Wno-deprecated-declarations -Winit-self
CFLAGS+= -O0 -g -std=c++11 -lm -lpthread -ldl -lrt -rdynamic
$(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

6.5 egdb或cgdb调试

# 支持鼠标拖动窗口分界线,和gdb命令一样去运行即可
# 鼠标点击中间行,按F11,增加断点
egdb ./main

在这里插入图片描述

6.6 更简单Makefile

【注意】这里的main和test就没调试信息了,如果简写

CC=g++
EXEC=main
OBJS=main.o test.o
CFLAGS=-Wall -Wno-sign-compare -Wno-unused-local-typedefs -Wno-deprecated-declarations -Winit-self
CFLAGS+= -O0 -g -std=c++11 -lm -lpthread -ldl -lrt -rdynamic
$(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案例分析

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: 在Linux中使用gdb调试程序时,可以通过设置断点来暂停程序的执行,以便进行调试。设置断点的方法如下: 1. 在终端中打开gdb调试器,输入要调试的程序的路径和名称,例如:gdb /path/to/program 2. 进入gdb调试器后,可以使用b命令设置断点。例如,要在程序的第10行设置断点,可以输入:b 10 3. 如果要在某个函数中设置断点,可以使用b命令加上函数名。例如,要在函数foo()中设置断点,可以输入:b foo 4. 如果要在某个文件中设置断点,可以使用b命令加上文件名和行号。例如,要在文件test.c的第20行设置断点,可以输入:b test.c:20 5. 设置好断点后,可以使用r命令运行程序。程序执行到断点处时,会自动暂停执行。 6. 在程序暂停执行时,可以使用s命令单步执行程序,或使用c命令继续执行程序直到下一个断点。 7. 如果要删除断点,可以使用d命令。例如,要删除第10行的断点,可以输入:d 10 以上就是在Linux中使用gdb调试器设置断点的方法。 ### 回答2: GDB是一个功能强大的调试工具,可以帮助我们在Linux环境下调试程序并诊断问题。为了更好地使用GDB进行调试,我们需要了解如何设置断点。下面将详细介绍如何在Linux中使用GDB设置断点。 首先,我们需要编写一个需要调试的程序,并使用-g选项编译程序。例如,我们编写一个名为test的C程序并使用以下命令编译它: gcc -g test.c -o test 在编译过程中,-g选项会在程序中生成用于调试的符号表。这些符号表包含程序中的变量和函数名称等信息,从而使GDB能够准确地显示代码和调试信息。 接下来,我们需要使用GDB打开编译过的程序: gdb test 当GDB启动时,我们可以使用run命令运行程序。如果程序需要参数,则可以在run命令后添加参数。例如,如果我们的程序需要一个文件名作为参数,则可以使用以下命令运行程序: run filename 现在,我们可以在程序中设置断点。设置断点的方法有许多种,以下是几种常用的方法: 1.使用break命令设置断点。break命令后可以跟一个文件名和行号,表示在该文件的该行设置断点。例如,要在test.c的第10行设置断点,可以使用以下命令: break test.c:10 如果要设置在一个函数中设置断点,可以在break命令后面跟上函数名。例如,要在main函数中设置断点,可以使用以下命令: break main 2.使用tbreak命令设置临时断点。tbreak命令与break命令类似,但是设置的断点只在第一次触发后失效。例如,要在test.c的第20行设置临时断点,可以使用以下命令: tbreak test.c:20 3.在程序运行时使用ctrl+c暂停程序,然后使用break命令设置断点。这种方法适用于在程序执行过程中才能确定需要设置断点的情况。例如,要在程序运行到函数foo()时设置断点,可以在程序运行时使用ctrl+c暂停程序,然后使用以下命令设置断点: break foo 设置断点后,我们可以使用continue命令让程序继续运行,直到程序执行到设置的断点处停止。例如,要让程序执行到设置的断点处停止,可以使用以下命令: continue 设置断点是一个非常重要的调试技巧,它可以帮助我们在程序执行过程中找到问题。在使用GDB进行调试时,我们需要充分利用这个功能,不断迭代代码,并在调试过程中修复问题。 ### 回答3: GDBLinux下最常用的调试工具之一,它的用法比较复杂,但是只要掌握了基本的调试技巧,就能够快速定位到代码的错误并进行修复。 设置断点是GDB调试的基本操作之一,通过设置断点,我们可以在程序执行的某个地方停止,并且查看此时的程序状态。下面我们来详细介绍在Linux GDB中如何设置断点。 1. 启动GDB。 在终端中输入"gdb"启动GDB。 2. 加载可执行文件。 可以使用GDB的"file"命令来加载可执行文件,在终端中输入: ``` (gdb) file 可执行文件路径 ``` 此时,GDB就会加载相应的可执行文件。 3. 设置断点。 设置断点可以使用GDB的"break"命令,可以在指定行数或者函数处设置断点。在终端中输入: - 在指定行数上设置断点 ``` (gdb) break 行号 ``` - 在指定函数处设置断点 ``` (gdb) break 函数名 ``` 设置完断点后,可以通过输入"info break"命令查看已经设置的断点信息。 4. 运行程序。 设置好断点之后,可以通过输入"run"命令来运行被调试的程序,程序会在第一个断点处停止。 5. 调试程序。 程序停在断点处之后,可以使用GDB的"next"、"step"、"print"等命令来进行调试,这些命令的作用分别是: - next:单步执行代码,不进入函数调用。 - step:单步执行代码,进入函数调用。 - print:打印变量值。 调试过程中,可以使用"continue"命令让程序继续执行,直到下一个断点处停止。 6. 删除断点。 如果要删除设置的断点,可以使用GDB的"delete"命令,可以在终端中输入: - 删除指定行数处的断点 ``` (gdb) delete 行号 ``` - 删除所有断点 ``` (gdb) delete ``` 以上就是在Linux GDB中设置断点的基本步骤和命令,通过学习和练习,相信大家都可以掌握GDB的基本调试技巧,从而提高程序调试的效率。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值