【发布时间】:2010-02-25 06:52:55
【问题描述】:
这是一个最独特的问题,具有许多跨学科的分支。
重点介绍这段代码(文件名mainpp.c):
#include <stdio.h>
#include <stdlib.h>
int main(int argc, char *argv[])
{
int status;
if (fork())
{
FILE *f=fopen("/tmp/gcc-trace","a");
fprintf(f,"----------------------------------------------------------------\n");
int i;
for(i=0;i<argc;i++)
{
fprintf(f,"%s:",argv[i]);
}
wait(&status);
fprintf(f,"\nstatus=%d",status);
fprintf(f,"\n");
fclose(f);
}
else
{
execv("g++.old",argv);
}
sleep(10);
return status;
}
这与 bash 脚本一起使用:
#!/bin/sh
gcc -g main.c -o gcc
gcc -g mainpp.c -o g++
mv /usr/bin/gcc /usr/bin/gcc.old
mv /usr/bin/g++ /usr/bin/g++.old
cp ./gcc /usr/bin/gcc
cp ./g++ /usr/bin/g++
希望这段代码(以及相应的 gcc 的 main.c)的目的很明确。它替换 g++ 并记录对 g++ 的调用以及所有命令行参数,然后继续调用 g++ 编译器(现在称为 g++.old)。
计划使用它来记录所有对 g++/gcc 的调用。 (由于 make -n 不跟踪递归 make,这是一种“在野外”捕获调用的方法。)
我在几个程序上试过这个,效果很好。 (包括编译程序本身。)然后我在我感兴趣的项目 libapt-pkg-dev(Ubuntu 存储库)上进行了尝试。
构建似乎进展顺利,但是当我检查一些可执行文件时丢失了。计数项目目录中的文件,我发现未记录的版本产生 1373,而记录的版本产生 1294。列出这些文件,我发现所有丢失的文件都是可执行文件、共享库或目标文件。
从已记录的 make 和未记录的 make 中捕获标准会产生相同的输出。 exec调用的所有进程的记录返回值为0。
我在代码中的不同位置放置了睡眠。它们似乎没有任何区别。 (具有跟踪版本的代码似乎每个文件的编译速度要快得多。我怀疑 exec 可能导致程序在保持 gcc 运行时终止。我认为这可能会导致失败,因为某些目标文件可能在其他人需要它们时没有完成.)
我只需要运行一个诊断程序来查看我是否可以诊断问题,然后我就没有想法了。有什么建议吗?
【问题讨论】:
-
我不确定这是个问题,但`execv("g++.old",argv);`必须有第一个参数
usr/bin/g++.old -
拍了拍他的额头,最初我通过了argv+1,因为我认为它会被附加。我没有意识到它会被改变。叹。但是,我不这么认为。很明显,g++ 成功了很多次,我认为这只会导致每次都彻底失败。
-
您可以使用 gcc 的
-v选项获得更详细的报告。比较更详细的报告,如果使用的话。