我一直想知道调试器是如何工作的?特别是可以“附加”到已经运行的可执行文件的那个。我知道编译器将代码翻译为机器语言,但是调试器如何“知道”它所附加的内容?

有帮助吗?

解决方案

调试器如何工作的细节取决于您正在调试的内容以及操作系统的内容。对于Windows上的本机调试,您可以在MSDN上找到一些详细信息: Win32调试API

用户通过名称或进程ID告诉调试器要连接的进程。如果是名称,则调试器将查找进程ID,并通过系统调用启动调试会话;在Windows下,这将是 DebugActiveProcess

一旦附加,调试器将进入一个事件循环,就像任何UI一样,但是不是来自窗口系统的事件,操作系统将根据正在调试的过程中发生的事情生成事件–例如发生异常。请参阅 WaitForDebugEvent

调试器能够读取和写入目标进程的虚拟内存,甚至可以通过操作系统提供的API调整其寄存器值。请参阅Windows的调试功能列表。

调试器能够使用符号文件中的信息将地址转换为源代码中的变量名称和位置。符号文件信息是一组独立的API,并不是操作系统的核心部分。在Windows上,这是通过调试接口访问SDK

如果您正在调试托管环境(.NET,Java等),则该过程通常看起来类似,但细节不同,因为虚拟机环境提供调试API而不是底层操作系统。

其他提示

据我所知:

对于x86上的软件断点,调试器用 CC 替换指令的第一个字节( int3 )。这是通过 WriteProcessMemory 在Windows上。当CPU到达该指令时,执行 int3 ,这会导致CPU生成调试异常。操作系统收到此中断,意识到正在调试进程,并通知调试器进程断点被命中。

在命中断点并且进程停止后,调试器会在其断点列表中查找,并将 CC 替换为最初的字节。调试器在 TF ,陷阱标志 http://en.wikipedia.org/wiki/FLAGS_register“rel =”noreferrer“> EFLAGS (通过修改 上下文 ),并继续此过程。陷阱标志使CPU自动生成单步异常( INT 1 )下一条指令。

当正在调试的进程下次停止时,调试器再次用 CC 替换断点指令的第一个字节,然后继续该过程。

我不确定这是否完全是由所有调试器实现的,但是我写了一个Win32程序,它设法使用这种机制调试自己。完全没用,但很有教育意义。

在Linux中,调试过程从 ptrace(2)系统调用开始。 这篇文章有一个很棒的教程,介绍如何使用 ptrace 来实现一些简单的调试构造。

如果您使用的是 Windows 操作系统,John Robbins 的“调试 Microsoft .NET 和 Microsoft Windows 的应用程序”是一个很好的资源:

(或者甚至是旧版本: “调试应用程序”)

本书有一章介绍调试器如何工作,其中包括几个简单(但有效)调试器的代码。

由于我不熟悉 Unix/Linux 调试的细节,这些东西可能根本不适用于其他操作系统。但我猜想,作为一个非常复杂的主题的介绍,概念(如果不是细节和 API)应该“移植”到大多数操作系统。

了解调试的另一个有价值的来源是英特尔CPU手册(英特尔® 64和IA-32架构 软件开发人员手册)。在第3A卷第16章中,它介绍了调试的硬件支持,例如特殊异常和硬件调试寄存器。以下是该章:

T(陷阱)标志,TSS—尝试时生成调试异常(#DB) 切换到在TSS中设置了T标志的任务。

我不确定Window或Linux是否使用此标志,但阅读该章节非常有趣。

希望这有助于某人。

我的理解是,当你编译一个应用程序或DLL文件时,它编译的任何内容都包含代表函数和变量的符号。

当您进行调试构建时,这些符号比发布版本更详细,因此允许调试器为您提供更多信息。当您将调试器附加到进程时,它会查看当前正在访问哪些函数并从此处解析所有可用的调试符号(因为它知道编译文件的内部结构是什么样的,它可以确定内存中可能存在的内容) ,含有整数,浮点数,字符串等内容。就像第一张海报所说,这些信息以及这些符号的工作方式在很大程度上取决于环境和语言。

我认为这里有两个主要问题需要回答:

<强> 1。调试器如何知道发生了异常?

当正在调试的进程中发生异常时,在目标进程中定义的任何用户异常处理程序有机会响应异常之前,操作系统会通知调试程序。如果调试器选择不处理此(第一次机会)异常通知,则异常调度序列继续进行,然后目标线程有机会处理异常(如果它想要这样做)。如果目标进程未处理SEH异常,则会向调试器发送另一个调试事件(称为第二次机会通知),以通知它在目标进程中发生了未处理的异常。 来源


<强> 2。调试器如何知道如何在断点处停止?

简化的回答是:当你在程序中放入一个断点时,调试器用一个int3指令替换你的代码,这个指令是一个软件中断。作为一种效果,程序被暂停并调用调试器。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top