Linux-gdb进程调试

本文介绍使用GDB调试器进行进程调试的方法,包括设置断点、查看变量、跟踪函数等基本操作,并演示了如何调试单个及多个进程的具体步骤。

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

gdb调试一个进程的过程

以下面模拟实现sleep()函数为例

#include <stdio.h>
#include <unistd.h>
#include <signal.h>
void wakeup(int signo)
{
      //do nothing
}
unsigned int mysleep(unsigned int t)
{
      struct sigaction new,old;
      sigset_t newmask,oldmask,suspmask;
      unsigned int unsleep=0;
      new.sa_handler=wakeup;
      new.sa_flags=0;
      sigemptyset(&new.sa_mask);
      //注册一个信号处理函数
      sigaction(SIGALRM,&new,&old);
      sigemptyset(&newmask);
      //添加一个信号到newmask阻塞集
      sigaddset(&newmask,SIGALRM);
      //阻塞SIGALRM信号
      sigprocmask(SIG_BLOCK,&newmask,&oldmask);
      //设置一个闹钟
      alarm(t);

      suspmask=oldmask;
      sigdelset(&suspmask,SIGALRM);
      //解除信号屏蔽并挂起进程,等待闹钟响起
      sigsuspend(&suspmask);

      //清空闹钟
      unsleep=alarm(0);
      //回复默认信号处理动作
      sigaction(SIGALRM,&old,NULL);
      sigprocmask(SIG_SETMASK,&oldmask,NULL);
      return unsleep;

}
int main(  )
{
    while( 1)
    {
        mysleep(5);
        printf(  "5s passed...\n");
        printf(  "pid=%d\n",getpid( ));

    }
    return 0;
}

程序编译通过无错误,执行下面命令(黄色部分)

gdb a.out    开始调试a.out文件
b 4          在第四行打断点,开始调试
i b          查看断点
d            删除断点
r            让程序跑起来
n            逐行调试
p 变量名      打印变量,配合n命令效果会更好
q           退出调试

如果是进入函数,需要上s命令

这里写图片描述
这里写图片描述

gdb调试多进程

以下面程序为例,这个程序是为了测试SIGCHLD信号的测试小程序。子进程退出,发SIGCHLD信号父进程,父进程自己做自己的事情,收到信号就回收子进程

#include <signal.h>
#include <stdlib.h>
void handler(int sig)
{
      pid_t id;
      while(id=waitpid(-1,NULL,WNOHANG)>0)
      {

          printf(  "wait child success:%d\n",id);

      }
      printf("  child is quit! %d\n",getpid( ));
}
int main(  )
{
      signal(SIGCHLD,handler);
      pid_t cpid;
      if(  cpid=fork()==0)
      {
            printf("child:%d\n",getpid());
            sleep(10);
            exit(1);

      }
      while(1)
      {
            printf(  " father proc is doing some thing!pid:%d\n",getpid());
            sleep(1);

      }
      return 0;
}

首先让程序编译通过,最好打印出各自pid
如果不打印,用 “ps aux | grep 目标文件名“查看进程pid

这里写图片描述

在另外一个终端输入:gdb a.out命令进入调试模式后,用attach 进程pid就可以调试该进程,但必须保证进程跑完.
这里写图片描述
其他操作和调试单个进程类似

### 使用 arm-linux-gdb 进行调试 #### 配置与安装 为了在 Linux使用 `arm-linux-gdb`,需要先完成其配置和安装过程。可以通过源码编译的方式构建适合的目标环境工具链。例如,在引用中提到的方法之一是通过指定目标平台来编译 GDBgdbserver[^3]。 具体操作可以参考以下流程: 1. **下载并解压 GDB 源码包** 获取官方发布的最新版本或者稳定版的 GDB 源码文件,并将其解压缩至工作目录。 2. **执行 configure 命令** 在解压后的 GDB 源码根目录下运行如下命令以初始化编译环境: ```bash ./configure --target=arm-linux --prefix=/usr/local/arm/ --enable-sim ``` 此处指定了目标架构为 ARM 并设置了安装路径 `/usr/local/arm/`[^5]。 3. **编译与安装** 执行标准 GNU Make 流程完成实际编译以及最终部署: ```bash make && sudo make install ``` #### 启动调试会话 一旦成功安装好所需的 cross-GDB 工具之后,则可按照下面方式开启一次完整的远程调试体验。 假设已经准备好待测程序文件名为 `gdbtest` ,则可以在 Ubuntu 主机上这样调用它开始交互模式下的断点设置等工作流管理活动: ```bash arm-linux-gdb gdbtest ``` 这一步骤将会加载应用程序镜像到内存当中等待进一步指令处理[^1]。 另外还需要注意的是如果打算采用客户端服务器模型来进行跨网络连接形式下的联合开发作业的话就需要额外准备一台充当被控节点角色的小型计算机或者其他类型的硬件载体上面事先安置好相应的服务进程实例即所谓的"gdbserver"[^2]. 当所有前期准备工作均已完成无误后就可以正式着手解决项目中存在的各类潜在缺陷了. #### 示例代码片段展示如何简单地利用 Python 实现自动化脚本来辅助日常任务执行效率提升. ```python import subprocess def run_gdb_command(command): result = subprocess.run(['arm-linux-gdb', '-batch', '-ex', command], stdout=subprocess.PIPE, stderr=subprocess.STDOUT) return result.stdout.decode() output = run_gdb_command('file gdbtest') print(output) breakpoint_output = run_gdb_command('break main') print(breakpoint_output ) run_output = run_gdb_command('run') print(run_output ) ``` 此段落提供了有关于怎样编写一小段 python 脚本来自动生成某些常用的 gdb 控制台命令序列从而减少人工重复劳动量的同时也提高了工作效率的例子说明文档[^4].
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值