The code in this repo shows an example of attaching a custom handler (uprobe) to the Math.sqrt() function in V8. It can be used to precisely measure the hardware perf events for some browser workload, or repurposed for low-level instrumentation in general.
To build and run the code:
-
$ make uprobe
-
$ sudo ./uprobe
-
Then (the order matters), run chrome with
/path/to/debugbuild/chrome --no-sandbox(we need symbol info so debug build; our instrumentation violates the seccomp sandbox)
Expected behavior:
If you call Math.sqrt from JavaScript, you are expected to see the uprobe program's handler handle_event getting fired
-
Q: I want to use my special chromium build. What is the specific
gnbuild flag required for the symbol info so I can modify the build configuration myself?A:
v8_symbol_level = 2should work. Note you can also modifysymbol_levelwhich is a superset that impliesv8_symbol_levelif the latter is not specified. -
Q: I see a V8 fatal error when I start chromium, what is this error and how can I fix it?
A: It's probably a debug-only check in V8 that will terminate the process when V8 detects instrumentation. You can safely disable it by commenting out the corresponding
#ifdef DEBUGblock inv8/src/execution/isolate.ccand recompile chromium. Or, note that the build flag for a target is stored in{out_dir}/obj/{target}.ninjaso you may change thedefinesthere and build again. -
Q: What should I modify if I want to attach to other code points rather than
Math.sqrt()?A: If you want to change the attached code point, change
SEC("uprobe//home/utsec/chromium/src/out/Debug/libv8.so:Builtins_MathSqrt")in the BPF programuprobe.bpf.c.
The base infra is from libbpf-bootstrap, and this blog can help a lot if you want to learn more about the libbpf details.