运行根危害分析

js/src/devtools/rootAnalysis 目录包含用于在 JS 源代码目录上运行 Brian Hackett 的静态 GC 根和线程堆写入安全分析的脚本。

要在 SpiderMonkey 上运行分析

  1. 取消设置您的 $MOZCONFIG

     unset MOZCONFIG
    
  2. 安装先决条件。

     mach hazards bootstrap
    
  3. 构建 shell 以运行分析。

     mach hazards build-shell
    
  4. 编译所有代码以收集信息。

     mach hazards gather --project=js
    
  5. 分析收集到的信息。

     mach hazards analyze --project=js
    

输出到 $srctop/haz-js/hazards.txt。这将仅在 js/src 树上运行分析;如果您希望分析整个浏览器,请使用

    --project=browser

(或将其保留;--project=browser 是默认值)

  1. (可选) 查看结果危害。

     mach hazards view --project=js
    

在运行分析一次后,您可以重用生成的 *.xdb 数据库文件,使用修改后的分析脚本,通过运行 mach hazards analyze 上面的命令,或通过添加 mach hazards analyze <step> 来运行分析步骤的子集;mach hazards analyze -- --list 查看步骤名称。

此外,您可以传递 -- -v 以获取用于运行各个阶段的确切命令行,以便剪切和粘贴,这有助于在调试器下运行。

增量分析

完成分析后,您可以进行代码更改并使用 mach hazards gather 重新构建。这将添加到现有的 *.xdb 文件中,这通常可以正常工作,但有时旧的编译会留下一些信息,这些信息会妨碍。一个典型的例子是 lambda 函数:您可能会收到由于不再存在的 lambda 函数而报告的危害,但较新的编译不会替换它们。虽然可以通过一定量的努力来解决这个问题,但您正在对抗一个基本问题,即分析依赖于某些事情发生(例如对 GC 的调用),而增量编译只会添加和替换现有信息。除非它用具有匹配名称的内容(例如 lambda 函数在其名称中具有在编译之间变化的自动生成的数字)替换它,否则它不会删除信息。

简而言之:为了提高开发速度,可以随意使用增量分析,但不要相信它们。如果危害分析开始声称不可能的事情正在发生,请尝试 mach hazards clobber 并进行完全重建。

这里正在发生的事情概述

那么这到底做了什么?

  1. 它从 Mozilla 服务器下载 GCC 编译器和插件(“sixgill”)。

  2. 它运行 run_complete,一个使用下载的 GCC 构建目标代码库的脚本,生成一些包含完整编译控制流图以及类型信息等的数据库文件。

  3. 然后它运行 analyze.py,一个 Python 脚本,它运行所有实际执行分析的脚本 - 棘手的部分。(这些脚本是用 JS 编写的。)

运行它的最简单方法是不尝试在本地进行检测编译。相反,从 try 服务器推送中获取相关文件并在本地分析它们。

下载的中间文件的本地分析

另一种有用的方法是让持续集成系统完成生成中间文件的工作并在本地分析它们。如果您正在处理分析本身,这特别有用。

  • 使用“–upload-xdbs”附加到 try: … 行进行 try 推送。

      mach try fuzzy -q "'haz" --upload-xdbs
    
  • 创建一个空目录以运行分析。

  • 当 try 作业完成后,将生成的 src_body.xdb.bz2src_comp.xdb.bz2file_source.xdb.bz2 文件下载到您的目录中。

  • 获取要使用的编译器和 sixgill 插件

      mach hazards bootstrap
    

如果您使用的是 osx,则这些将不可用。相反,手动构建 sixgill(这些说明有点过时了)

    hg clone https://hg.mozilla.org/users/sfink_mozilla.com/sixgill
    cd sixgill
    CC=$HOME/.mozbuild/hazard-tools/gcc/bin/gcc ./release.sh --build # This will fail horribly.
    make bin/xdb.so CXX=clang++
  • 使用 ctypes 构建优化的 JS shell。请注意,这不需要以任何方式与您正在分析的源代码匹配;事实上,一旦构建了它,您几乎不需要更新它。(尽管我保留将来使用 Spidermonkey 中实现的任何新 JS 功能的权利……)

      mach hazards build-shell
    

shell 将默认放置在 $topsrcdir/obj-haz-shell 中。

  • 创建一个包含以下内容的 defaults.py 文件,并填写您自己的路径

      js = "<objdir>/dist/bin/js"
      sixgill_bin = "<sixgill-dir>/bin"
    
  • 对于根分析,运行

      python <srcdir>/js/src/devtools/rootAnalysis/analyze.py gcTypes
    
  • 对于堆写入分析,运行

      python <srcdir>/js/src/devtools/rootAnalysis/analyze.py heapwrites
    

此外,您可能希望使用 -v(即 –verbose)运行以查看执行的确切命令,以便在需要时剪切和粘贴。(当我处理分析时,我使用它们在 JS 调试器下运行。)