【问题标题】:attach source code to a running process, how does it work?将源代码附加到正在运行的进程,它是如何工作的?
【发布时间】:2014-05-08 05:54:22
【问题描述】:
我有一个使用 mysqlcppconn 责任编译的二进制文件。我也得到了 mysqlcppconn 的源代码。
我做了什么,我使用 Visual Studio 打开了 mysqlcppconn 源代码,导入 .exe 文件,将其设置为启动类,然后在源代码中放置一个断点。在调试模式下运行,当它到达断点时,我能够看到假设存储在 .exe 文件中的 mysqlcppconn 的变量值。这是怎么发生的?
我的理解是:
.exe 文件是内存中的指令列表,所以如果我认为 .exe 文件是输入输出活动,那么如果输入是 A 并且我们期望输出 B,编译器将使用
.exe 内存(说明)来指导 A 应该去哪里。但是当我使用源代码编译时,由于源代码产生了相同的指令,不知何故(这也是我不明白的地方),编译器决定使用源代码创建的指令而不是.exe文件来指导哪里A应该去。
有什么想法吗?
提前致谢。
【问题讨论】:
标签:
c++
compiler-construction
computer-science
【解决方案1】:
不,我不认为它是这样工作的。
如果您附加到一个正在运行的程序,它只会告诉调试器对哪个进程感兴趣,并且从中可以找到 EXE 文件和 PDB 符号文件。调试器可以从 PDB 符号中找到所需的源代码文件和与二进制代码匹配的行号。
当您在源代码中设置断点时,调试器会检查符号表并找出对应于二进制文件的位置。然后它在该位置的运行程序的二进制文件中放置一个断点。上次我查看了一个英特尔处理器,该处理器涉及用为此目的保留的不同单字节指令 (RST 3) 替换内存中二进制中的指令。在其他处理器上,机制会有所不同。
当执行遇到该特殊指令时,它会导致一个陷阱返回到调试器。调试器恢复正确的指令(以防您碰巧查看反汇编)并在其表中查找断点,找到正确的源代码并将其显示以供您查看。
它还会找到正确的堆栈帧并向您显示该函数中的所有局部变量。
当一切正常时,这有点神奇,但在幕后它却出奇地简单。
顺便说一句,这一切都可以在没有 PDB 文件或源代码文件的情况下工作,但是您只能使用调试器的反汇编。
【解决方案2】:
Visual Studio 一定在某处找到了符号文件 (*.pdb)。这些文件是在编译过程中生成的,其中包含将内存中的某些汇编代码与某些 C++ 源代码匹配所需的信息。这是因为二进制可执行文件不包含或包含很少关于它编译源代码的信息。如果你有mysqlcppconn 库和源代码,很可能有人提供了调试符号和源代码以简化开发。如果您自己编译该库,Visual Studio 会为您生成这些符号。
一旦调试器获得此信息,它可能会在程序运行时提取存储在 RAM 中的变量值。