gdb调试多线程底层实现原理

哈喽,我是子牙老师,一个手写过操作系统、编程语言、Java虚拟机、docker、Ubuntu系统,玩透Windows内核、Linux内核...的硬核男人

现实中,我们写的程序一般都是多线程程序。如果多线程程序出问题了,就需要用到gdb的多线程调试功能,非常方便,直接通过thread tid切到可能存在问题的线程,单步执行,看堆栈、寄存器、内存,很快就能找到错误原因

这么强大的功能背后,底层实现原理是什么呢?我们自己写调试器,该如何实现呢?本篇文章为你全方位揭晓!本篇文章看完,gdb远程调试的all,你就过关了!

本篇文章需要前面文章的功底,如果你没看过,建议看看《从零手写gdb调试器》《调试器是如何让代码停下来的》《gdb调试器底层实现原理》《gdb的放过去是如何做到的》

以下,enjoy

Linux内核层面

刚开始接触,难免丈二和尚摸不着头脑,那不妨猜测一下,Linux内核层面会如何实现呢?

那也不能无凭无据的乱猜对吧,根据我们研究调试器的经验+使用gdb调试多线程程序的经验,肯定是Linux内核创建一个线程,就把这个创建线程事件报告给调试器进程。会以何种方式报告呢?信号。什么信号呢?不知道,得看代码找证据。那就开始找证据

研究Linux内核,肯定要借助单步调试环境。那在哪下断点呢?得知道使用pthread_create创建线程,进入内核后,调用的是哪个函数。课程《实战Linux内核》三期讲过,__do_fork函数

通过单步调试Linux内核,跟踪代码执行,发现确实跟我们猜想的一样

那发送的是什么信号呢?进入函数ptrace_event_pid就能找到答案

也是SIGTRAP信号,但是还拼接了点东西。这个要记住,后面写调试器代码会用上。这个event是多少呢?3

用户态实现

如果trace值为0,就不会执行ptrace_event_pid,发送SIGTRAP信号。想想也有道理,如果创建线程,不管三七二十一,都给父进程发SIGTRAP信号,是有点多此一举了。那这个动作肯定是由用户触发了,用户告诉Linux内核:嘿,大兄弟,有线程创建知会我一声

用户怎么告诉内核呢?这样

进入Linux内核后呢?这样

这样,被调试进程的ptrace上就多了很多东西,这个多出来的东西会影响被调试进程创建线程的参数clone_flags(这个环节在pthread库中,偷个懒,不找了)

最终会执行ptrace_event_pid函数,给调试进程发送SIGTRAP信号

妙不妙?反正我研究Linux内核,读Linux内核源码,特别上瘾!

写调试器

来,开干

手写告诉Linux内核:大兄弟,打个桩,有线程创建,告诉我

终于,等了许久,有线程创建了,SIGTRAP信号来了

捕捉到线程创建,完整的操作应该是这样

你在gdb中,使用info threads查看所有的线程信息,通过thread tid能够切换线程,都是以这个代码为基础实现的,来看看完整的代码

至此,gdb调试多线程的底层原理,你应该全部掌握了吧!

如果你也想像我一样,打通所有技术认知,可以随意玩汇编、C语言、Linux用户态、Linux内核态、调试器,欢迎跟我学习。全国唯一一个人做了整个计算机体系课程的人:手写JVM、手写操作系统、实战Linux内核、手写Ubuntu Linux系统、手写编程语言、手写docker、手写调试器

相关推荐
还卿一钵无情泪3 小时前
Unsloth 微调 构建自己的大模型 没有GPU也能微调
linux·开发语言·人工智能·python·大模型·nlp·unsloth
高山有多高3 小时前
【Linux笔记】IO模型
linux
不会就选b3 小时前
Linux之TCP理论<1>
linux·运维·服务器
小π军4 小时前
操作系统面试题
java·linux·服务器
Lsetea5 小时前
curl用IP测试HTTPS报证书不匹配:--resolve与Host头别混用
linux·https·ssl证书·openssl·curl
Hao2855 小时前
Windows11 下把 WSL2 Ubuntu 26.04 装到 D 盘完整
linux
Android系统攻城狮5 小时前
Linux Gstreamer深度解析之gst_audio_encoder_get_frame_samples_min调用流程与实战(六十)
linux·运维·服务器·音视频·gstreamer音视频·音视频进阶·gstreamer音视频进阶
_upupup6 小时前
Linux中的自动化构建——make/Makefile
linux·运维·自动化
HEJOO96 小时前
Linux 设备驱动系列——使用全局工作队列
java·linux·算法
slimer7 小时前
07.进制转换上篇:位权展开与十进制互转
linux