Valgrind

来自 PostgreSQL 维基
跳转到导航跳转到搜索

Valgrind 和 Postgres

Postgres 直接支持 Valgrind memcheck - 可以将“客户端请求”包含在内存分配器中,从而检测到许多其他在普通版本中无法检测到的内存错误。有关如何在支持 Valgrind memcheck 检测的 Postgres 中构建 Postgres 的完整详细信息,请参见 src/include/pg_config_manual.h。

通常应将 MEMORY_CONTEXT_CHECKING 与 USE_VALGRIND 一起使用;如果没有它,repalloc() 的检测效果较差。

已知错误

如果在 x86_64 硬件上使用 Valgrind 运行时,在自动清理期间观察到核心转储,则这可能是 valgrind 3.8.1 及更早版本中的一个已知错误;请参见 https://bugs.kde.org/show_bug.cgi?id=280114。如果你准备重新编译 Valgrind,请应用其中显示的单行补丁。否则,最简单的解决方法是在使用 Valgrind 时在 postgresql.conf 中设置 autovacuum = off。但是,尚不清楚“修复”是否会隐藏该问题的所有情况。

使用 Valgrind

这里概述了一种在运行回归测试时收集 Valgrind memcheck 检测的有效方法。带有调试符号的二进制文件会生成源文件行号详细信息。

可以使用以下方法启动一个 Memcheck 托管的 postgres

  valgrind --leak-check=no --gen-suppressions=all \
    --suppressions=src/tools/valgrind.supp --time-stamp=yes \
    --error-markers=VALGRINDERROR-BEGIN,VALGRINDERROR-END \
    --log-file=$HOME/pg-valgrind/%p.log --trace-children=yes \
    postgres --log_line_prefix="%m %p " \
    --log_statement=all --shared_buffers=64MB 2>&1 | tee $HOME/pg-valgrind/postmaster.log

. 运行回归测试

  make installcheck

如果检测到错误,并且为了调试目的需要更多详细信息,则可以重新运行一个更小的测试用例,并将 "--track-origins=yes --read-var-info=yes" 标志也添加进去。这会明显降低速度,但会提供更具体的提示。有关更多信息,请参见 Valgrind 文档。

运行回归测试的单个子集,以限制测试持续时间

  make installcheck-tests TESTS="json combocid"

并非回归测试中的所有测试都能够像这样单独运行 - 你可能希望先验证每个测试是否能在不通过 Valgrind 运行 Postgres 的情况下通过。(文件 src/test/regress/parallel_schedule 应该可以让你了解目标测试可能对其他测试的依赖关系)。

附加抑制

你可能需要额外的本地抑制。如果你收到关于 wcstombs 和相关函数的投诉,请考虑添加以下内容

# wcsrtombs uses some clever optimizations internally, which to valgrind
# may look like access to uninitialized data. For example AVX2 instructions
# load data in 256-bit chunks, irrespectedly of wchar length. gconv does
# somethink similar by loading data in 32bit chunks and then shifting the
# data internally. Neither of those actually uses the uninitialized part
# of the buffer, as far as we know.
#
# https://postgresql.ac.cn/message-id/[email protected]

{
   wcsnlen_optimized
   Memcheck:Cond
   fun:__wcsnlen_avx2
   fun:wcsrtombs
   fun:wcstombs
   fun:wchar2char
}

{
   wcsnlen_optimized_addr32
   Memcheck:Addr32
   fun:__wcsnlen_avx2
   fun:wcsrtombs
   fun:wcstombs
   fun:wchar2char
}

{
   gconv_transform_internal
   Memcheck:Cond
   fun:__gconv_transform_internal_utf8
   fun:wcsrtombs
   fun:wcstombs
   fun:wchar2char
}

(在我的系统中,这还不够,因为 wchar2char 似乎是内联的,所以我收到关于 wcstombs 被调用 wchar2char 的函数调用的额外报告。因此你可能需要删除每个建议的抑制的最后一行。)

故障排除

如果你收到类似以下错误

   valgrind: mmap(0x58000000, 2347008) failed in UME with error 22 (Invalid argument).
   valgrind: this can be caused by executables with very large text, data or bss segments.

最有可能的罪魁祸首是尝试在 Valgrind 下运行 Valgrind,可能是通过一个包装器脚本。例如,如果你正在使用一个包装器脚本运行 pg_regress,请确保你使用which -a或更改PATH以找到下一个 postgres,而不是重新执行你的包装器脚本。