【问题标题】:Problem with gcc tracker/make/fork/exec/waitgcc 跟踪器/make/fork/exec/wait 的问题
【发布时间】: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 选项获得更详细的报告。比较更详细的报告,如果使用的话。

标签: c gcc g++ posix exec


【解决方案1】:

我不确定这是否能解决您的问题,但您是否考虑过使用 strace 代替您的自定义代码?

strace 执行命令(或附加到正在运行的进程)并列出它进行的所有系统调用。因此,例如,您可以运行以下命令,而不是直接运行 make

strace -f -q -e trace=execve make
  • -f 表示在新进程被分叉时附加到它们
  • -q 表示禁止附加/分离消息
  • -e trace=execve 表示只向execve 报告呼叫

然后,您可以通过 grep 查找有关 /usr/bin/gcc 的消息的输出。

【讨论】:

  • 实际上我在这样做之前尝试了 strace。每个 gcc/g++ 调用都有(IIRC)大约 64 个参数,因此参数列表被终止。不错的尝试,我没有托盘的一件事是对记录的版本进行 strace。这可能会给我一些关于问题的提示。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2012-11-24
  • 2013-10-06
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-01-23
  • 1970-01-01
相关资源
最近更新 更多