G++和__attribute__((优化))不改变调试器行为

G++ and __attribute__((optimize)) not changing debugger behavior

本文关键字:调试器 改变 优化 attribute G++      更新时间:2023-10-16

我正在尝试使用__attribute__,以便使用与代码其余部分不同的标志来编译函数。例如:

#include <iostream>
#include <vector>
void MyNormalFunction();
void MyDebugabbleFunction() __attribute__((optimize(0)));
void MyNormalFunction()
{
  std::cout << "Test" << std::endl;
  std::vector<int> a;
  for(unsigned int i = 0; i < 10; ++i)
  {
    a.push_back(i);
  }
}
void MyDebugabbleFunction()
{
  std::cout << "Test" << std::endl;
  std::vector<int> a;
  for(unsigned int i = 0; i < 10; ++i)
  {
    a.push_back(i);
  }
}
int main()
{
  MyNormalFunction();
  MyDebugabbleFunction();
  return 0;
}

我正在使用-g-O2进行构建,但我希望能够理智地调试MyDebugabbleFunction()——所以我在其声明中使用了__attribute__((optimize(0)))。然而,当使用调试器逐步执行这两个函数时,我真的看不出有什么区别。我希望在MyNormalFunction中尝试逐步执行优化代码时会出现"看似不稳定"的行为,但在MyDebuggableFunction中会出现标准的"-g"-仅调试器行为。

是我把__attribute__做错了吗?或者我在这两个函数中使用了糟糕的演示代码(即没有得到"大量优化"的代码)?或者我误解了调试器中的区别?

我使用的是gcc 4.6。


根据GManNickG的建议进行编辑

我用这个代码代替,并建立了-O2-g:

#include <iostream>
#include <vector>
int MyNormalFunction();
int MyDebugabbleFunction() __attribute__((optimize(0)));
int MyNormalFunction()
{
  int val = 0; // breakpoint here - debugger does NOT stop here
  val = 1;
  val = 2;
  return val;
} // debugger stops here instead
int MyDebugabbleFunction()
{
  int val = 0;  // breakpoint here - debugger stops here and steps through the next 3 lines as if it were built with only -g
  val = 1;
  val = 2;
  return val;
}
int main()
{
  int a = MyNormalFunction();
  std::cout << a << std::endl;
  int b = MyDebugabbleFunction();
  std::cout << b << std::endl;
  return 0;
}

尝试这样的测试:

int MyNormalFunction()
{
    int val = 0;
    val = 1;
    val = 2;
    // should optimize to return 2
    return val;
}
int MyDebuggableFunction() __attribute__((optimize(0)));
{
    int val = 0;
    val = 1;
    val = 2;
    // could optimize to return 2, but attribute blocks that
    return val;
}
int main()
{
    // we need to actually output the return values,
    // or main itself could be optimized to nothing
    std::cout << MyNormalFunction() << std::endl;
    std::cout << MyDebuggableFunction() << std::endl;
}

这会让它更容易理解。


请注意,当逐步通过时,您应该从main开始,因为它很可能会减少为:

int main()
{
    std::cout << 2 << std::endl;
    std::cout << MyDebuggableFunction() << std::endl;
}

如果你愿意的话,看看拆解会让这项任务变得容易得多。

修复代码中的错误后,它编译:

g++ -S x.c
_Z16MyNormalFunctionv:
.LFB1255:
    .cfi_startproc
    movl    $2, %eax
    ret
_Z20MyDebuggableFunctionv:
.LFB1256:
    .cfi_startproc
    movl    $0, -4(%rsp)
    movl    $1, -4(%rsp)
    movl    $2, -4(%rsp)
    movl    -4(%rsp), %eax
    ret

正如您所看到的,优化属性运行良好。