【问题标题】:Constant symbols in a binary二进制中的常量符号
【发布时间】:2016-02-11 17:58:22
【问题描述】:

如果我的程序做了一个

#ifdef USE_REL_DEF
#  define MAX_NUM_REL 10
#else
#  define MAX_NUM_REL 5
#endif

是否可以检查生成的二进制文件以了解 MAX_NUM_REL 的最终值?我没有在程序中放置日志/打印的选项,但我确实有生成的二进制文件。

我尝试使用 nm 和 objdump,但没有找到符号的值。

【问题讨论】:

  • #define 本身并不直接让跟踪进入二进制文件。定义被它们各自的值(10 或 5)替换,它们在编译时出现在代码中。
  • 这些符号甚至在编译开始之前就在预处理阶段消失了。
  • 可能会在调试符号中找到它,具体取决于您的环境和构建设置。

标签: c assembly macros gnu


【解决方案1】:

不可能以这种方式检查MAX_NUM_REL 的最终值:这不是一个变量,而是一个占位符,它将被您在代码实际编译之前定义的值替换(在 预处理阶段)。

你唯一能控制的就是使用它的后果:

例如,您是否应该在 C 代码中的某处包含以下行:

 int myIntegerVariable = MAX_NUM_REL;
  • 您可以通过在代码上运行预处理器(只是预处理器,而不是编译器)来查看实际使用的值:这将生成另一个 C 文件,其中 MAX_NUM_REL 替换为其实际值(@ 987654324@)。您必须参考您正在使用的编译器的文档,以了解如何在文件上运行预处理器。

  • 或者您可以反汇编已编译的代码以确定在该位置使用的是 10 还是 5。不过这并不容易。

    • 符号myIntegerVariable 不会在二进制代码中出现。这是一个符号,只有在您使用调试选项编译程序时才能跟踪该符号,该选项在二进制文件中保持符号表可用。

    • 即使使用符号表,这也不是您一眼就能发现的,这需要一些工作。

  • 最后,即使你不能产生日志,你也可以正常地对你的代码进行分步调试。这允许您检查代码中设置为MAX_NUM_REL 的变量或函数参数。

【讨论】:

    【解决方案2】:

    是否可以检查生成的二进制文件以知道 MAX_NUM_REL 的最终值?

    不,至少不是直接的。 MAX_NUM_REL 是一个,而不是一个变量。预处理器将宏名称替换为宏定义范围内作为预处理标记出现的任何地方的扩展名(无论哪个)。如果它出现在不是完整预处理标记的任何地方,则不能作为对象的名称。

    如果二进制文件中的某处碰巧有一个文件范围变量,该变量使用MAX_NUM_REL 的值进行初始化,例如...

    int num_rel = MAX_NUM_REL;
    

    ...然后您可以在二进制文件中找到该符号的初始值,并从中推断出MAX_NUM_REL 的选定值。

    也可以使用预处理器来制定关于使用哪个定义的有根据的猜测。假设包含该定义的文件是mysource.c。如果您能够使用用于实际编译的所有相同选项调用预处理器,则预处理此源...

    include "mysource.c"
    
    int the_value = MAX_NUM_REL;
    

    ... 使用这些相同的选项* 将(可能)生成一堆以任一结尾的预处理 C 源代码

    int the_value = 5;
    

    int the_value = 10;
    

    请注意,如果 MAX_NUM_REL 在源代码中的某处重新定义,这可能不会为您提供正确的答案,但您可以很容易地检查出来。

    如何仅运行预处理器取决于您的系统。如果您使用的是gcc,那么您可以使用gcc -E

    *您可能需要一个额外的选项来确保 mysource.c 在包含搜索路径中。

    【讨论】:

      【解决方案3】:

      这实际上不是一个符号。如果您尝试搜索MAX_NUM_REL,那不好,因为这是#define,这意味着它甚至不是一个变量,因为所有工作都由预处理器完成(所以这个确切的名称不会进入二进制文件文件)。

      要找到这个值,你需要有源代码,然后查看这个定义的使用位置,然后再搜索这个值所分配给的变量的名称。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2011-06-11
        • 1970-01-01
        • 2020-12-23
        • 2010-10-16
        • 2010-11-17
        • 2012-10-07
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多