热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

gdb调试多进程、多线程

一、gdb的初步认识介绍:gdb是Linux操作系统下的代码调试工具使用:需要在源代码生成可执行文件后的时候加上-g选项eg:ÿ

一、gdb的初步认识


  1. 介绍: gdb是Linux操作系统下的代码调试工具
  2. 使用: 需要在源代码生成可执行文件后的时候加上-g选项 eg:(Makefile文件中在生成可执行文件的那句编译后面加上 -g)
  3. 开始使用: gdb binFile(binFile代表可执行文件)
  4. 退出: ctrl + d或 quit
  5. 调试过程中常用得命令:“`

    list/l 行号:显示binFile源代码,接着上次的位置往下列,每次列10行。
    list/l 函数名:列出某个函数的源代码。
    r或run:运行程序。
    s或step:进入函数调用
    breaktrace(bt):查看各级函数调用及参数
    info(i) locals:查看当前栈帧局部变量的值
    info break :查看断点信息。
    finish:执行到当前函数返回,然后挺下来等待命令
    print(p):打印表达式的值,通过表达式可以修改变量的值或者调用函数
    set var:修改变量的值
    quit:退出gdb
    break(b) 行号:在某一行设置断点
    break 函数名:在某个函数开头设置断点
    continue(或c):从当前位置开始连续而非单步执行程序
    run(或r):从开始连续而非单步执行程序
    delete breakpoints:删除所有断点
    delete breakpoints n:删除序号为n的断点
    disable breakpoints:禁用断点
    enable breakpoints:启用断点
    info(或i) breakpoints:参看当前设置了哪些断点
    display 变量名:跟踪查看一个变量,每次停下来都显示它的值
    undisplay:取消对先前设置的那些变量的跟踪
    until X行号:跳至X行
    p 变量:打印变量值
    n 或 next:单条执行“`


二、gdb调试多进程

1 #include 2 #include3 #include4 #include5 6 int main()7 {8 pid_t pid=fork();//creat child process9 10 if(pid == -1)11 {12 perror("fork error");13 return -1;14 }15 else if(pid == 0)//child16 {17 printf("I am a child process:my pid is %d,my father pid is %d",getpi d(),getppid());18 }19 else//father20 {21 22 printf("I am a father process:my pid is %d,my father pid is %d",getp id(),getppid());23 wait(NULL);//wait child process24 }25 return 0;26 27 }

Makefile文件1 process : process.c2 gcc -o $@ $^ -g 3 .PHONY:clean4 clean:5 rm -f process

调试代码结果:
这里写图片描述
2、默认情况下。在调试多进程程序时GDB只会调试主进程。但是GDB(>V7.0)支持多进程的分别调试及同时调试,换句话说,GDB可以同时调试多个进程。只需要设置 follow-fork-mode(默认值:parent)和 detach-on-fork(默认值:on)即可。
follow-fork-mode detach-on-fork 说明:

parent on :只调试主进程(GDB默认)
child on :只调试子进程
parent off :同时调试两个进程,gdb跟主进程,子进程block在fork位置
chlid off :同时调试两个进程,gdb跟子进程,主进程block在fork位置

1>进入gdb调试模式

gdb process

这里写图片描述

2>查看系统默认的follow-fork-mode 与 detach-on-fork:

show follow-fork-mode
show detach-on-fork

这里写图片描述
3>设置follow-fork-mode 与 detach-on-fork

set follow-fork-mode [parent|child]
set detach-on-fork off[on|off]

这里写图片描述
4>用l/list命令查看源代码(按enter翻页),分别在子进程和父进程相应位置下断点:
这里写图片描述
5>运行程序,查询正在调试的进程:
显示GDB调试的所有inferior,GDB会为他们分配ID。其中带有*的进程是正在调试的inferior.(GDB将每一个被调试程序的执行状态记录在一个名为inferior的结构中。一般情况下一个inferior对应一个进程,每个不同的inferior有不同的地址空间。inferior有时候会在进程没有启动的时候就存在。)

run
info inferiors

这里写图片描述
6>切换调试的进程

inferior [infer number]

这里写图片描述
7>其他

(1)add-inferior [-copies n] [-exec executable]
//添加新的调试进程,可以用file executable来分配给inferior可执行文件。增加n个inferior并执行程序为executable。如果不指定n只增加一个inferior。如果不指定executable,则执行程序留空,增加后可使用file命令重新指定执行程序。这时候创建的inferior其关联的进程并没启动。

(2)remove-inferiors infno1
//删除一个infno号的inferior。如果inferior正在运行,则不能删除,所以删除前需要先kill或者detach这个inferior。

(3)clone-inferior [-copies n] [infno]1
//复制n个编号是infno的inferior。如果不指定n的话,就只复制一个inferior。如果不指定infno,则就复制正在调试的inferior。

(4)detach inferior1
//detach掉编号是infno的inferior。注意这个inferior还存在,可以再次用run命令执行它。

(5)kill inferior infno: 1
//kill掉infno号inferior。注意这个inferior仍然存在,可以再次用run等命令执行它。

(6)set schedule-multiple on|off1
//设为off:只有当前inferior会执行。
设为on:全部是执行状态的inferior都会执行。 这个选项类似于多线程调试里的set .

(7)scheduler-locking1
//注意:如果scheduler-locking是指为on,即使schedule-multiple设置为on,也只有当前进程的当前线程会执行。
show schedule-multiple: 查看schedule-multiple的状态。

(8)set follow-exec-mode new|same1
//设置same:当发生exec的时候,在执行exec的inferior上控制子进程。 设置为new:新建一个inferior给执行起来的子进程。而父进程的inferior仍然保留,当前保留的inferior的程序状态是没有执行。

show follow-exec-mode1
//查看follow-exec-mode设置的模式。

(9)set print inferior-events on|off1
//用来打开和关闭inferior状态的提示信息。

show print inferior-events1
//查看print inferior-events设置的状态。

(10)maint info program-spaces1
//用来显示当前GDB一共管理了多少地址空间。

三,gdb 调试多线程


1,多线程程序举例

1 #include2 #include3 //thread.c4 void *thread1(void* arg)5 {6 printf("i am thread1,my tid is %u\n",pthread_self()); 7 return NULL;8 }9 10 void *thread2(void* arg)11 {12 printf("i am thread2,my tid is %u\n",pthread_self());13 return NULL;14 }15 16 int main()17 {18 pthread_t tid1,tid2;19 pthread_create(&tid1,NULL,thread1,NULL);//creat thread1 20 pthread_create(&tid2,NULL,thread2,NULL);//creat thread221 22 pthread_join(tid1,NULL);//wait thread123 pthread_join(tid2,NULL);//wait thread224 return 0;25 }

多线程Makefile文件:

1 threads : threads.c2 gcc -o $@ $^ -g -lpthread 3 .PHONY:clean4 clean:5 rm -f threads

该代码运行结果:
这里写图片描述
以上代码中,主线程main创建了两个子线程分别是thread1,threads2,所以线程总数为3个。


2、使用gdb对多线程程序进行调试

在多线程编程时,当我们需要调试时,有时需要控制某些线程停在断点处,有些线程继续执行。有时需要控制线程的运行顺序,有时需要中断某个线程,切换到其他线程。这些都可以通过gdb实现。
GDB默认支持调试多线程,跟主线程,子进程block在creat thread.

gdb 调试多线程常用命令:

(1)info threads//:显示可以调试的所有进程。gdb会为每个线程分配一个ID(和tid不同),编号一般从1开始。后面的ID是指这个ID。

1>在主线程处打断点

这里写图片描述
由于断点在16行,线程1与线程2还没有创建,所以可以调试的只有一个主线程。


2>在线程1中打断点

这里写图片描述
断点设置在线程1中,显示可以调试的线程有3个,正在运行的为线程一。


3>在线程2中打断点

这里写图片描述

断点设置在12行,(线程2中),由于线程1已经运行完毕,所以可以调试的线程只有两个,正在运行的为线程2。

(2)thread ID//切换当前调试的线程为指定的ID的线程。

这里写图片描述
(3)其他

break FileName.cpp:LineNum thread all //所有的线程都在文件FileName.cpp的第LinueNum行有断点。

thread apply ID1 ID2 IDN command
//让线程编号是ID1,ID2…等等的线程都执行command命令。

thread apply all command
//所有线程都执行command命令。

set scheduler-locking off|on|step:
// 在调式某一个线程时,其他线程是否执行。在使用step或continue命令调试当前被调试线程的时候,其他线程也是同时执行的,如果我们只想要被调试的线程执行,而其他线程停止等待,那就要锁定要调试的线程,只让他运行。

off
//不锁定任何线程,默认值。

on
//锁定其他线程,只有当前线程执行。

step
//在step(单步)时,只有被调试线程运行。

set non-stop on/off
//当调式一个线程时,其他线程是否运行。

set pagination on/off:
//在使用backtrace时,在分页时是否停止。

set target-async on/off
//同步和异步。同步,gdb在输出提示符之前等待程序报告一些线程已经终止的信息。而异步的则是直接返回。

show scheduler-locking
// 查看当前锁定线程的模式

推荐阅读
  • 使用Boost.Asio进行异步数据处理的应用程序主要依赖于两个核心概念:I/O服务和I/O对象。I/O服务抽象了操作系统接口,使得异步操作能够高效地执行。I/O对象则代表了具体的网络资源,如套接字和文件描述符,通过这些对象可以实现数据的读写操作。本文详细介绍了这两个概念在Boost.Asio中的应用及其在网络编程中的重要性。 ... [详细]
  • 在操作系统中,阻塞状态与挂起状态有着显著的区别。阻塞状态通常是指进程因等待某一事件(如I/O操作完成)而暂时停止执行,而挂起状态则是指进程被系统暂时移出内存,以释放资源或降低系统负载。此外,本文还深入分析了`sleep()`函数的实现机制,探讨了其在不同操作系统中的具体实现方式及其对进程调度的影响。通过这些分析,读者可以更好地理解操作系统如何管理进程的不同状态以及`sleep()`函数在其中的作用。 ... [详细]
  • 深入RTOS实践,面对原子操作提问竟感困惑
    在实时操作系统(RTOS)的实践中,尽管已经积累了丰富的经验,但在面对原子操作的具体问题时,仍感到困惑。本文将深入探讨RTOS中的原子操作机制,分析其在多任务环境下的重要性和实现方式,并结合实际案例解析常见的问题及解决方案,帮助读者更好地理解和应用这一关键技术。 ... [详细]
  • Python与R语言在功能和应用场景上各有优势。尽管R语言在统计分析和数据可视化方面具有更强的专业性,但Python作为一种通用编程语言,适用于更广泛的领域,包括Web开发、自动化脚本和机器学习等。对于初学者而言,Python的学习曲线更为平缓,上手更加容易。此外,Python拥有庞大的社区支持和丰富的第三方库,使其在实际应用中更具灵活性和扩展性。 ... [详细]
  • 在Linux系统中,`inet_pton` 和 `inet_ntop` 是两个重要的IP地址转换函数,它们能够实现IP地址在“点分十进制”和“整数”格式之间的相互转换。特别是 `inet_pton`,它不仅支持IPv4,还支持IPv6地址的转换,广泛应用于网络编程中,确保了不同格式IP地址的高效处理和兼容性。本文将详细探讨这两个函数的内部实现机制及其在网络编程中的具体应用。 ... [详细]
  • 本文作为“实现简易版Spring系列”的第五篇,继前文深入探讨了Spring框架的核心技术之一——控制反转(IoC)之后,将重点转向另一个关键技术——面向切面编程(AOP)。对于使用Spring框架进行开发的开发者来说,AOP是一个不可或缺的概念。了解AOP的背景及其基本原理,对于掌握这一技术至关重要。本文将通过具体示例,详细解析AOP的实现机制,帮助读者更好地理解和应用这一技术。 ... [详细]
  • 从无到有,构建个人专属的操作系统解决方案
    操作系统(OS)被誉为程序员的三大浪漫之一,常被比喻为计算机的灵魂、大脑、内核和基石,其重要性不言而喻。本文将详细介绍如何从零开始构建个人专属的操作系统解决方案,涵盖从需求分析到系统设计、开发与测试的全过程,帮助读者深入理解操作系统的本质与实现方法。 ... [详细]
  • 如何将PHP文件上传至服务器及正确配置服务器地址 ... [详细]
  • Ceph API微服务实现RBD块设备的高效创建与安全删除
    本文旨在实现Ceph块存储中RBD块设备的高效创建与安全删除功能。开发环境为CentOS 7,使用 IntelliJ IDEA 进行开发。首先介绍了 librbd 的基本概念及其在 Ceph 中的作用,随后详细描述了项目 Gradle 配置的优化过程,确保了开发环境的稳定性和兼容性。通过这一系列步骤,我们成功实现了 RBD 块设备的快速创建与安全删除,提升了系统的整体性能和可靠性。 ... [详细]
  • 本文详细介绍了如何在Linux系统中搭建51单片机的开发与编程环境,重点讲解了使用Makefile进行项目管理的方法。首先,文章指导读者安装SDCC(Small Device C Compiler),这是一个专为小型设备设计的C语言编译器,适合用于51单片机的开发。随后,通过具体的实例演示了如何配置Makefile文件,以实现代码的自动化编译与链接过程,从而提高开发效率。此外,还提供了常见问题的解决方案及优化建议,帮助开发者快速上手并解决实际开发中可能遇到的技术难题。 ... [详细]
  • 提升工作效率:掌握这些技巧,IDEA 使用效率翻倍 | IDEA 高效操作指南
    提升工作效率:掌握这些技巧,IDEA 使用效率翻倍 | IDEA 高效操作指南 ... [详细]
  • 利用ViewComponents在Asp.Net Core中构建高效分页组件
    通过运用 ViewComponents 技术,在 Asp.Net Core 中实现了高效的分页组件开发。本文详细介绍了如何通过创建 `PaginationViewComponent` 类并利用 `HelloWorld.DataContext` 上下文,实现对分页参数的定义与管理,从而提升 Web 应用程序的性能和用户体验。 ... [详细]
  • 开发心得:利用 Redis 构建分布式系统的轻量级协调机制
    开发心得:利用 Redis 构建分布式系统的轻量级协调机制 ... [详细]
  • 本文探讨了将PEBuilder转换为DIBooter.sh的方法,重点介绍了如何将DI工具集成到启动层,实现离线镜像引导安装。通过使用DD命令替代传统的grub-install工具,实现了GRUB的离线安装。此外,还详细解析了bootice工具的工作原理及其在该过程中的应用,确保系统在无网络环境下也能顺利引导和安装。 ... [详细]
  • ZeroMQ在云计算环境下的高效消息传递库第四章学习心得
    本章节深入探讨了ZeroMQ在云计算环境中的高效消息传递机制,涵盖客户端请求-响应模式、最近最少使用(LRU)队列、心跳检测、面向服务的队列、基于磁盘的离线队列以及主从备份服务等关键技术。此外,还介绍了无中间件的请求-响应架构,强调了这些技术在提升系统性能和可靠性方面的应用价值。个人理解方面,ZeroMQ通过这些机制有效解决了分布式系统中常见的通信延迟和数据一致性问题。 ... [详细]
author-avatar
手机用户2502896641
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有