6

Ubuntu 12.04 を使用して注釈付きのソースを表示しようとしています (Mac OSX を使用しても同じ問題が発生し$ valgrind --tool=callgrind ./myProgramます) 。$ kcachegrind$ qcachegrind

C++ スクリプトは、 ( などを介して) ファイルmyProgram.cpp内に存在する関数を呼び出します。私は次のようにコンパイルします:.hpp#include "../include/myHeader.hpp"myProgram.cpp

g++ -g -o myProgram myProgram.o -l<some third party lib>

そのサードパーティのライブラリの注釈付きソースを表示することは気にしません。

私が見たいのは 、関数 inmyHeader.hppと forの注釈付きソースですmyProgram.cpp

代わりに、呼び出されるすべての関数のリストを含む kcachegrind の Flat Profile ウィンドウが表示さmyHeader.hppます。現在、kcachegrind は関数の場所を frommyHeader.hppとしてレポートしますmyProgram-これは奇妙です。最後に、フラット プロファイル ウィンドウから任意の関数を選択し、ソース コードを表示するように要求すると、次のメッセージが表示されます。

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...>

私が試したこと:

  • myHeader.hppkcachegrind の GUI を使用して、ディレクトリ保持を Annotations リストに追加しました。

  • -O0 を使用してコンパイルし、コンパイラの最適化を削除します

4

1 に答える 1

6

ユーザー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;
}

ヘッダファイルheader.hppsomeDirectory/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;
  }
}

メイクファイル

# Makefile 
CXX = g++  
main: 
   $(CXX) -g -o main main.cpp
   chmod 700 main
clean:
  rm main

このすべての後、実行するだけでmake( debugmainでコンパイルされた実行可能ファイルが生成されます-g)、その後にvalgrind --tool=callgrind ./main. これにより、期待されるcallgrind.out.<PID>ファイルが生成され、kcachegrind で読み取ることができます。ソース アノテーションは、ヘッダー ファイルから main()だけでなく、main.cpp の関数にも使用できます。bisect_sine()

したがって、これはコンパイルの問題であることが判明しました。実行可能ファイル、オブジェクト ファイル、共有オブジェクト、やだやだやだへのコンパイルについてもっと理解していれば、この混乱には巻き込まれなかったでしょう。

于 2014-04-13T22:05:44.933 に答える