[hellogcc] Re: [投稿] Debugger Not In Depth: inferior call

  • From: asmwarrior <asmwarrior@xxxxxxxxx>
  • To: hellogcc@xxxxxxxxxxxxx
  • Date: Sat, 25 Jun 2011 22:09:41 +0800

On 2011-6-25 22:00, Yao Qi wrote:
决定写一系列文章,关于调试器内部机理的,名字叫做Debugger Not In Depth。为了以后方便保存,我都是用latex写的,tex
->  html ->  txt

今天这篇是关于inferior call,欢迎意见。


1 inferior call

inferior call 可以被简单地理解为“调试器在当前的堆栈上,主动调用被调试程序的函数
,并且正确的得到函数的返回值(这一句好像有点多余)”。inferior call理解起来,远
比我们想象的简单,这个功能在我们的调试过程经常会被用到。比如在调试GCC rtl的时候
,我们经常在GDB中用 p print_rtx (rtx),来打印rtx 的内容。这就是一个inferior
call。我们来仔细想一下,第一,函数print_rtx (rtx)是在被调试程序那里执行的,而不
是在GDB这里;第二,参数rtx是GDB传给被调试程序的函数;第三,GDB能够正确得到
print_rtx (rtx)这个函数的返回值;最后,被调试程序在执行完成print_rtx (rtx)后,
仍然停在原来的位置,程序的状态没有任何变化。上边这几点,就是调试器为了实现
inferior call所需要做到的,或者,需要保证的。
下来我们想想,调试器应该怎样保证上边四条,

  1. 第一,函数是在被调试程序那里实行的。这个容易实现,调试器需要找到函数的入口
     地址,把寄存器pc设置为函数的入口地址,然后用ptrace让被调试程序继续执行(
     PTRACE_CONT)就可以了。
  2. 第二,调试器传递参数给调用的函数。这个相对麻烦一些,因为调试器需要知道当前
     被调试程序所在系统的函数调用规则(function call convention),也就是规定,
     每一个函数的参数,应该如何传递给被调用函数。这个也是系统ABI的一部分。简单点
     说,如果函数有四个参数,这个四个参数在函数调用的时候,应该在什么位置,是在
     寄存器里边还是在堆栈上?调试器在知道这些规范以后,必须按照规范把被调用函数
     需要的参数,放在规定的地方。
  3. 第三, 调试器需要得到函数调用的返回值。函数调用的返回值所在的位置同样规范在
     系统的ABI中。函数的返回值是在寄存器里边,还是堆栈上?调试器根据这个规范,从
     规定的位置,得到函数的返回值。
  4. 第四,调试器需要函数调用完成后,程序依然停在之前的位置,没有任何变化。被调
     用的函数是不知道它被调用是一般的正常调用,还是调试器用inferior call。所以,
     调试器在程序返回地址上,做了一些手脚。一般来说,程序的返回地址应该是调用这
     个函数的指令的下一条指令。在inferior call,调试器会把函数调用的返回地址设置
     为一个特殊的地址,并且在这个地址上设置一个断点。这样,当程序返回的时候,调
     试器就能够保证程序执行完成后,程序就停下来。

这样看来,只要能够对系统的ABI有个全面的了解,实现inferior call应该没有什么困难
。下来我们看看GDB里边,是怎么实现 inferior call的,

[这里还有一个表格,帖进来就乱了,参见附件。]

牛,全部概念我都理解了,厉害!
嘿嘿,你为什么latex变成html之后,再变成txt???奇怪。

Other related posts: