kcachegrind:以下函数没有可用的源代码

Tom*_*ens 5 c++ profiling callgrind kcachegrind

我正在尝试查看带注释的源,$ valgrind --tool=callgrind ./myProgram然后$ kcachegrind使用Ubuntu 12.04(我在$ qcachegrind使用Mac OSX时遇到了同样的问题).

C++脚本myProgram.cpp调用生活在.hpp文件中的函数(通过#include "../include/myHeader.hpp"等).我myProgram.cpp像这样编译:

g++ -g -o myProgram myProgram.o -l<some third party lib>
Run Code Online (Sandbox Code Playgroud)

我不关心查看第三方库的注释源.

我想看到的是 函数in myHeader.hpp和for的注释源myProgram.cpp.

相反,我看到 kcachegrind的Flat Profile窗口,其中列出了所有被调用的函数,包括函数myHeader.hpp- 这很棒.现在,kcachegrind报告函数的位置myHeader.hpp来自myProgram- 这很奇怪.最后,当我从Flat Profile窗口中选择任何函数并请求查看源代码时,我遇到了:

There is no source available for the following function
<name of the selected function>
This is because no debug information is present.
Recompile the source and redo the profile run.
The function is located in the ELF object:
<some location...>
Run Code Online (Sandbox Code Playgroud)

我尝试过的:

  • myHeader.hpp使用kcachegrind的GUI 添加了保存到Annotations列表的目录.

  • 使用-O0编译以删除编译器优化

Tom*_*ens 5

感谢用户nm,我正在回答自己的问题-我在运行简化示例时发现了这一点。问题出在我的编译指令上,我是使用-g而不是编译为目标文件-g

这是一个工作示例,说明如何使kcachegrind显示带注释的源:

main.cpp 住在目录中 someDirectory/example

// main.cpp

#include <iostream>
#include <math.h>
#include "../include/header.hpp"
using namespace std;

int main() {
  double a=1.0; double b=4.0;
  double tol = 1E-10;
  double zero = -99;

  if (sin(a)*sin(b) < 0 && (b-a) >= tol)
  zero = bisect_sine(a,b,tol);

  cout << zero << endl;

  return 0;
}
Run Code Online (Sandbox Code Playgroud)

头文件header.hpp位于someDirectory/include

// header.hpp

#include <math.h>
#include <iostream>
using namespace std;

double bisect_sine(double a, double b, double tol) {

  double c;
  int step = 0; int maxsteps = 100;
  while (step < maxsteps) {
    c = (a+b)/2.0;

    if (sin(c) == 0 || (b-a)/2 < tol)
      return c;
    if (sin(a)*sin(c) >= 0)
      a = c;
    else 
      b = c;

    step+=1;
  }
}
Run Code Online (Sandbox Code Playgroud)

生成文件

# Makefile 
CXX = g++  
main: 
   $(CXX) -g -o main main.cpp
   chmod 700 main
clean:
  rm main
Run Code Online (Sandbox Code Playgroud)

完成所有这些操作后,只需运行make(生成main通过调试编译的可执行文件-g),然后运行即可valgrind --tool=callgrind ./main。这将产生预期的callgrind.out.<PID>文件,可以由kcachegrind读取。然后,源注释将可用于main()main.cpp 的功能以及bisect_sine()头文件中的功能。

因此,这原来是一个编译问题。如果我对编译成可执行文件,目标文件,共享对象,yada yada yada有了更多了解,那么我就不会陷入困境。