c++ - G++ 和 __attribute__((optimize)) 不改变调试器行为

标签 c++ gcc

我正在尝试使用 __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;
}

如果您愿意,查看反汇编会使这项任务变得容易得多。

关于c++ - G++ 和 __attribute__((optimize)) 不改变调试器行为,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12114019/

相关文章:

c++ - 我怎样才能让这个 += 运算符工作?

c++ - gcc 内联 asm 跳转到带有交叉抛出异常的标签

c++ - C++ 模板参数中的三元表达式

perl - 配置 OpenDDS

c++ - 无法通过 "variables"将参数传递给基于可变参数的模板

c++ - ICU4C 相当于 LocaleMatcher

c# - 我将如何使用 C++/CLI dll 将 native 代码与 C# 中的多个依赖库一起包装?

c++ - std::forward_list::remove_if 谓词的要求

c - 将二进制文件移动到目录之外时出现段错误

c - gcc中使用的C版本是多少