如何从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)