在 Node.js 程序上使用 DTrace 时没有函数名称
Posted
技术标签:
【中文标题】在 Node.js 程序上使用 DTrace 时没有函数名称【英文标题】:No function names when using DTrace on Node.js program 【发布时间】:2014-05-24 19:45:44 【问题描述】:我正在尝试根据this guide 在 VirtualBox 中的 Omnios VM 上使用 DTrace 对 Node.js 程序进行 CPU 分析,我完全按照 these steps 进行设置(使用节点 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 helper 应该将这些地址转换为可读的名称。在使用--with-dtrace
标志(我做过)构建节点时应该启用此功能,但显然它不适合我。
几乎完全相同的问题实际上是asked before,但那里接受的答案对我来说没有帮助,因为我一直在使用--dest-cpu=x64
(为了确定也尝试了--dest-cpu=ia32
,但确实如此没有任何区别)。
【问题讨论】:
你也可以发布你正在运行的 dtrace 命令吗? @FaridNouriNeshat 当然,将命令添加到问题中。 【参考方案1】:想通了,感谢这篇关于 node.js+DTrace on FreeBSD 的精彩帖子。使用 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.c
中的dtrace_dof_copyin
)几乎相同(参见FreeBSD source 与OmniOS source)。因此,在我的情况下,Node ustack 帮助程序也超过了 DOF/DTrace 对象的大小限制,即使该限制在 OmniOS 中设置为 8 mb,而不是在 FreeBSD 中设置为 256 kb。
为了验证假设,我尝试了使用 Node v0.10.5 而不是 v0.10.26 的完全相同的过程,因为该版本显然至少在 3 people 之前工作过,而且它在我的案例中也起到了作用;带有上述标志的启动节点打印:
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 输出中。
编辑:Node v0.10.20 是它工作的最新版本。
【讨论】:
以上是关于在 Node.js 程序上使用 DTrace 时没有函数名称的主要内容,如果未能解决你的问题,请参考以下文章
与命令行相比,来自 C 的 Dtrace 不会产生相同的分析结果