如何从Delphi程序或编译器生成的debugging信息中提取本地variables信息(地址和types)?
我的目标是:
- 给定一个Delphi编译的32位或64位Windows程序中挂起的线程,走栈(可行)
- 给定堆栈条目,枚举每个方法中的局部variables及其值。 也就是说,至less可以find他们的地址和types(整数32/64 /有符号/无符号,string,浮点,logging,类…)的组合可以用来find它们的值。
第一个很好,这是第二个问题。 在很高的层次上, 如何在Delphi中给出一个堆栈条目来枚举局部variables?
在低层次,这是我一直在调查:
RTTI:不列出这种方法的信息。 这不是我曾经认为是一个现实的select,但无论如何这里列出。
debugging信息:加载为debugging版本生成的debugging信息。
- 地图文件:即使是一个详细的地图文件(一个文本格式的文件!打开一个,看看)不包含本地variables信息。 这基本上是地址和源文件行号的列表。 非常适合地址到文件和行相关,例如排水沟中的蓝点; 不是很好的更详细的信息
- 远程debugging信息(RSM文件) – 没有关于其内容或格式的已知信息 。
- TD32 / TDS文件:我目前的研究。 它们包含许多其他信息中的全球和地方符号。
我遇到的问题是:
- 没有关于TD32文件格式的文档(我可以find)。
- 我对他们的大部分知识来自使用它们的Jedi JCL代码(JclTD32.pas),我不知道如何使用该代码,或者结构是否足够显示本地variables。 我很确定它会处理全球符号,但我对本地的情况很不确定。 有很多定义的常量,没有格式的文档,阅读它们的意思,我只是猜测。 然而,这些常数和他们的名字必须来自某个地方。
- 我可以find使用TDS信息源不加载或处理本地符号。
如果这是正确的方法,那么这个问题就变成了:“TDS / TD32文件格式是否有文档,有没有加载局部variables的代码示例?
代码示例不是必需的,但可能非常有用,即使它非常小。
检查是否有任何debugging符号不是二进制的。 也可以使用GDB(在Windows上是它的一个端口)。 如果你find一个.dbg或.dSYM文件,那就太好了。 它们包含源代码,例如。
gdb> list foo 56 void foo() 57 { 58 bar(); 59 sighandler_t fnc = signal(SIGHUP, SIG_IGN); 60 raise(SIGHUP); 61 signal(SIGHUP, fnc); 62 baz(fnc); 63 }
如果您没有任何debugging文件,您可以尝试使用MinGW或Cygwin,并使用nm(1)( 手册页 )。 它将从二进制读取符号名称。 它们可能包含一些types,如C ++:
int abc::def::Ghi::jkl(const std::string, int, const void*)
不要忘了添加--demangle
选项,否则你会得到像这样的东西:
__ZN11MRasterFont21getRasterForCharacterEh
代替:
MRasterFont::getRasterForCharacter(unsigned char)