2

このガイドに従って、VirtualBox の OmniOS VM で Node.js プログラムの CPU プロファイリングに DTrace を使用しようとしています。これは、これらの手順に正確に従ってセットアップしました(ノード 0.10.26 を使用する場合を除く)。

残念ながら、DTrace は人間が判読できる JS 関数名を提供してくれませんが、生の関数アドレス (私が理解している限り) だけです。

CPU     ID                    FUNCTION:NAME
  0  66407                        :tick-30s 


              node`v8::internal::String::ComputeHashField(unibrow::CharacterStream*, int, unsigned int)+0x162
              node`v8::internal::Utf8SymbolKey::Hash() [clone .part.342]+0xb9
              node`v8::internal::HashTable<v8::internal::SymbolTableShape, v8::internal::HashTableKey*>::FindEntry(v8::internal::Isolate*, v8::internal::HashTableKey*)+0x20
              node`v8::internal::SymbolTable::LookupKey(v8::internal::HashTableKey*, v8::internal::Object**)+0x38
              node`v8::internal::SymbolTable::LookupSymbol(v8::internal::Vector<char const>, v8::internal::Object**)+0x4e
              node`v8::internal::Heap::LookupSymbol(v8::internal::Vector<char const>)+0x34
              node`v8::internal::Factory::LookupSymbol(v8::internal::Vector<char const>)+0x34
              node`v8::internal::JSProxy::CallTrap(char const*, v8::internal::Handle<v8::internal::Object>, int, v8::internal::Handle<v8::internal::Object>*)+0x76
              node`v8::internal::JSProxy::GetPropertyWithHandler(v8::internal::Object*, v8::internal::String*)+0x108
              node`v8::internal::Object::GetProperty(v8::internal::Handle<v8::internal::Object>, v8::internal::Handle<v8::internal::Object>, v8::internal::LookupResult*, v8::internal::Handle<v8::internal::String>, PropertyAttributes*)+0x57
              node`v8::internal::LoadIC::Load(v8::internal::InlineCacheState, v8::internal::Handle<v8::internal::Object>, v8::internal::Handle<v8::internal::String>)+0x49d
              node`v8::internal::LoadIC_Miss(v8::internal::Arguments, v8::internal::Isolate*)+0xbd
              0xa730a376
              0x8966eee0
              0x8968bb7c
              0xa7321899
              0xa731308a

上記は、これらのコマンドを実行した結果です。

dtrace -n 'profile-97/pid == 12345 && arg1/{ @[jstack(150, 8000)] = count(); } tick-30s { exit(0); }' > stacks.out
gc++filt < stacks.out > demangled.out

私は DTrace の経験がありませんが、これまでに収集したことから、ノードのustack ヘルパーはこれらのアドレスを読み取り可能な名前に変換する必要があります。この機能は、フラグを使用して Node をビルドするときに有効にする必要がありますが--with-dtrace(私はそうしました)、どうやら機能していないようです。

ほぼまったく同じ質問が実際に以前に尋ね--dest-cpu=x64られましたが、とにかく使用していたので、そこで受け入れられた回答は私の場合には役に立ちませんでした(--dest-cpu=ia32念のため試してみましたが、違いはありませんでした)。

4

1 に答える 1

0

FreeBSD の node.js+DTrace に関するこの優れた投稿のおかげで、それを理解しました。フラグを付けて Node を起動するとDTRACE_DOF_INIT_DEBUG、記事で言及されているような疑わしいメッセージが表示されました。

dtrace DOF: DTrace ioctl failed for DOF at cd5240 in /usr/local/bin/node: Arg list too long
dtrace DOF: DTrace ioctl succeeded for DOF at 1397e70 in /usr/local/bin/node

この記事は FreeBSD に関するものですが、DTrace ソースの関連部分 ( dtrace_dof_copyin)dtrace.cはほとんど同じです ( FreeBSD ソースと OmniOSソースを参照)。したがって、私の場合、Node ustack ヘルパーも DOF/DTrace オブジェクトのサイズ制限を超えていたように見えました.OmniOS では制限が8 MBに設定されていますが、FreeBSD では256 kbです。

仮定を検証するために、v0.10.26 の代わりに Node v0.10.5 でまったく同じ手順を試しました。これは、以前に少なくとも3 人で機能していたように見えるバージョンであり、私の場合もうまくいきませんでした。前述のフラグでノードを開始すると、次のように出力されます。

dtrace DOF: DTrace ioctl succeeded for DOF at cd6c88 in /usr/local/bin/node
dtrace DOF: DTrace ioctl succeeded for DOF at d122c8 in /usr/local/bin/node

また、JS 関数名が期待どおりに DTrace 出力に表示されます。

編集: ノード v0.10.20 は、動作する最新バージョンです。

于 2014-05-25T12:48:35.727 に答える