C 语言调试器是怎么工作的呢?

这篇博客探讨了C语言调试器的工作机制,重点介绍了Linux Ptrace API在调试过程中的作用。调试器通过Ptrace API能够读写被调试进程的内存、CPU寄存器,控制执行流程并处理符号和调试信息。尽管Ptrace API提供了底层机制,但断点的实现涉及到更复杂的技巧,包括修改内存并在触发信号时处理。调试器还需要处理符号和调试信息,以便将二进制指令与源代码关联起来,提供更友好的调试体验。
摘要由CSDN通过智能技术生成

开始,让我们先研究它怎样才会不工作。它不能通过阅读和分析程序的二进制信息来模拟程序的运行。它其实能做,而那应该能起作用(Valgrind 内存调试器就是这样工作的),但是这样的话会很慢。Valgrind会让程序慢1000倍,但是GDB不会。它的工作机制与Qemu虚拟机一样。

所以到底是怎么回事?黑魔法?……不,如果那样的话就太简单了。

另一种猜想?……?破解!是的,这里正是这样的。操作系统内核也提供了一些帮助。

首先,关于Linux的进程机制需要了解一件事:父进程可以获得子进程的附加信息,也能够ptrace它们。并且你可以猜到的是,调试器是被调试的进程的父进程(或者它会变成父进程,在Linux中进程可以将一个进程变为自己子进程:-))

小编在这里小打扰一下,有兴趣学习c/c++编程的小伙伴可以加群466572167,群内有大量的资源可以供各位学习使用,更有大神以及许多小伙伴在群内交流解答,有兴趣的可以加群哦!

Linux Ptrace API

Linux Ptrace API 允许一个(调试器)进程来获取低等级的其他(被调试的)进程的信息。特别的,这个调试器可以:

读写被调试进程的内存 :PTRACE_PEEKTEXT、PTRACE_PEEKUSER、PTRACE_POKE……

读写被调试进程的CPU寄存器 PTRACE_GETREGSET、PTRACE_SETREGS

因系统活动而被提醒:PTRACE_O_TRACEEXEC, PTRACE_O_TRACECLONE, PTRACE_O_EXITKILL, PTRACE_SYSCALL(你可以通过这些标识区分exec syscall、clone、exit以及其他系统调用)

控制它的执行:PTRACE_SINGLESTEP、PTRACE_KILL、PTRACE_INTERRUPT、PTRACE_CONT (注意,CPU在这里是单步执行)

修改它的信号处理:PTRACE_GETSIGINFO、PTRACE_SETSIGINFO

Ptrace是如何实现的?

Ptrace的实现不在本文讨论的范围内,所以我不想进一步讨论,只是简单地解释它是如何工作的(我不是内核专家,如果我说错了请一定指出来,并原谅我过分简化:-))

Ptrace 是Linux内核的一部分,所以它能够获取进程所有内核级信息:

读写数据?Linux有copy_to/from_user

获取CPU寄存器?用copy_regset_to/from_user很轻松(这里没有什么复杂的,因为CPU寄存器在进程未被调度时保存在Linux的struct task_struct *调度结构中)。

修改信号处理?更新域last_siginfo

单步执行?在处理器出发执行前,设置进程task结构的right flag(ARM

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值