Skip to content

Instantly share code, notes, and snippets.

@wreulicke
Created September 28, 2020 16:10
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save wreulicke/e4ff0ffc947aff2dd41a0beec1b789ee to your computer and use it in GitHub Desktop.
Save wreulicke/e4ff0ffc947aff2dd41a0beec1b789ee to your computer and use it in GitHub Desktop.
pprofのprotoファイルのあるディレクトリのREADMEの和訳

https://github.com/google/pprof/tree/acf8798be1f76c82483eaa0daf3fc93ab3d493b6/proto/README.md の和訳

========================================================

これは profile.proto のフォーマットの説明です。

Overview

Profile.protoはプロファイルデータのデータ表現です。これは集められたりしたデータのタイプや、データを集めるために用いられたサンプリングプロセスに非依存で src/proto/profile.proto によって示された gzipされたプロトコルバッファによって表現されます。

このコンテキストにおけるプロファイルはサンプルのコレクションを言及しており、それぞれ一つがジョブのライフサイクルの特定の点で実行された計測を表現します。 サンプルは一般的にそのサンプルが取られた時のプログラムのコールスタックを示す、Locationのリスト共に計測結果の集合と関連付きます。

pprof のようなツールはそれらのサンプルを解析し、最も呼び出されている場所を特定したり、視覚的なコールグラフやコールツリーを組み立てたりして、 この情報を様々な形で表示します。

General structure of a profile (プロファイルの一般構造)

プロファイルは 次のようなフィールドを含む、Profile メッセージ(※)で表現されます。

※訳者注 メッセージとは message buffer におけるメッセージのことで .proto ファイルにかかれている Profile メッセージ型を示すようです。

  • sample: プロファイルのサンプル。計測された値やロケーションのIDのリストとして関連付けられたコールストックを持ちます。 同一のコールスタックを持つサンプルは要素ごとにそれぞれの値を加算することで、マージされます。

  • location: プログラムにおけるユニークな場所で一般的には単一のインストラクションアドレスにマッピングされます。 サンプルから参照されるためにユニークな非ゼロのIDを持っています。行の形式でソースの情報やバイナリを指し示す mapping id を含んでいます。

  • function: プログラムソースに定義された関数。locationのlinesから参照されるユニークな非ゼロのIDを持ちます。それはその関数の人が可読できる名前やシステムの名前や対応するソースの名前やその他関数の属性などを含んでいます。

  • mapping: プロファイルを収集中のプログラムの一部であるバイナリ。ロケーションから参照されるユニークな非ゼロのIDを持ちます。 プログラムの実行中にバイナリがどのようにマッピングされたかについての詳細を含んでいます。

  • string_table: ここで繰り返されるフィールドへのインデックスとして表現されるプロファイルにおける全ての文字列。最初の文字列は空で、index === 0 は常に空文字を表現しています。

Measurement values (計測値)

計測値は64-bitの整数として表現されます。そのプロファイルは2つのフィールドと共に、ValueTypeメッセージを使って、表現される値それぞれの明示的な説明を含みます。

  • Type: 型のセマンティクスへの人が読める説明。例えば、CPU時間を示す "cpu" 、実時間を示す、"wall" や "time" に加えて アロケートされたバイトのための "memory"

  • Unit: 64 bit の整数によって表現される単位の人が読める名前。例えば、時間の値のための "nanoseconds" だったり "millseconds" や メモリ量を示す "bytes" や "megabytes"です。 もしこれが単にイベントの数を表しているなら、推奨される単位の名前は "count" です。

プロファイルは毎サンプルで複数の計測結果を表現できますが、全てのサンプルは同じ数と同じ型を持っていなければなりません。 実際の値は Sample.value フィールドに保存されており、それぞれの対応する sample_type フィールドによって説明されます。(※)

※訳者注 Sample.valueの値は repeated な形で表現されており、Profile.sample_typeのindexに対応する値が Sample.valueに入っており、同数の値が含まれていなければなりません。

いくつかのプロファイルはデータのコレクションの粒度を示す統一の区切りを持っています。 例えば、CPUプロファイルの場合、100msの区切りを持っていたり、メモリアロケーションのプロファイルでは512kbの区切りを持っていたりします。 プロファイルはそのような値を Profile.period や Profile.period_type フィールドでオプション的に示すことが出来ます。 このプロファイルの区切りは人間が使うためのもので、プロファイルデータの解釈には影響を与えません。

慣例的に、プロファイルにおける最初の値は、単位 "count" を持った コールスタックで得られた sample 数です。 なぜならプロファイルはオプショナルな区間を超えるサンプリングプロセスを記述していないからため、全ての計測のサンプリングされていない値を含める必要があります。 例えば、CPU Profileであれば、 value[0] にはサンプル数で、value[1] にはミリ秒での時間を持つでしょう。

※訳者注 意味が取れなくてよく分からない。

Locations, functions and mappings

それぞれのサンプルはサンプルが集められたそれぞれの場所のIDをボトムアップの順番で記録しています。 それぞれの location は 明示的でユニークな非ゼロの整数のIDを持っており、プロファイルの場所に依存せず、対応するソースを見分けるための追加の情報を保持しています。

プロファイルのソースはスタックにおける呼び出しを示すためにその locationを必要とする調整を実行することを期待されています。 例えば、もしプロファイルのソースがプログラムのスタックをさかのぼって、コールスタックを抽出するなら、その呼び出しが戻る命令の代わりに、実際の呼び出し命令を指し示す命令アドレスを調整する必要があります。

ソースはいつもこれら2つのカテゴリに分類されるプロファイルを生成します。

  • :Unsynbolized profiles: これには命令のアドレスだけを含み、分離されたツールによってシンボル化されるためのものです。正しいマッピングを示すそれぞれの location は重要で シンボル化のために必要なその情報を提供します。これらは、C++やGoなどのコンパイル言語のprofileのために使われます。

  • :Symbolized profiles: これにはプロファイルに利用可能な全てのシンボル情報を含みます。シンボル化された場所では、マッピングや命令アドレスはオプショナルです。 これらはJavaやPythonのようなインタプリタ言語やJIT言語のプロファイルのために使われます。プロファイルフォーマットはシンボル化された locationやシンボル化されていないものが混在するプロファイルの生成を許します

シンボルの情報は、Locationのメッセージの繰り返しの行のフィールドで表現されます。もし複数のプログラムソースを反映するなら、ロケーションは複数の行を持っています。 例えば、inline化されたコールスタックを表現している場合。行は非ゼロのユニークなIDや関数によってリストされたソースファイル内のソース行番号によって関数を参照しています。 関数は関数のためのソース属性を含んでおり、名前やソースファイルなどを含んでいます。 関数は名前のユーザやシステムの形式両方を含んでおり、例えば、C++デマングル名、C++マングル名を含んでいます。同じ文字列が一つしか無いプロファイルでは両方を同じ文字列に設定する必要があります。

マッピングもまた、ユニークの非ゼロIDによって locationから参照され、マッピング内のアドレスをシンボル化するために必要な全ての情報を含んでいます。 Linuxの/proc/self/maps ファイルに似たような情報を含んでいます。マッピングに関連づいた場所はマッピングのstarとlimitの間にあるアドレスを持っている必要があります。 そして、もし可能ならば、使われているバイナリのバージョンをユニークに特定するためのビルドIDを含んでいるべきです。

Labels

サンプルはオプショナルで同一の位置でサンプルを分けるためのアノテーションである、ラベルを持っています。 例えば、アロケーションのサイズを示すmallocのプロファイルで使われ、同じコールスタックで2MBと4MBのサイズを持つ2つのサンプルは 2つのアロケーションと6MBのサイズをもつ1つのサンプルにマージされません。

ラベルは文字列ベースや数字です。それらはラベルを特定するキーと、文字列や数字のいずれかを含むラベルメッセージで表現されています。 数字のラベルは、プロファイルで計測単位を指定できます。単位が指定されていないかつ、キーが"request" もしくは "alignmnet" なら 単位は "bytes" だと見なされます。その他の場合、単位が指定されていない時はそのキーは数値の計測単位として使われます。 同じキーを持つ全てのタグは同じ単位を持っているべきです。

Keep and drop expressions

一部のプロファイルソースには、興味のない、もしくは無関係な場所の知識を持っている場合があります。 しかしながら、もしそれらの場所を特定するためにシンボル化が必要なのであれば、プロファイルソースはプロファイルが生成されるときに削除できない場合があります。 プロファイルフォーマットでは、正規表現を通して、名前によってフレームを特定するためのメカニズムを提供します。

それら全体で関数の名前と式はマッチしなければなりません。Profile.drop_framにマッチするフレームは、下にあるどんなフレームも合わせて、プロファイルからドロップされます。 Profile.keep_frames にマッチするフレームは維持されます、たとえ drop_framesにマッチしたとしても。

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment