当前位置:首页 > 生活 > 正文内容

调试(调试器到底怎样工作)

wwwnzt88com2年前 (2022-12-21)生活40

编译自: https://opensource.com/article/18/1/how-debuggers-really-work

作者: Levente Kurusa

译者: Stephen

你也许用过调速器检查过你的代码,但你知道它们是如何做到的吗?

调试器是大多数(即使不是每个)开发人员在软件工程职业生涯中至少使用过一次的那些软件之一,但是你们中有多少人知道它们到底是如何工作的?我在悉尼 linux.conf.au 2018 的演讲中,将讨论从头开始编写调试器……使用 Rust !

在本文中,术语 调试器(debugger)和 跟踪器(tracer)可以互换。 “ 被跟踪者(Tracee)”是指正在被跟踪器跟踪的进程。

ptrace 系统调用

大多数调试器严重依赖称为 ptrace(2) 的系统调用,其原型如下:

long ptrace(enum __ptrace_request request, pid_t pid, void *addr, void *data);

这是一个可以操纵进程几乎所有方面的系统调用;但是,在调试器可以连接到一个进程之前,“被跟踪者”必须以请求 PTRACE_TRACEME 调用 ptrace。这告诉 Linux,父进程通过 ptrace 连接到这个进程是合法的。但是……我们如何强制一个进程调用 ptrace?很简单!fork/execve 提供了在 fork 之后但在被跟踪者真正开始使用 execve 之前调用 ptrace 的简单方法。很方便地,fork 还会返回被跟踪者的 pid,这是后面使用 ptrace 所必需的。

现在被跟踪者可以被调试器追踪,重要的变化发生了:

  • 每当一个信号被传送到被跟踪者时,它就会停止,并且一个可以被 wait 系列的系统调用捕获的等待事件被传送给跟踪器。
  • 每个 execve 系统调用都会导致 SIGTRAP 被传递给被跟踪者。(与之前的项目相结合,这意味着被跟踪者在一个 execve 完全发生之前停止。)

这意味着,一旦我们发出 PTRACE_TRACEME 请求并调用 execve 系统调用来实际在被跟踪者(进程上下文)中启动程序时,被跟踪者将立即停止,因为 execve 会传递一个 SIGTRAP,并且会被跟踪器中的等待事件捕获。我们如何继续?正如人们所期望的那样,ptrace 有大量的请求可以用来告诉被跟踪者可以继续:

  • PTRACE_CONT:这是最简单的。 被跟踪者运行,直到它接收到一个信号,此时等待事件被传递给跟踪器。这是最常见的实现真实世界调试器的“继续直至断点”和“永远继续”选项的方式。断点将在下面介绍。
  • PTRACE_SYSCALL:与 PTRACE_CONT 非常相似,但在进入系统调用之前以及在系统调用返回到用户空间之前停止。它可以与其他请求(我们将在本文后面介绍)结合使用来监视和修改系统调用的参数或返回值。系统调用追踪程序 strace 很大程度上使用这个请求来获知进程发起了哪些系统调用。
  • PTRACE_SINGLESTEP:这个很好理解。如果您之前使用过调试器(你会知道),此请求会执行下一条指令,然后立即停止。

我们可以通过各种各样的请求停止进程,但我们如何获得被调试者的状态?进程的状态大多是通过其寄存器捕获的,所以当然 ptrace 有一个请求来获得(或修改)寄存器:

  • PTRACE_GETREGS:这个请求将给出被跟踪者刚刚被停止时的寄存器的状态。
  • PTRACE_SETREGS:如果跟踪器之前通过调用 PTRACE_GETREGS 得到了寄存器的值,它可以在参数结构中修改相应寄存器的值,并使用 PTRACE_SETREGS 将寄存器设为新值。
  • PTRACE_PEEKUSER 和 PTRACE_POKEUSER:这些允许从被跟踪者的 USER 区读取信息,这里保存了寄存器和其他有用的信息。 这可以用来修改单一寄存器,而避免使用更重的 PTRACE_{GET,SET}REGS 请求。

在调试器仅仅修改寄存器是不够的。调试器有时需要读取一部分内存,甚至对其进行修改。GDB 可以使用 print 得到一个内存位置或变量的值。ptrace 通过下面的方法实现这个功能:

  • PTRACE_PEEKTEXT 和 PTRACE_POKETEXT:这些允许读取和写入被跟踪者地址空间中的一个字。当然,使用这个功能时被跟踪者要被暂停。

真实世界的调试器也有类似断点和观察点的功能。 在接下来的部分中,我将深入体系结构对调试器支持的细节。为了清晰和简洁,本文将只考虑 x86。

体系结构的支持

ptrace 很酷,但它是如何工作? 在前面的部分中,我们已经看到 ptrace 跟信号有很大关系:SIGTRAP 可以在单步跟踪、execve 之前以及系统调用前后被传送。信号可以通过一些方式产生,但我们将研究两个具体的例子,以展示信号可以被调试器用来在给定的位置停止程序(有效地创建一个断点!):

  • 未定义的指令:当一个进程尝试执行一个未定义的指令,CPU 将产生一个异常。此异常通过 CPU 中断处理,内核中相应的中断处理程序被调用。这将导致一个 SIGILL 信号被发送给进程。 这依次导致进程被停止,跟踪器通过一个等待事件被通知,然后它可以决定后面做什么。在 x86 上,指令 ud2 被确保始终是未定义的。
  • 调试中断:前面的方法的问题是,ud2 指令需要占用两个字节的机器码。存在一条特殊的单字节指令能够触发一个中断,它是 int $3,机器码是 0xCC。 当该中断发出时,内核向进程发送一个 SIGTRAP,如前所述,跟踪器被通知。

这很好,但如何我们才能胁迫被跟踪者执行这些指令? 这很简单:利用 ptrace 的 PTRACE_POKETEXT 请求,它可以覆盖内存中的一个字。 调试器将使用 PTRACE_PEEKTEXT 读取该位置原来的值并替换为 0xCC ,然后在其内部状态中记录该处原来的值,以及它是一个断点的事实。 下次被跟踪者执行到该位置时,它将被通过 SIGTRAP 信号自动停止。 然后调试器的最终用户可以决定如何继续(例如,检查寄存器)。

好吧,我们已经讲过了断点,那观察点呢? 当一个特定的内存位置被读或写,调试器如何停止程序? 当然你不可能为了能够读或写内存而去把每一个指令都覆盖为 int $3。有一组调试寄存器为了更有效的满足这个目的而被设计出来:

  • DR0 到 DR3:这些寄存器中的每个都包含一个地址(内存位置),调试器因为某种原因希望被跟踪者在那些地址那里停止。 其原因以掩码方式被设定在 DR7 寄存器中。
  • DR4 和 DR5:这些分别是 DR6 和 DR7 过时的别名。
  • DR6:调试状态。包含有关 DR0 到 DR3 中的哪个寄存器导致调试异常被引发的信息。这被 Linux 用来计算与 SIGTRAP 信号一起传递给被跟踪者的信息。
  • DR7:调试控制。通过使用这些寄存器中的位,调试器可以控制如何解释 DR0 至 DR3 中指定的地址。位掩码控制监视点的尺寸(监视1、2、4 或 8 个字节)以及是否在执行、读取、写入时引发异常,或在读取或写入时引发异常。

由于调试寄存器是进程的 USER 区域的一部分,调试器可以使用 PTRACE_POKEUSER 将值写入调试寄存器。调试寄存器只与特定进程相关,因此在进程抢占并重新获得 CPU 控制权之前,调试寄存器会被恢复。

冰山一角

我们已经浏览了一个调试器的“冰山”:我们已经介绍了 ptrace,了解了它的一些功能,然后我们看到了 ptrace 是如何实现的。 ptrace 的某些部分可以用软件实现,但其它部分必须用硬件来实现,否则实现代价会非常高甚至无法实现。

当然有很多我们没有涉及。例如“调试器如何知道变量在内存中的位置?”等问题由于空间和时间限制而尚未解答,但我希望你从本文中学到了一些东西;如果它激起你的兴趣,网上有足够的资源可以了解更多。

想要了解更多,请查看 linux.conf.au 中 Levente Kurusa 的演讲 Let's Write a Debugger! ,于一月 22-26 日在悉尼举办。

<hr>

via: https://opensource.com/article/18/1/how-debuggers-really-work

作者: Levente Kurusa 译者: stephenxs 校对: wxy

本文由 LCTT 原创编译, Linux中国 荣誉推出

点击“了解更多”可访问文内链接

扫描二维码推送至手机访问。

版权声明:本文由小草网发布,如需转载请注明出处。

本文链接:http://www.nzt88.com/82046.html

分享给朋友:

“调试(调试器到底怎样工作)” 的相关文章

烛之武退秦师拼音(烛之武退秦师拼音朗读)

烛之武退秦师拼音(烛之武退秦师拼音朗读)

烛之武退秦师中这些字的读音:鄙,薄,陪,微,知!可以读作bei。 意思是“增加”。 卑鄙的毕三声微圩一声识知芝四声左传中烛之武退秦师里一句"且贰于楚也"中贰的读法拼音(,拼音)R0是数字2的大写字母,有以前2元的纸币就可以看了。 我平时读的er一二之二...

镇远号(镇远号铁锚拿回来了吗)

镇远号战列舰的介绍镇远号战舰是中国清朝海军在德国伏尔加造船厂订购建造的炮塔铁甲舰。 清末北洋水师主力舰之一。 属于定远级铁甲舰。 当时被称为东洋一坚舰。 1880年(光绪六年)订购德国伏尔加造船厂,排水量7340吨,马力6000匹,航速14.5节,造价110.3万库平银。 1885年,刘昂等带回国。...

长发公主的故事(长发公主的故事原文完整版)

并非所有公主都是幸福的,《长发公主:幸福前奏》诉说了怎样的故事?以前,我喜欢梦工厂制作的比较成人化的三维动画,对迪士尼看起来很幼稚的动画不太感兴趣。 后来看了迪士尼的《长发公主:幸福前奏》,觉得这部电影确实很值得期待。 故事紧凑流畅,题材特别新颖,角色鲜明,画面绚烂多彩,很美,像水彩画,那长发公主更...

glove是什么意思(glove是什么意思英语)

glove是什么意思(glove是什么意思英语)

glove怎么读glove的读音为[=LV],具体释义如下。手套; (用于拳击、棒球等)加垫防护手套; 给……戴手套的比赛中用戴手套的手连接。词类:通常在文中既可以成为名词,也可以成为动词。组合固定: Glovepuppetry袋戏。1、hebitthefingersofhisrightglovea...

幽芳的意思(幽芳的意思)

幽芳的意思是什么幽芳的幽(意思是安静、淡淡、清新的自然。 追述:幽芳:基本解释:1.清香的含义。 也指香花。 2 .比喻高尚的德行。 谢谢您的录用!缕缕幽芳的意思是什么?缕幽芳(幽芳是指香气清淡芬芳。 幽芳写下了梅花纯洁的品格。来自梅花魂(陈慧瑛创作小说)原文摘录:家乡的梅花又开了。 那冰冷而根深蒂...

英语听力入门3000第二册答案(英语听力入门3000第二册答案unit7)

求英语听力入门3000第二册答案这一部分主要考察宾语复合结构的知识点:从动词上区分开来,几个动词后面往往跟有二宾语。 这类动词有give、show、bring、read、pass、lend、tell、leave、teach、write、buy、sing等。 例如,theteachergiveseac...

以孤篇压倒全唐之作(以孤篇压倒全唐之作作者)

那首诗获得了“以孤篇压倒全唐”?还说用孤编压迫全唐吗? 这当然是张若虚写的《春江花月夜》啊。号称孤篇压全唐的是哪首诗?唐、张若虚、<; 春江花月夜>;张若虚的《春江花月夜》首诗,被闻一多先生誉为“孤篇压全唐朝之作”,是“诗中之诗,顶之巅”。《春江花月夜》紧扣春、江、花、月、夜五景格局全篇,在...

一声风雷电打一生肖(今期一声风雷电是什么生肖)

风雨雷电各代表什么生肖?风雨雷在十二生肖中是龙。龙在中国传统十二生肖中排第五。 龙是中国传说中能带来善变、腾云降雨、造福万物的神异动物,是众鳞虫之长,居四灵(龙、凤、麒麟、龟)之首。 古籍记述其形象各种各样。 有鳞的叫蛟龙,有翅膀的叫应龙,有角的多其龙,无角的叫虬。 名字叫蛟,名字叫龙。 其中很多是...

秀逗了是什么意思(秀逗糖是什么意思)

秀逗了是什么意思(秀逗糖是什么意思)

秀逗是什么意思?这就是人脑“短路”,也就是说“一时变傻,脑子转不动了”。说“秀气”有一次,有一位美眉在网上聊天,说我很有趣。 我很高兴听到那个。 我还以为是在夸奖“对话有趣,说话有趣”,结果知道她本来是在骂我。 肖曼,即使大脑进水。“秀逗”一词是港台传来的,是日语对英语“short”的音译,原本意思...

熊瞎子掰苞米(熊瞎子掰苞米)

熊瞎子掰苞米(熊瞎子掰苞米)

歇后语熊瞎子掰苞米的下一句应该怎么说?熊盲人煮着打碎米-打碎一个,丢一个。“熊瞎子打破玉米,失去一个”的说法,意味着有些人心灵笨拙,学新忘旧,很难进步。相关故事典故:童话说,熊在割玉米穗时,把一个穗折下来夹在腋窝里,另一个穗破了又夹在腋窝里,正要抬起胳膊夹第二个穗时,第一个穗掉了下来。 所以不管怎么...

白川恭子(白川恭子心悦泽)

白川恭子(白川恭子心悦泽)

姉汁的登场人物图白川悠() () () ) CV :成濑未亚) TSF性转换发生时,介绍OVA )主人公。 白川家的小弟弟。 为了解除诅咒,收集嫂子三人的汁液。 因为诅咒的影响,在目的达成之前能听懂科里的话。 如果汤汁收集失败(如果在指定时间收集未完成,或者瓶子被别人发现),诅咒(俗称TSF...

星期三左眼跳(星期三左眼跳是什么意思)

星期三左眼跳(星期三左眼跳是什么意思)

星期三左眼跳是什么预兆如果科学地解释左眼皮跳是什么前兆,那么科学上唯一的解释就是这只是人类的正常反应,让我们从精算师的角度来思考左眼皮跳是怎么回事。说到眼皮跳,我想大家都经历过。 而且,很多人认为眼睛后面会跳,往往预示着会发生什么事。 所以,说起眼角跳动,几乎每个人都有自己的体验。 另外,一些书记载...

西游记每章概括30字(西游记第十二章概括)

西游记每回概括50字?东胜神洲自豪地在国海有花果山,山顶上仙石孕育了石猴。 住在溪边的石猴发现了一个叫“水帘洞”的石洞,被群猴拥戴为王。 三五百年后,石猴突然因人生无常而哀叹活不了多久。 根据一只老猴子的指示,石猴经过南面的赡养训练洲前往西牛贺洲,登上灵台方寸山,进入斜月三星洞,拜谒须菩提祖师,被收...

茶汤李(茶汤李总店地址)

北京市茶汤李餐饮管理有限公司怎么样?北京市茶汤李餐饮管理有限公司是1998-06-17在北京市西城区注册成立的有限责任公司(自然人投资或控股公司),注册地址在北京市西城区几条胡同5号。北京市茶汤李餐饮管理有限公司统一社会信用代码/注册号为911101026330869323,企业法人李跃表示,目前企...

魏文侯与虞人期猎翻译(魏文侯与虞人期猎翻译命驾将适野)

魏文侯守信的“文侯与虞人期猎”翻译魏文侯答应和虞人一起打猎。 到了那天,正好碰上大风,周围的人劝他不要去,文侯没听。 “不行。 大风一吹就会失信于人,我不会这么做的。 ’所以我自己开车去签约了。本回答由提问者推荐魏文侯守信的“文侯与虞人期猎”翻译魏文侯答应和虞人一起打猎。 到了那天,正好碰上大风,周...

天秤座的拼音(天秤座的拼音是多音字吗)

天秤座的拼音?天、秤、座读法为绾n、chng、zu;声调为阴平、去声、去声。=====================================柳浪听了莺儿的芝麻,尽力回答你的录用是我们坚持百度的动力天秤座标准读音是什么?绾tinchngzu;天秤座( Libra ),9月23日――10月2...