Нет имен функций при использовании DTrace в программе Node.js
Я пытаюсь использовать DTrace для профилирования ЦП программы Node.js в соответствии с этим руководством на виртуальной машине OmniOS в VirtualBox, которую я точно настроил, выполнив следующие действия (за исключением использования узла 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
просто чтобы быть уверенным, но это не имело никакого значения).
1 ответ
Разобрался, благодаря этому отличному посту о node.js+DTrace на 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_dof_copyin
в dtrace.c
) практически идентичен (см. источник FreeBSD против источника OmniOS). Следовательно, в моем случае это выглядело так, как будто вспомогательный ustack Node также превышал ограничение размера для объектов DOF /DTrace, даже если это ограничение установлено в 8 МБ в OmniOS, в отличие от 256 КБ в FreeBSD.
Чтобы проверить предположение, я попробовал точно такую же процедуру с 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, как и ожидалось.
РЕДАКТИРОВАТЬ: Node v0.10.20 является самой последней версией, где он работает.