Linux·gdb调试命令和使用方法

基本命令

调试未运行的程序

$ gdb helloworld Reading symbols from helloWorld...(no debugging symbols found)...done.

如果没有调试信息,会提示no debugging symbols found。

如果是下面的提示:

Reading symbols from helloWorld...done.

则可以进行调试。

  • readelf查看段信息

例如:

$ readelf -S helloWorld|grep debug [28] .debug_aranges PROGBITS 0000000000000000 0000106d [29] .debug_info PROGBITS 0000000000000000 0000109d [30] .debug_abbrev PROGBITS 0000000000000000 0000115b [31] .debug_line PROGBITS 0000000000000000 000011b9 [32] .debug_str PROGBITS 0000000000000000 000011fc

helloWorld为文件名,如果没有任何debug信息,则不能被调试。

  • file查看strip状况

下面的情况也是不可调试的:

$ file helloWorld helloWorld: (省略前面内容) stripped

如果最后是stripped,则说明该文件的符号表信息和调试信息已被去除,不能使用gdb调试。但是not stripped的情况并不能说明能够被调试。

调试例如:

$ gdb helloWorld (gdb)

输入run命令,即可运行程序

调试启动带参程序

假设有以下程序,启动时需要带参数:

#include<stdio.h> int main(int argc,char *argv[]) { if(1 >= argc) { printf("usage:hello name\n"); return 0; } printf("Hello World %s!\n",argv[1]); return 0 ; }

编译:

$ gcc -g -o hello hello.c

这种情况如何启动调试呢?需要设置参数:

$ gdb hello (gdb)run 编程珠玑 Starting program: /home/shouwang/workspaces/c/hello 编程珠玑 Hello World 编程珠玑! [Inferior 1 (process 20084) exited normally] (gdb)

只需要run的时候带上参数即可。

或者使用set args,然后在用run启动:

$ gdb hello (gdb) set args 编程珠玑 (gdb) run Starting program: /home/hyb/workspaces/c/hello 编程珠玑 Hello World 编程珠玑! [Inferior 1 (process 20201) exited normally] (gdb)

调试正在运行的程序

如果程序已经运行了怎么办呢?

首先使用ps命令找到进程id:

$ ps -ef|grep 进程名

或者:

$ pidof 进程名

attach方式

假设获取到进程id为20829,则可用下面的方式调试进程:

$ gdb (gdb) attach 20829

接下来就可以继续你的调试啦。

可能会有下面的错误提示:

Could not attach to process. If your uid matches the uid of the target process, check the setting of /proc/sys/kernel/yama/ptrace_scope, or try again as the root user. For more details, see /etc/sysctl.d/10-ptrace.conf ptrace: Operation not permitted.

解决方法,切换到root用户:

将/etc/sysctl.d/10-ptrace.conf中的

kernel.yama.ptrace_scope = 1

修改为

kernel.yama.ptrace_scope = 0

直接调试相关id进程

还可以是用这样的方式gdb program pid,例如:

gdb hello 20829

或者:

gdb hello --pid 20829

已运行程序没有调试信息

为了节省磁盘空间,已经运行的程序通常没有调试信息。但如果又不能停止当前程序重新启动调试,那怎么办呢?还有办法,那就是同样的代码,再编译出一个带调试信息的版本。然后使用和前面提到的方式操作。对于attach方式,在attach之前,使用file命令即可:

$ gdb (gdb) file hello Reading symbols from hello...done. (gdb)attach 20829

错误文件调试分析

调试core文件

当程序core dump时,可能会产生core文件,它能够很大程序帮助我们定位问题。但前提是系统没有限制core文件的产生。可以使用命令limit -c查看:

$ ulimit -c 0

如果结果是0,那么恭喜你,即便程序core dump了也不会有core文件留下。我们需要让core文件能够产生:

$ ulimit -c unlimied #表示不限制core文件大小 $ ulimit -c 10 #设置最大大小,单位为块,一块默认为512字节

上面两种方式可选其一。第一种无限制,第二种指定最大产生的大小。

调试core文件也很简单:

$ gdb 程序文件名 core文件名 bt 可以查看函数调用栈

调试多进程

  • 调试父进程:set follow-fork-mode parent(默认)
  • 调试子进程:set follow-fork-mode chiled
  • 设置调试模式:set detach-on-fork [on|off],缺省是on,表示调试当前进程的时候,其它的进程继续运行,如果用off,调试当前进程的时候,其它的进程被gdb挂起。
  • 查看调试的进程:info inferiors
  • 切换当前调试的进程:inferior 进程 id

调试多线程

  • 查看当前运行的进程:ps -aux | grep 进程名
  • 查看当前运行的轻量级进程:ps -aL | grep 进程名
  • 查看主线程与新线程的关系:pstree -p 主线程id
  • 查看线程:info threads
  • 切换线程:thread 线程id
  • 只运行当前线程:set scheduler-locking on
  • 运行全部的线程:set scheduler-locking off
  • 指定某线程执行某gdb命令:thread apply 线程id cmd
  • 全部的线程执行某gdb命令:thread apply all cmd

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/27872.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

redis工具使用

一、工具 官网下载&#xff1a;https://redisdesktop.com/download 二、安装 自己选择路径&#xff0c;点击install安装 安装成功后点击finish。之后就可以打开软件进行操作了。 三、简单使用 1.点击Connect to Redis Server&#xff0c;新建一个redis连接 2.Name&#…

Ceph 分布式应用2

一、创建 CephFS 文件系统 MDS 接口 1、服务端操作 1&#xff09;在管理节点创建 mds 服务 [rootadmin ceph]# cd /etc/ceph [rootadmin ceph]# ceph-deploy mds create node01 node02 node03 [ceph_deploy.conf][DEBUG ] found configuration file at: /root/.cephdeploy.c…

22.代理模式

代理模式 二十三种设计模式中的一种&#xff0c;属于结构型模式。它的作用就是通过提供一个代理类&#xff0c;在调用目标方法的时候&#xff0c;不再是直接对目标方法进行调用&#xff0c;而是通过代理类间接调用。让不属于目标方法核心逻辑的代码从目标方法中剥离出来——解耦…

LDAP Tool Box Self Service Password

手册地址&#xff1a;https://self-service-password.readthedocs.io/en/latest/安装要求&#xff1a; Apache or another web server php (>7.4) php-curl (haveibeenpwned api) php-filter php-gd (captcha) php-ldap php-mbstring (reset mail) php-openssl (token cryp…

HCIP第十二天

题目 拓扑图 sw1、sw2、sw3分别创建VLAN、划分接口&#xff0c;配置干道 VLAN间路由 所有PC通过DHCP获取IP地址 PC1/3可以正常访问PC2/4/5/6

【AI底层逻辑】——篇章5(上):机器学习算法之回归分类

目录 引入 一、何为机器学习 1、定规则和学规则 2、算法的定义 二、机器学习算法 1、常见学习方法 2、回归 3、分类 续下篇... 往期精彩&#xff1a; 引入 计算机发明初&#xff0c;专家通过将专业知识和经验梳理成规则输入计算机程序&#xff0c;但是这样跟不上知识…

基于深度学习的高精度农作物机器与行人目标检测系统(PyTorch+Pyside6+YOLOv5模型)

摘要&#xff1a;基于深度学习的高精度农作物机器与行人目标检测系统可用于日常生活中或野外来检测与定位农作物机器与行人目标&#xff0c;利用深度学习算法可实现图片、视频、摄像头等方式的农作物机器与行人目标检测识别&#xff0c;另外支持结果可视化与图片或视频检测结果…

Java Jsp+Json+阿贾克斯

0目录 1.补充阿贾克斯 2.实战&#xff08;加入Json&#xff09; 1.补充阿贾克斯 创建工程&#xff0c;加入jason依赖和数据库 新建数据库&#xff0c;表和实体类 先新建一个查询方法 FruitServlet 修改Web.xml 加入Js包&#xff08;版本1.9.1&#xff09; …

Unity LayerMask原理和判断包含关系

在本文之前&#xff0c;请先了解全部位操作的含义&#xff0c;否则继续下去会很困难。 本质&#xff1a;32位整数的每一位表示一个层 LayerMask本质上是一个32位的整数(Int32 ,int)&#xff0c;每个位代表一个图层&#xff0c;因此LayerMask最多可以表示32个图层&#xff08;0…

Python_pymysql_与mysql交互

目录 基础功能 简单封装 源码等资料获取方法 基础功能 import pymysql from pymysql.cursors import DictCursor # 导入字典类型的游标对象# 连接数据库 db pymysql.connect(host192.168.3.109, # 数据库IP地址port3306, # 数据库端口号userroot, …

8. 自动化测试 selenium

目录 1. 什么是自动化 2. 自动化测试金字塔 2.1 单元测试 2.2 接口自动化 2.3 UI自动化 3. 什么是 selenium 4. selenium 工作原理&#xff08;重点&#xff09; 1. 什么是自动化 自动化测试指软件测试的自动化&#xff0c;在预设状态下运行应用程序或者系统&#xff0…

px4上传数据waiting for bootloader

输入make px4_fmu-v6c_default upload&#xff0c;出现waiting for bootloader 原因&#xff0c;可能是启动了QGC占用了端口&#xff0c;把QGC关掉&#xff0c;重新上电&#xff0c;就OK了。