我的目标是:

  • 给定Delphi编译的32或64位Windows程序中的挂起线程,以遍历堆栈(可行)
  • 给定堆栈条目,以枚举每种方法中的局部变量及其值。也就是说,至少要找到它们的地址和类型(整数32/64 /有符号/无符号,字符串,浮点数,记录,类...),可以将它们的组合用于查找其值。

  • 第一个很好,这是这个问题的第二个。在较高的级别上,在给定Delphi中的堆栈条目的情况下,如何枚举局部变量?

    从低层次看,这就是我一直在研究的内容:

    RTTI:未列出有关方法的此类信息。我实际上从未想到过这是一个现实的选择,但无论如何都要在此处列出。

    调试信息:加载为调试版本生成的调试信息。
  • map 文件:即使是详细的 map 文件(文本格式的文件!打开其中的文件并查看)也不包含局部变量信息。它基本上是地址和源文件行号的列表。非常适合地址与文件和行的关联,例如天沟中的蓝点;不适用于更详细的信息
  • 远程调试信息(RSM文件)-no known information的内容或格式。
  • TD32 / TDS文件:我当前的研究 Realm 。它们包含许多其他信息中的全局和局部符号。

  • 我在这里遇到的问题是:
  • 没有TD32文件格式的文档(我可以找到。)
  • 我对它们的大部分知识都来自使用它们的Jedi JCL代码(JclTD32.pas),我不确定如何使用该代码,或者不确定其中的结构是否足够广泛以显示本地var。我很确定它将处理全局符号,但是我对局部符号不确定。我定义了各种各样的常量,并且没有格式的文档,要阅读它们的含义,我在猜测。但是,这些常量及其名称必须来自某个地方。
  • Source I can find using TDS info不会加载或处理本地符号。

  • 如果这是正确的方法,那么这个问题将变成“是否存在有关TDS / TD32文件格式的文档,并且是否有任何代码示例加载局部变量?”

    代码示例不是必不可少的,但即使非常少也可能非常有用。

    最佳答案

    检查是否有任何调试符号不是二进制的。
    也可以使用GDB(在Windows上为
    它)。如果找到.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 }
    

    如果没有任何调试文件,则可以尝试获取MinGW或Cygwin,并使用nm(1)(man page)。它将从二进制文件中读取符号名称。它们可能包含一些类型,例如C++类型:
    int abc::def::Ghi::jkl(const std::string, int, const void*)
    

    然后不要忘记添加--demangle选项,否则您将得到类似以下内容的信息:
    __ZN11MRasterFont21getRasterForCharacterEh
    

    代替:
    MRasterFont::getRasterForCharacter(unsigned char)
    

    10-04 20:51
    查看更多