2

我正在尝试根据本指南在 VirtualBox 中的 OmniOS VM 上使用 DTrace 对 Node.js 程序进行 CPU 分析,我完全按照这些步骤进行设置(使用节点 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 的经验,但根据我目前收集到的信息,Node 的ustack 助手应该将这些地址转换为可读的名称。使用标志构建节点时应该启用此功能--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_copyinin dtrace.c)的相关部分几乎是相同的(参见FreeBSD 源代码OmniOS 源代码)。因此,在我的情况下,Node ustack 帮助程序也超过了 DOF/DTrace 对象的大小限制,即使在 OmniOS 中该限制设置为8 mb ,而在 FreeBSD 中为256 kb 。

为了验证这个假设,我尝试了使用 Node v0.10.5 而不是 v0.10.26 的完全相同的过程,因为该版本显然之前至少适用于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 回答