Chose me JavaScript-V8 /Chapter1-环境配置
最后更新时间:
写在前面
以下步骤一般情况下只在用户能够正常访问外网时成立。
大致来说,您需要为自己的设备和 git 配置代理,然后才能够顺利完成以下步骤,但出于某些原因,笔者不便在这里过多赘述配置代理的步骤,还望读者见谅
运行环境
step 0
似乎现在去 clone 那个 depot_tools 的仓库里自带了 ninja,有需要这一步的师傅可以在后续步骤中遇到报错时再回来补
1 |
|
step 1
安装依赖并克隆仓库,设置环境变量后拉取 v8 的代码
但考虑到中英文问题和一些网络代理问题,这里不安装字体依赖,有需要的师傅可以试着去掉该参数
1 |
|
step 2
写一个脚本去跑编译,方便以后直接换版本编译:
1 |
|
1 |
|
编译效率一般取决于自己的设备性能
调试环境
将 “v8/tools/gdbinit” 保存到自己惯用的目录下,这里称之为 “path”,然后将路径写到 .gdbinit 下:
1 |
|
做完以后,就能够在源代码中插入如下代码进行调试了:
1 |
|
但这两条代码并非原有的语法,在执行时需添加参数 “–allow-natives-syntax”,
否则会提示 “SyntaxError: Unexpected token ‘%’”
调试样本
就用一个简单的 demo 测试一下调试能够正常进行:
1 |
|
我们暂时不用在意这段代码在做什么,这无关紧要,我们现在只想知道调试环境是否能够正常工作而已,所以读者只需要知道有这么个变量名为 f 的变量即可
在 v8/out/x64_$name.release 目录下可以找到二进制程序 d8,它才是解析执行 js 代码的引擎,通过 gdb 去调试该程序,并将 demo.js 作为参数传给它
1 |
|
可以看到 gdb 正常发生了中断,但由于我们调试的并非 js 脚本,所以自然不可能顺着脚本中断,而是在 d8 的某行机器码处中断了,此时它会打印出数组 f 的数据:
1 |
|
另外,v8提供的gdbinit中额外支持了一条 “job” 命令,它可以用来打印对象的相关信息,这里我们可以用数组 a 进行测试:
1 |
|
其参数是之前 DebugPrint 打印出的地址,可以看见,该指令将对象的各个信息都打印出来了,但我们可以注意到,这个地址的最低位似乎没有四字节对齐,其真实地址是 0x2bdb081d370d-1,但使用 job 时需要将地址加一来区分对象类型和数字类型。如果给出的参数是真实地址,大致会像下面这样:
1 |
|
v8 储存数据的方式有些特别,它会让这些整数都乘以二,也包括数组的长度,因此当 job 认为该地址是一个数字类型时,会将其除以二后的值当作本来的值
可以通过其他查看真正的内存数据:
1 |
|
可以发现,v8 对地址数据进行了压缩储存,由于高 32bit 的地址完全相同,每个地址只会存放其低 32bit 的数据
参考
- https://nobb.site/2021/12/01/0x69/
- https://mem2019.github.io/jekyll/update/2019/07/18/V8-Env-Config.html
插画ID:95370072