0

最近我正在尝试修改 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 时,程序因段错误而崩溃。

4

3 回答 3

0

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

于 2013-04-19T18:00:43.457 回答
0

我做了和你一样的事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 <iostream>

`使用命名空间标准;

主函数()

{

    cout<<"hello world"<<endl;

}`

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

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

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

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

于 2013-07-24T14:22:47.413 回答
0

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

于 2013-04-17T06:06:14.030 回答