GDB用法(三)

本文介绍了如何在GDB中管理和操作命令历史,包括设置历史扩展、保存命令到文件、自定义gdb命令(如pvector)以及.gdbinit文件的使用。还涉及了CMakeLists.txt文件在构建过程中与GDB交互的内容。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

预备

测试代码参照GDB用法(二)

命令历史

可以将命令历史保存到文件中

(show history) 展示当前gdb中history的设置信息

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

设置expansion
(set history expansion) 打开历史扩展

能使用历史处理命令对历史数据进行处理, 暂不细究

(show history expansion) 展示历史扩展配置

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

设置save
(set history save) 启用命令历史保存到文件

等关闭的时候就会保存到history save中的文件夹中

(show history save) 展示命令历史保存的配置

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

设置size
(set history size 数字) 设置保存的命令条数

默认条数256

(show history size) 展示设置的命令条数配置

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

设置保存文件filename
(set history filename 文件名) 设置保存历史文件

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

(show history filename) 展示历史文件名

默认是当前目录下的.gdb_history文件中

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

关闭gdb, 保存到文件中

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

存的是最后十条命令记录

初始化文件(.gdbinit)

增加.gdbinit文件
p "自动 gdbinit 初始化完成!"
自动调用.gdbinit文件

只能叫.gdbinit, 且目录位置要对

  1. root用户, .gdbinit文件放在~/ 目录下

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

  1. 其他用户, .gdbinit文件放在/home/用户名/ 下, 对于用户本身, 其实也就是在~/目录下

    外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

    外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

    先切换到普通用户

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

手动加载.gdbinit文件

source 目录/文件 // 用linux命令读取文件内容

文件名都不需要是.gdbinit

在工程下新建文件testinit

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

p "手动加载 testinit文件成功"

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

之前gdb设置的一些参数, 退出gdb后再进入配置就不生效了, 写入初始化文件则会一直生效

自定义gdb命令

(define) 自定义命令

define 命令名

​ 命令

​ …

end

(document) 给自定义命令添加说明

documnt 命令名

​ 说明

end

help 命令 // 显示说明

stl中pvector的自定义

define pvector
	if $argc == 0
		help pvector
	else
		set $size = $arg0._M_impl._M_finish - $arg0._M_impl._M_start
		set $capacity = $arg0._M_impl._M_end_of_storage - $arg0._M_impl._M_start
		set $size_max = $size - 1
	end
	if $argc == 1
		set $i = 0
		while $i < $size
			printf "elem[%u]: ", $i
			p *($arg0._M_impl._M_start + $i)
			set $i++
		end
	end
	if $argc == 2
		set $idx = $arg1
		if $idx < 0 || $idx > $size_max
			printf "idx1, idx2 are not in acceptable range: [0..%u].\n", $size_max
		else
			printf "elem[%u]: ", $idx
			p *($arg0._M_impl._M_start + $idx)
		end
	end
	if $argc == 3
	  set $start_idx = $arg1
	  set $stop_idx = $arg2
	  if $start_idx > $stop_idx
	    set $tmp_idx = $start_idx
	    set $start_idx = $stop_idx
	    set $stop_idx = $tmp_idx
	  end
	  if $start_idx < 0 || $stop_idx < 0 || $start_idx > $size_max || $stop_idx > $size_max
	    printf "idx1, idx2 are not in acceptable range: [0..%u].\n", $size_max
	  else
	    set $i = $start_idx
		while $i <= $stop_idx
			printf "elem[%u]: ", $i
			p *($arg0._M_impl._M_start + $i)
			set $i++
		end
	  end
	end
	if $argc > 0
		printf "Vector size = %u\n", $size
		printf "Vector capacity = %u\n", $capacity
		printf "Element "
		whatis $arg0._M_impl._M_start
	end
end

document pvector
	Prints std::vector<T> information.
	Syntax: pvector <vector> <idx1> <idx2>
	Note: idx, idx1 and idx2 must be in acceptable range [0..<vector>.size()-1].
	Examples:
	pvector v - Prints vector content, size, capacity and T typedef
	pvector v 0 - Prints element[idx] from vector
	pvector v 1 2 - Prints elements in range [idx1..idx2] from vector
end 

加载其他库定义的函数

修改工程

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

main.cpp
#include <iostream>
#include <vector>

using namespace std;

int main(int argc,char *argv[])
{
    cout << "参数个数:" << argc << endl;
    for(int i = 0; i < argc; i++)
    {
        cout << "参数[" << i << "]:" << argv[i] << endl;
    }
    
    vector<int> v = {1, 3};

    return 0;
}
Functions/pFun.h
#ifndef _PFUN_H_
#define _PFUN_H_

#include <iostream>
#include <vector>

void pvector_self(const std::vector<int> v);

#endif
Functions/pFun.cpp
#include "pFun.h"

void pvector_self(const std::vector<int> v)
{
    if(v.empty())
    {
        std::cout << "为空" << std::endl;
    }

    for(int i = 0; i < v.size(); i++)
    {
        std::cout << "num" << i << ": " << v[i];
        if(i != v.size() - 1)
        {
            std::cout << std::endl;
        }  
    }

    std::cout << std::endl;
    std::cout << "vector<int> 读取完毕" << std::endl;
}
Functions/CMakeLists.txt
cmake_minimum_required(VERSION 3.10)

AUX_SOURCE_DIRECTORY(. FUNCTIONS_SOURCE)

add_library(Functions SHARED ${FUNCTIONS_SOURCE})
CMakeLists.txt
cmake_minimum_required(VERSION 3.10)

project(main)

SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -g -Wall")

INCLUDE_DIRECTORIES(./)

AUX_SOURCE_DIRECTORY(./ MAIN)

add_subdirectory(Functions)

add_executable(main ${MAIN})

target_include_directories(main PUBLIC Functions)
target_link_libraries(main Functions)

testinit
p "手动加载 testinit文件成功"

set $pvector_self = pvector_self

Functions/CMakeLists.txt 会生成 libFunctions.so, gdb就要调用这个函数的输出方法, 输出vector

编译生成libFunctions.so和main

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传
外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

### GDB调试器使用方法 #### 编译带有调试信息的程序 为了能够有效地利用GDB进行调试,编译源代码时应当加入`-g`参数以便包含必要的调试信息。例如,如果有一个C文件名为`test.c`,可以通过下面这条指令将其编译成可执行文件: ```bash gcc -g test.c -o test ``` 此操作会在生成的目标文件中嵌入额外的信息用于支持后续的调试工作[^3]。 #### 启动GDB并加载目标程序 启动GDB的方式很简单,只需在终端输入`gdb`加上待调试的应用名称作为参数即可。比如针对上面提到的例子可以这样调用: ```bash gdb ./test ``` 一旦进入GDB环境之后,就可以通过一系列命令来进行断点设置、单步执行以及变量查看等动作了[^1]。 #### 基础命令概览 以下是几个常用的GDB基础命令列表: - `run`: 开始运行被调试的程序; - `breakpoint function_name/line_number`: 设置断点于指定函数或者某一行处; - `continue`: 继续执行直到遇到下一个断点为止; - `next`: 执行下一条语句而不深入子过程内部; - `step`: 进入当前行所调用的方法体内继续跟踪其逻辑流程; - `print variable/expression`: 显示特定变量或表达式的值; 这些只是入门级别的功能介绍,实际上GDB还提供了许多高级特性供更复杂的场景需求使用[^2]。 #### 安装方式简介 对于大多数现代Linux发行版而言,默认情况下已经预装好了GDB工具链。如果没有的话,则可以根据具体平台选用合适的包管理器来完成安装任务。例如,在基于Debian系统的机器上可通过如下命令快速部署最新稳定版本: ```bash sudo apt-get update && sudo apt-get install gdb ``` 而对于RedHat系操作系统则应采取yum/yumdnf途径实现相同目的。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值