【问题标题】:program crash after modification on gcc and gcov修改 gcc 和 gcov 后程序崩溃
【发布时间】:2013-04-08 13:22:53
【问题描述】:

最近我正在尝试修改 GCC 和 gcov 来收集程序的执行顺序。众所周知,gcc 会在基本块之间的 arcs 上检测代码,以计算 arc 的执行次数。所以我在弧上检测了一个函数,该函数将打印出该弧的编号,因此我可以收集程序执行顺序。它适用于 x86 和 x86_64 上的 c 程序,也适用于 x86 的 c++ 程序。但是对于 x86_64 上的 c++ 程序,程序会因段错误而崩溃。编译没有问题。我使用的操作系统是 CentOS 6.4。 gcc 的版本是 3.4.5。有人有什么建议吗?

示例程序:

#include <iostream> using namespace std; int main(){cout<<"hello world"<<endl;}

如果我在 x86_64 模式下编译程序。程序调用cout CALL时Segment Error导致程序崩溃。

【问题讨论】:

    标签: gcc x86-64 gcov


    【解决方案1】:

    好的,通过另一个晚上的调试就可以了。我发现函数 emit_library_call 只会生成 asm 代码来调用我的函数,而不是保护上下文(寄存器)。因此,在发出代码之前或之后的函数调用可能会由于上下文不统一而失败。而 x86_64 asm 使用与 x86 不同的寄存器。所以在 x86 平台上运行良好可能只是偶然。我需要一个可以发出库函数调用并保护上下文的函数 api。也许我应该再写一个 emit_library_call。

    【讨论】:

      【解决方案2】:

      也许您可以尝试动态二进制翻译框架,例如DynamoRIOPin。这些工具提供了比您需要的更多的灵活性,但它们允许您在每个基本块的开始/结束处注入代码。然后你想要做的是保存/恢复标志和寄存器(并可能重新对齐堆栈),并调用一个函数。 DynamoRIO 内置了类似的功能,称为“干净调用”。我认为 Pin 还可以通过潜在的更高级别的接口实现这一点。

      【讨论】:

      • TKS,我会试试的。使用已有的工具总比自己修改GCC好。
      【解决方案3】:

      我做了和你在3.5.0-23-generic #35~precise1-Ubuntu SMP Fri Jan 25 17:13:26 UTC 2013 x86_64 x86_64 x86_64 GNU/Linux一样的事情

      #include &lt;iostream&gt;

      `使用命名空间标准;

      int main()

      {

          cout<<"hello world"<<endl;
      

      }`

      上面的代码用g++ -ftest-coverage -fprofile-arcs hello.cpp -o hello编译 hello.gcno 文件已生成。

      执行后./hello hello.gcda文件生成。

      所以一旦检查你的 gcc 版本。

      我的 gcc 版本是gcc version 4.6.3 (Ubuntu/Linaro 4.6.3-1ubuntu5)

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2013-04-03
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2018-07-09
        相关资源
        最近更新 更多