【问题标题】:Avoiding source-level "jumping around" in gdb在 gdb 中避免源代码级别的“跳跃”
【发布时间】:2015-04-30 21:24:19
【问题描述】:

使用为使用 g++ 进行调试而构建的 C++ 代码(即选项“-O0 -ggdb”)并使用最新的 gcc (5.1.0) 和 gdb (7.9) 时,gdb 中源代码的显示仍然非常非线性使用“下一步”命令。举个例子,这个函数调用可能会通过一个“next”单步执行:

7757|   SDValue NewRoot = TLI->LowerFormalArguments(
7758|      DAG.getRoot(), F.getCallingConv(), F.isVarArg(), Ins, dl, DAG, InVals);

但是它需要四个,显示的执行行首先是 7757,然后是 7758,然后是 7757,然后是 7758。如果函数调用被压缩为一行,那么只需要一个“下一个”。如果调用被荒谬地夸大了,则需要七个“next”(显示为“#”注释)

       7757|   SDValue
       7758| NewRoot
       7759| =
  #1,6 7760| TLI
       7761| ->
       7762| LowerFormalArguments(
    #5 7763|       DAG.getRoot(),
       7764| F.getCallingConv(),
    #3 7765| F.isVarArg(),
       7766| Ins,
       7767| dl,
       7768| DAG,
       7769| InVals
#2,4,7 7770| );

所以它与“不同行上的每个函数调用都是一个步进点”相关但并不那么简单。这与递归函数中的断点尤其令人困惑,我发现自己检查调用堆栈以查看它是否真的是一个新的调用或只是一个虚假的后退步骤。

由于重排所有 LLVM 源以在一行中包含函数调用并不是一个真正可行的选择,是否有一些 gcc/gdb 选项来控制这种行为?

编辑:现在使用 clang 3.5 和 lldb 3.5 检查:使用 clang 构建时,只会出现三个“下一个”。 gdb 和 lldb 在任何一种情况下都会看到相同的“下一个”行为(即 4 与 gcc,3 与 clang)

【问题讨论】:

    标签: debugging gcc gdb


    【解决方案1】:

    调试器的这种行为是一种“GIGO”情况——也就是说,通常 gdb 只是做调试信息告诉它做的任何事情。也就是说,当出现奇怪的行为时,通常是由于编译器做出的决定。这可能是一个错误,并且可能值得报告错误,但如果出于某种原因它打算以这种方式工作,我也不会感到惊讶。

    您可以通过使用readelfobjdump 检查行表来调查这类问题。

    【讨论】:

    • 来自readelf --debug-dump 很明显,clang 发出比 gcc 对相同代码块发出更多的“X 提前地址和 Y 行”DWARF 操作码,但是对于这两个编译器来说,何时会发生这种情况是不可预测的(例如,自动对象的析构函数是否会在作用域结束时获得单独的“前进”)
    • 但是在 DWARF-land 中徘徊(无知地)似乎很明显,调试器无法忽略这些中间进展,即似乎没有任何特定于语句终止符的东西“下一条语句”命令可以利用。所以编译器会改变高级操作码的粒度,我猜 gcc 和 clang 目前都没有对此的公开控制
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-02-25
    • 2016-02-05
    • 1970-01-01
    • 2022-10-23
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多