Skip to content

Instantly share code, notes, and snippets.

@mmarchini
Last active November 3, 2019 05:32
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 mmarchini/6bb52b691d7c3d4c6ad0a57eb9384e70 to your computer and use it in GitHub Desktop.
Save mmarchini/6bb52b691d7c3d4c6ad0a57eb9384e70 to your computer and use it in GitHub Desktop.
Node.js v10 -> v12 bpftrace programs
// Node v10.15.3
uprobe:/home/mmarchini/.nvm/versions/node/v10.15.3/bin/node:_ZN2v88internal17Builtin_JsonParseEiPPNS0_6ObjectEPNS0_7IsolateE
{
// Load constants
$kPointerSize = (uint32)(1 << (*uaddr("v8dbg_PointerSizeLog2")));
$stringLengthOffset = (uint32)*uaddr("v8dbg_class_String__length__SMI");
$kTag = (uint32)*uaddr("v8dbg_HeapObjectTag");
$kTagMask = (uint32)*uaddr("v8dbg_SmiTagMask");
$kShiftSize = (uint32)*uaddr("v8dbg_SmiShiftSize");
// Object**
$args_objects = arg1;
$index = (uint64)1;
$a = ($args_objects - ($index * $kPointerSize));
$str = (uint64)(*$a);
$b = (uint64)($str - $kTag + $stringLengthOffset);
$strLen = ((int64)*$b) >> ($kShiftSize + $kTagMask);
@ = hist($strLen);
}
// Node.js v12.11.1
uprobe:/home/mmarchini/.nvm/versions/node/v12.11.1/bin/node:_ZN2v88internal17Builtin_JsonParseEiPmPNS0_7IsolateE
{
// Load constants
$kPointerSize = (uint32)(1 << (*uaddr("v8dbg_SystemPointerSizeLog2")));
$stringLengthOffset = (uint32)*uaddr("v8dbg_class_String__length__int32_t");
$kTag = (uint32)*uaddr("v8dbg_HeapObjectTag");
$kTagMask = (uint32)*uaddr("v8dbg_SmiTagMask");
$kShiftSize = (uint32)*uaddr("v8dbg_SmiShiftSize");
// Object**
$args_objects = arg1;
$index = (uint64)1;
$a = ($args_objects - ($index * $kPointerSize));
$str = (uint64)(*$a);
$b = (uint64)($str - $kTag + $stringLengthOffset);
$strLen = ((int32)*$b);
@ = hist($strLen);
}
uprobe:/home/mmarchini/.nvm/versions/node/v10.15.3/bin/node:_ZN2v88internal17Builtin_JsonParseEiPPNS0_6ObjectEPNS0_7IsolateE
{
// Load constants
$kPointerSize = (uint32)(1 << (*uaddr("v8dbg_PointerSizeLog2")));
$stringLengthOffset = (uint32)*uaddr("v8dbg_class_String__length__SMI");
$kTag = (uint32)*uaddr("v8dbg_HeapObjectTag");
$kTagMask = (uint32)*uaddr("v8dbg_SmiTagMask");
$kShiftSize = (uint32)*uaddr("v8dbg_SmiShiftSize");
// 6 means only the string was given, 7 means a receiver was given as well.
// Other numbers mean an invalid signature was used
// int
$args_length = arg0;
// Object**
$args_objects = arg1;
// Isolate*, Probably not needed;
$isolate = arg2;
$index = (uint64)1;
@l[$args_length] = count();
$a = ($args_objects - ($index * $kPointerSize));
$str = (uint64)(*$a);
$kHTagMask = (uint32)*uaddr("v8dbg_HeapObjectTagMask");
$kMapOffset = (uint32)*uaddr("v8dbg_class_HeapObject__map__Map");
$kMapTypeOffset = (uint32)*uaddr("v8dbg_class_Map__instance_type__uint16_t");
$kMapTypeMask = (uint32)0xffff;
$kFirstNonstringType = (uint32)*uaddr("v8dbg_FirstNonstringType");
$map = $str + $kMapOffset;
if ((($str & $kHTagMask) == $kTag) && (($map & $kHTagMask) == $kTag)) {
$typeAddr = $map + $kMapTypeOffset;
$type = *$typeAddr;
$type = $type & $kMapTypeMask;
if ($type < $kFirstNonstringType) {
$b = (uint64)($str - $kTag + $stringLengthOffset);
$strLen = ((int64)*$b) >> ($kShiftSize + $kTagMask);
@ = hist($strLen);
} else {
@miss[0] = count();
printf("%lx %lx %lx %lx\n", $map, $typeAddr, $type, $kFirstNonstringType);
printf("%s\n", ustack);
}
} else {
@miss[1] = count();
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment