ネイティブ トレース

このガイドではネイティブ トレース API(trace.h)を使用してシステム バッファにトレース イベントを書き込む方法について説明します。 このトレース出力は Systrace ツールを使用して分析できます。 ネイティブ トレース API は Android API レベル 23 以上でサポートされています。

概要

ネイティブ コードにカスタム トレースを作成する技法は、 アプリケーション コードのトレースで説明されている Java プログラミング言語の技法に似ています。 通常、トレースするセクションでネイティブ例外がスローされる場合や早期リターンが使用されている場合でなければ、ネイティブ トレース コードを try/catch ブロックに置く必要はありません。

すべての ATrace_beginSection() 呼び出しに対して、対応する ATrace_endSection() 呼び出しを置く必要があります。そうしないとトレース ファイルが破損することがあります。

トレースが有効でない場合に複雑な文字列または引数を構築するのを避けるには、保護のために ATrace_isEnabled() を追加します。

関数のトレース

ネイティブ トレース API のユースケースの 1 つは、特定のコードブロックにかかる時間を調べるというケースです。 通常、このトレースはパイプライン処理ステージ中に行います(たとえば画像のデコード、フレームの描画、ネットワーク リクエストの待機など)。

あるコードブロックにかかる時間をトレースするには、次の手順に従います。

  1. trace.h ヘッダー ファイルをインクルードします。
    #include <android/trace.h>
    
  2. セクション名を変数として ATrace_beginSection(). に指定します。トレースするコードブロックの最後に、対応する ATrace_endSection(). 呼び出しを置きます。これはトレースするセクションでネイティブ例外がスローされる場合や早期リターンが使用されている場合に特に重要です。
    void myExpensiveFunction() {
      ATrace_beginSection("myExpensiveFunction");
      ... // trace-worthy work here
      ATrace_endSection();
    }
    
  3. (省略可能)コードブロックをトレースするためのコンビニエンス オブジェクト/マクロ構造を作成します。 次の例は、ATRACE_CALL() という名前のそのようなオブジェクト/マクロを実装する方法を示しています。
    #define ATRACE_NAME(name) ScopedTrace ___tracer(name)
    
    // ATRACE_CALL is an ATRACE_NAME that uses the current function name.
    #define ATRACE_CALL() ATRACE_NAME(__FUNCTION__)
    
    class ScopedTrace {
      public:
        inline ScopedTrace(const char *name) {
          ATrace_beginSection(name);
        }
    
        inline ~ScopedTrace() {
          ATrace_endSection();
        }
    };
    
    ATRACE_CALL() オブジェクト/マクロを使用すると、前のステップのコードを次のように簡略化できます。 オブジェクト/マクロをこのように使用すると、トレースするセクションで例外がスローされる場合または早期リターンが使用されている場合に try/catch ブロックを追加することについて心配する必要がなくなります。
    void myExpensiveFunction() {
      ATRACE_CALL();
      ... // trace-worthy work here
    }