
如何用 hang analyzer 为疑似挂起的 MongoDB 测试进程收集 core dump 与堆栈信息【免费下载链接】mongoThe MongoDB Database项目地址: https://gitcode.com/GitHub_Trending/mo/mongo在 MongoDB 源码树里用 resmoke 跑 jstests 时测试经常会卡在某个阶段没有响应mongod 或 mongos 进程活着但不推进测试整体超时。此时空等没有意义需要用仓库自带的 hang analyzer 对疑似挂起的进程做两次动作——给 resmoke 发信号让 Python 线程打印堆栈再对非 Python 子进程收集 core dump 和附加诊断信息。完成本文操作后你会在当前工作目录得到 core dump 文件和debugger_process_pid.log形式的调试器输出作为定位挂起原因的依据。该工具的完整文档见 docs/testing/hang_analyzer.md 和 buildscripts/resmokelib/hang_analyzer/README.md。注意附加诊断数据C 堆栈、锁信息、会话信息等的完整列表只在 Linux 上准确其他平台只执行其中一部分操作。准备条件hang analyzer 是 resmoke 的一个子命令入口在 buildscripts/resmoke.py。按 docs/testing/README.md 的说明先准备好 Python 环境和可测试的二进制python3 -m venv python3-venv source python3-venv/bin/activate buildscripts/uv_sync.sh bazel build install-dist-test其中bazel build install-dist-test产出 resmoke 要运行和诊断的二进制。文档同时提示命令中的python可能需要替换为你实际使用的解释器名可能是python、python3Windows 上则是Python、Python3。选择分析对象进程名匹配与 PID 指定hang analyzer 只处理它认为interesting的进程匹配规则在 hang_analyzer.py 和 plugin.py 中默认进程名列表为mongo、mongod、mongos、_test、dbtest源码注释说明故意排除了python、java避免 hang analyzer 被重复触发以python或live-record开头的进程走特殊路径向它们发 SIGUSR1让 resmoke 打印所有 Python 线程的堆栈并把子进程 PID 报告回 hang analyzer 继续分析用-p传入的进程名会覆盖默认列表用-d传入 PID 列表时直接指定进程且优先级高于-p和-g进程名匹配默认是contains包含可用-m exact改为精确匹配。匹配时会把名字转小写并去掉扩展名如 Windows 上的.exe。本地使用 hang analyzer 时interesting进程的定义是以python或live-record开头的进程以及 resmoke 派生的子进程来自 docs/testing/hang_analyzer.md。执行 hang-analyzer 收集 core dump 与堆栈对非 Jepsen 任务文档给出的本地调用方式是buildscripts/resmoke.py hang-analyzer -o file -o stdout -m exact -p python这条命令精确匹配机器上所有python进程目标就是 resmoke 本身并向其发信号。resmoke 被信号触发后会做三件事打印所有 Python 线程的堆栈、为其非 Python 子进程收集 core dump 及诊断信息、对 Python 子进程再次发信号做同样的事。Jepsen 任务的调用方式是可选分支buildscripts/resmoke.py hang-analyzer -o file -o stdout -p dbtest,java,mongo,mongod,mongos,python,_test如果需要明确对指定进程收 core dump 或直接锁定 PID在命令中加入-c、-d等参数。Evergreen 超时时 resmoke 实际再次调用的形式就是这种带 PID 的写法python3 buildscripts/resmoke.py hang-analyzer -o file -o stdout -k -c -d pid1,pid2,pid3文档特别指出这里两个参数的含义-k会在分析完成后杀死被分析的进程-c表示为每个被分析的进程生成 core file。pid1,pid2,pid3需要你替换为实际挂起进程的 PID。如果你还想保留这些测试进程继续存活不要加-k——源码显示未加-k时被暂停的非 Python 进程在分析结束后会被恢复。各参数含义来自 plugin.py参数用途-c/--dump-core为每个被分析的进程生成 core file-k/--kill-processes分析完成后杀死被分析的进程-d/--process-ids逗号分隔的 PID 列表优先于-p、-g-p/--process-names逗号分隔的进程名列表-g/--go-process-names逗号分隔的 Go 进程名会被 SIGABRT 触发堆栈输出-m/--process-match进程名匹配方式contains默认或exact-s/--max-disk-usage-percent允许打 core 的最大磁盘使用率默认 90-o/--debugger-outputfile或stdout可重复指定以同时写多处默认只写 stdout--task-id/-t给定 Evergreen task ID用于取对应的符号理解数据收集的顺序按 docs/testing/hang_analyzer.md 的描述数据收集按以下顺序执行暂停所有非 Python 进程防止 hang analyzer 附着时它们解卡非 Sanitizer 构建上抓取调试符号对 Python 进程发信号尽可能多地 dump core直到磁盘配额耗尽默认配额是所在卷总空间的 90%对应-s参数收集附加的非 core 数据C 堆栈、MozJS 堆栈、锁/互斥量信息、Server Sessions、Recovery Units、存储引擎信息用 jstack dump Java 进程Jepsen 测试对 Go 进程发 SIGABRTUnix/terminateWindows。各平台的具体收集逻辑由 dumper.py 中的 dumper 对象实现Linux 用GDBDumpermacOS 用LLDBDumperWindows 用WindowsDumper和JstackWindowsDumper另有平台无关的兜底SigabrtDumper非 Windows 的 Java 进程用JstackDumper。判断收集是否完成、结果在哪里运行结束后按以下线索核对结果调试器输出-o file时每个被附着的进程会生成一个debugger_process_pid.log文件-o stdout时输出写到该 Python 进程的 stdout。core dump 文件文档说明结果生成的 core dump 会放在当前运行目录可直接在仓库工作目录或启动 resmoke 的目录下查找。日志中的运行信息hang_analyzer.py 会打印Current disk usage percent、分析结束时打印Done analyzing all processes for hangs磁盘空间不足时会跳过并打印Not enough space for a core dump, skipping ...若中途有异常会打印Exceptions were thrown while dumping. There may still be some valid dumps.——也就是说部分 dump 失败时成功的 dump 仍然保留可继续分析。可选用 core-analyzer 分析 core dump收集到 core dump 后仓库提供了core-analyzer子命令文档见 buildscripts/resmokelib/hang_analyzer/README.mdpython3 buildscripts/resmoke.py core-analyzer它默认在build/install目录找二进制、在当前目录找 core dump本地环境不同时可用--install-dir和--core-dir指定其他位置。如果要分析 Evergreen 上某个任务的 core dumppython3 buildscripts/resmoke.py core-analyzer --task-id{task_id}其中{task_id}替换为对应的 Evergreen task ID。该方式会下载任务的所有 core dump 和二进制到--working-dir默认是core-analyzer目录分析结果写入该目录下的analysis子目录。限制core analyzer 目前只在 Linux 上运行Windows 仍使用 legacy hang analyzermacOS 没有 core dump 分析。另外如果分析机与跑任务的 Evergreen host 不是同一 AMI部分分析可能失败。可选让测试超时时自动触发 hang analyzer在跑 resmoke 时加上--testTimeoutN单位秒0 或留空表示不设超时来自 run/init.py某个测试超时后 resmoke 会自动对该测试相关的所有进程执行 hang analyzer。被分析的进程范围包括测试用例创建的进程、该进程的任意子进程、带有该测试专属环境变量标记的进程、与任一子进程同进程组的进程仅 Unix以及任务 fixture 的进程。文档同时提醒一个边界如果某个进程像示例中的bar那样被创建在新的进程组里macOS 上可能漏掉它——父进程退出后它被init收养不再是子进程且在开启 SIP 的 macOS 上一般无法读取任意进程的环境变量。已知边界本地运行 hang analyzer 时没有超时限制文档原话hang analyzer 自己也可能无限期挂起在 Evergreen 上则受 post-task timeout 约束可能来不及收集完所有信息就被 agent 终止。附加非 core 数据的完整列表C 堆栈、MozJS 堆栈、锁信息、Sessions、Recovery Units、存储引擎信息只在 Linux 上准确其他平台只是子集。core dump 受磁盘配额限制默认 90%空间不足时对应进程的 core 会被跳过但其他信息仍会收集。【免费下载链接】mongoThe MongoDB Database项目地址: https://gitcode.com/GitHub_Trending/mo/mongo创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考