繁体   English   中英

调试器实施-跳过问题

[英]Debugger implementation - Step over issue

我目前正在为脚本虚拟机编写调试器。 脚本的编译器生成调试信息,例如函数入口点,变量作用域,名称,行映射指令等。

但是,并遇到了跨步问题。

现在,我有以下内容:1.查找当前IP 2.从该IP地址获取源代码行。3.获取下一个(有效的)源代码行。4.获取下一个有效源代码行开始的IP 5.设置一个临时地址。该指令的断点

或:如果下一个源代码行不再属于同一功能,则在返回地址后的下一个有效源代码行上设置温度断点。

到目前为止,这很好。 但是,我似乎在跳跃方面遇到了问题。

例如,使用以下代码:

n = 5; // Line A
if(n == 5) // Line B
{
    foo(); // Line C
}
else
{
    bar(); // Line D
    --n;
}

给定此代码,如果我在B行上并选择跨步,则为断点确定的IP将在C行上。但是,如果条件跳转的结果为false,则应将其放在D行上。其中,跨步操作不会在预期的位置停止(或者完全不会停止)。

那里几乎没有关于此特定问题的调试器实现的信息。 但是,我发现了这个 尽管这是针对Windows上的本机调试器的,但该理论仍然适用。

似乎作者在“实施跨步”一节中也没有考虑此问题,他说:

 1. The UI-threads calls CDebuggerCore::ResumeDebugging with EResumeFlag set to StepOver. This tells the debugger thread (having the debugger-loop) to put IBP on next line. 2. The debugger-thread locates next executable line and address (0x41141e), it places an IBP on that location. 3. It calls then ContinueDebugEvent, which tells the OS to continue running debuggee. 4. The BP is now hit, it passes through EXCEPTION_BREAKPOINT and reaches at EXCEPTION_SINGLE_STEP. Both these steps are same, including instruction reversal, EIP reduction etc. 5. It again calls HaltDebugging, which in turn, awaits user input. 

再次:

调试器线程查找下一个可执行行和地址(0x41141e),它将IBP放置在该位置。

但是,在涉及跳转的情况下,该声明似乎并不成立。

有人遇到过这个问题吗? 如果是这样,您是否有解决此问题的技巧?

好的,因为这似乎有点黑魔法,所以在这种特殊情况下,最聪明的事情是枚举下一行开始的指令(或指令流结束+ 1),然后在停止之前运行那么多指令再次。

唯一的陷阱是我必须跟踪堆栈帧,以防执行CALL。 这些指令应在不计入步数的情况下运行。

由于此线程在搜索“调试器实施步骤”时首先出现在Google中。 我将分享有关x86架构的经验。

首先,请执行以下步骤:基本上是单步执行说明,并检查与当前EIP对应的行是否发生了更改。 (您可以使用DIA SDK或读取侏儒调试数据来查找EIP的当前行)。

在单步执行的情况下:在单步执行下一条指令之前,您需要检查当前指令是否为CALL指令。 如果是CALL指令,则在其后的指令上放置一个临时断点,并继续执行直到执行停止(然后将其删除)。 在这种情况下,您实际上可以在汇编程序级别有效地跳过函数调用,在源代码级别也是如此。

无需管理堆栈框架(除非您需要处理单行递归函数)。 这种类比也可以应用于其他架构。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM