使用 GDB 调试内置函数
从 V8 v6.9 版本开始,可以在 GDB(以及可能的其他调试器)中创建断点来调试 CSA / ASM / Torque 内置函数。
(gdb) tb i::Isolate::Init
Temporary breakpoint 1 at 0x7ffff706742b: i::Isolate::Init. (2 locations)
(gdb) r
Thread 1 "d8" hit Temporary breakpoint 1, 0x00007ffff7c55bc0 in Isolate::Init
(gdb) br Builtins_RegExpPrototypeExec
Breakpoint 2 at 0x7ffff7ac8784
(gdb) c
Thread 1 "d8" hit Breakpoint 2, 0x00007ffff7ac8784 in Builtins_RegExpPrototypeExec ()
请注意,对于这种情况,使用临时断点(在 GDB 中的快捷方式为 tb
)比使用常规断点(br
)效果更好,因为您只需要在进程启动时使用它。
内置函数在堆栈跟踪中也是可见的
(gdb) bt
#0 0x00007ffff7ac8784 in Builtins_RegExpPrototypeExec ()
#1 0x00007ffff78f5066 in Builtins_ArgumentsAdaptorTrampoline ()
#2 0x000039751d2825b1 in ?? ()
#3 0x000037ef23a0fa59 in ?? ()
#4 0x0000000000000000 in ?? ()
注意事项
仅适用于嵌入式内置函数。
断点只能设置在内置函数的开头。
在设置内置函数断点之前,需要在
Isolate::Init
中设置初始断点,因为 GDB 会修改二进制文件,并且我们在启动时会验证二进制文件中的内置函数部分的哈希值。否则,V8 会抱怨哈希值不匹配。# Fatal error in ../../src/isolate.cc, line 117 # Check failed: d.Hash() == d.CreateHash() (11095509419988753467 vs. 3539781814546519144).