system(mkdir)挂在我的应用程序中

时间:2014-09-04 08:01:21

标签: c++ gprof

我们的代码库中有一个方法可以正常工作,但不再有(不对此方法进行任何修改):

void XXX::setCSVFileName()
{
    //get current working directory
    char the_path[1024];
    getcwd(the_path, 1023);
    printf("current dir: %s \n",the_path);
    std::string currentPath(the_path);
    std::string currentPathTmp = currentPath + "/tmp_"+pathSetParam->pathSetTravelTimeTmpTableName;
    std::string cmd = "mkdir -p "+currentPathTmp;
    if (system(cmd.c_str()) == 0) // stops here
    {
        csvFileName = currentPathTmp+"/"+pathSetParam->pathSetTravelTimeTmpTableName + ".csv";
    }
//...
}

我尝试调试它,发现罪魁祸首是if (system(cmd.c_str()) == 0)。我在该行上设置了一个断点并尝试跳过它。它就在那里。 调试器显示的cmd值为:

  

详细信息:{static npos =,_ M_dataplus =   {> = {< __ gnu_cxx :: new_allocator> = {},},_ M_p = 0x306ae9e78" mkdir -p   /家庭/ FM-simmobility /瓦赫德/ simmobility的/ dev /基本/ tmp_xuyan_pathset_exp_dy_traveltime_tmp"}}

我不知道系统正在做什么,但我在top中的应用程序显示大约100%的CPU使用率。 你有过这种情况吗?

重要更新 像往常一样,我开始将我的代码中的更改逐个恢复到问题之前的状态。令人惊讶的是,我发现了问题(但不是解决方案......)。

我将 -pg 添加到我的编译选项中以启用gprof。这就是造成这个问题的原因。

您可能对gropf不排system()mkdir ??

的原因有所了解

感谢

1 个答案:

答案 0 :(得分:2)

您在对其他问题的评论中说,您需要使用gprof来支持您自己的探查器生成的结果。

换句话说,您想编写一个分析器,并将其与gprof进行比较,并且您正在质疑-pg标志是否使system挂起。
我说忘了-pg旗。所做的只是将gprof的调用计数代码放在编译器看到的函数中。

如果我是你,我会找到更好的方法来比较你的探查器。 请记住人们使用分析器的典型原因是 找到加速 , 他们可能认为收集测量结果会帮助他们做到这一点。 它没有。 相反它的作用是说服他们没有找到加速。 (他们会问“new占用5%的时间,这是我的瓶颈,我怎样才能加快速度?”) 这就是gprof为我们做的事情。

这是一个分析器功能表,从差到好到最好:

                              gprof   perf   zoom  pausing
samples program counter      |   X  |   X  |   X  |   X   |
show self % by function      |   X  |   X  |   X  |   X   |
show inclusive % by function |      |   X  |   X  |   X   |
samples stack                |      |   X  |   X  |   X   |
detects extra calls          |      |   X  |   X  |   X   |
show self % by line          |      |   X  |   X  |   X   |
show inclusive % by line     |      |   ?  |   X  |   X   |
handles recursion properly   |      |   ?  |   X  |   X   |
samples on wall-clock time   |      |      |   X  |   X   |
let you examine samples      |      |      |      |   X   |

这些重要的原因是加速器真的很好地隐藏了分析器:

  • 如果未逐行显示,则加速可能是大功能中的任何位置。
  • 如果未显示包含%,则不会看到无关的调用。
  • 如果样本没有在挂钟时间,外部I / O或阻塞没有看到。
  • 如果显示热路径,则加速可以隐藏在其两侧。
  • 如果显示了call-graph,加速可以通过不被本地化为A调用B而隐藏在其中,例如通过“隧道”功能。
  • 如果显示火焰图,可以通过不聚合可以移除的样本来加速加速。

但他们无法避免简单地检查堆栈样本。


P.S。以下是加速器如何隐藏分析器的一些示例 如果探查器显示“热路径”,它只显示堆栈样本的一小部分,因此它只能显示小问题。 但是如果只是比较堆栈样本的相似性而不是相等性,那么可能会出现一个很大的问题:

enter image description here

加速也可以隐藏在调用图中,因为在这种情况下,A1总是调用C2而A2总是调用C1的事实被“隧道函数”B(可能是多层)遮挡。 调用堆栈显示在右侧,人类可以轻松识别模式:

enter image description here

在这种情况下,A总是调用C的事实被A调用任何一个Bi函数(可能是多个层)然后调用C来模糊。 同样,在调用堆栈中很容易识别模式:

enter image description here

另一种方法是,如果堆栈样本显示花费了大量时间来调用具有相同名称但属于不同类的函数(因此是不同的函数),或者具有不同的名称但是由于类似的目的而相关。

在剖析器中,这些合谋将时间分成少量,告诉你没有什么大事。 这是人们“寻找慢功能”的结果,这实际上是一种盲目的形式。