内存消毒器

此页面是从 MDN 导入的,内容可能已过时

什么是内存消毒器?

内存消毒器 (MSan) 是一种快速检测器,用于检测 C/C++ 程序中的未初始化内存。它使用编译时插桩来确保运行时所有内存访问都只使用已初始化的内存。与大多数其他消毒器不同,如果未插桩所有库,MSan 容易导致误报。发生这种情况是因为 MSan 无法观察未插桩库中的内存初始化。有关 MSan 的更多信息,请参阅内存消毒器维基

公开版本

注意:目前尚无公开版本可用。

手动构建

构建先决条件

注意:MemorySanitizer 需要64 位 Linux才能工作。不支持其他平台/操作系统。

LLVM/Clang

MSan 插桩作为 LLVM 传递实现,并集成到 Clang 中。由于 MSan 是较新的消毒器之一,我们建议使用较新的 Clang 版本,例如 Clang 3.7 及更高版本。

您可以在LLVM 发行版页面上找到 LLVM/Clang 的预编译二进制文件。

构建 Firefox

警告

警告:使用 MemorySanitizer 运行 Firefox 需要所有外部依赖项也使用 MemorySanitizer 构建。据我们所知,这从未尝试过,因此此处提供的构建配置未经测试,并且如果没有适当插桩的用户空间,它会导致误报。

获取源代码

如果您还没有源代码存储库克隆,则需要获取 Mozilla-central 的克隆

调整构建配置

在您的 Mozilla-central 目录中创建具有以下内容的构建配置文件.mozconfig

mk_add_options MOZ_OBJDIR=@TOPSRCDIR@/objdir-ff-msan

# Enable LLVM specific code and build workarounds
ac_add_options --enable-memory-sanitizer
# If clang is already in your $PATH, then these can simply be:
#   export CC=clang
#   export CXX=clang++
export CC="/path/to/clang"
export CXX="/path/to/clang++"

# llvm-symbolizer displays much more complete backtraces when data races are detected.
# If it's not already in your $PATH, then uncomment this next line:
#export LLVM_SYMBOLIZER="/path/to/llvm-symbolizer"

# Add MSan to our compiler flags
export CFLAGS="-fsanitize=memory"
export CXXFLAGS="-fsanitize=memory"

# Additionally, we need the MSan flag during linking. Normally, our C/CXXFLAGS would
# be used during linking as well but there is at least one place in our build where
# our CFLAGS are not added during linking.
# Note: The use of this flag causes Clang to automatically link the MSan runtime :)
export LDFLAGS="-fsanitize=memory"

# These three are required by MSan
ac_add_options --disable-jemalloc
ac_add_options --disable-crashreporter
ac_add_options --disable-elf-hack

# Keep symbols to symbolize MSan traces
export MOZ_DEBUG_SYMBOLS=1
ac_add_options --enable-debug-symbols
ac_add_options --disable-install-strip

# Settings for an opt build
ac_add_options --enable-optimize="-O2 -gline-tables-only"
ac_add_options --disable-debug

启动构建过程

现在您可以使用常规的make -f client.mk命令启动构建过程。

启动 Firefox

构建完成后,您可以像往常一样从objdir启动 Firefox。

构建 JavaScript shell

注意:与 Firefox 本身不同,JavaScript shell **不需要**插桩的用户空间。对 zlib 等外部库的调用在引擎内部使用特殊注释处理。

警告

警告:JavaScript 引擎内部使用的某些技术与 MSan 不兼容,必须在运行时禁用以防止误报。这包括 JIT 和 asm.js。因此,请始终确保使用“--no-ion --no-baseline --no-asmjs --no-native-regexp”运行。

如果您只想构建 JavaScript shell 而不是执行完整的 Firefox 构建,下面的构建脚本可能会帮助您做到这一点。在使用它之前,您当然必须调整LLVM_ROOT 的路径名称以匹配您的设置。调整好所有内容后,在js/src/子目录中执行此脚本,并将目录名称作为第一个参数传递。然后将在具有该名称的新子目录中创建构建。

#! /bin/sh

if [ -z $1 ] ; then
    echo "usage: $0 <dirname>"
elif [ -d $1 ] ; then
    echo "directory $1 already exists"
else
    autoconf2.13
    mkdir $1
    cd $1
    LLVM_ROOT="/path/to/llvm"
    CC="$LLVM_ROOT/build/bin/clang" \
    CXX="$LLVM_ROOT/build/bin/clang++" \
    CFLAGS="-fsanitize=memory" \
    CXXFLAGS="-fsanitize=memory" \
    LDFLAGS="-fsanitize=memory" \
            ../configure --enable-debug --enable-optimize --enable-memory-sanitizer --disable-jemalloc --enable-posix-nspr-emulation
    make -j 8
fi

使用 LLVM Symbolizer 加速/改善跟踪

默认情况下,MSan 跟踪不会符号化。

LLVM 附带符号化二进制文件llvm-symbolize,如果在PATH上找到程序,MSan 将立即使用它来输出符号化跟踪。如果您的llvm-symbolize位于PATH之外,则可以设置MSAN_SYMBOLIZER_PATH环境变量以指向您的符号化二进制文件。