如何在不通过 valgrind 命令选项启动 Process 的每个实例的情况下对每个实例进行 valgrind memcheck
Posted
技术标签:
【中文标题】如何在不通过 valgrind 命令选项启动 Process 的每个实例的情况下对每个实例进行 valgrind memcheck【英文标题】:how do i valgrind memcheck on every instance of Process without starting it via valgrind command options 【发布时间】:2009-08-06 11:37:36 【问题描述】:如何在不通过 valgrind 命令选项启动的情况下对 Process 的每个实例进行 valgrind memcheck。
有没有办法将监控选项保存在进程中,而不是每次都使用 valgrind 命令启动进程?
在 Microsoft Application Verifier 中,如果指定要监视应用程序,则该应用程序的任意数量的实例都会受到监视,无论它是子进程还是以其他方式启动。
有什么想法可以在 Valgrind 中做同样的事情吗?
我已经尝试了 valgrind memcheck 的 --trace-children=yes 选项...但是我的应用程序 xyz 向另一个应用程序 zzz 发出信号以启动 xyz(process) 的新实例,我想对其进行分析。在这种情况下,当 xyz 完成发送 zzz 信号时,valgrind 退出。它不会跟进 zzz 启动的进程。
谢谢, 维杰
【问题讨论】:
【参考方案1】:IIRC,Valgrind 必须执行应用程序,因为它会更改只读符号以替换常见的库函数,如 malloc
等。
这意味着您不能将 memcheck 附加到已经运行的进程,因为它无法更改内存中程序的该部分(并且可能会破坏运行状态)。
可能还有其他原因。 quick google 建议您也不能将 memcheck 附加到正在运行的进程。如建议的那样,您可以将可执行文件包装在 bash 脚本中,例如。因此,如果程序myprog
创建了newprog
的新进程,则执行以下操作:
]$ mv /path/to/myprog /path/to/newprog
然后
#!/bin/bash
valgrind (options) /path/to/newprog $@
并称它为myprog
$@
确保参数被传递。然后,当您的程序使用myprog -a b -c d
创建一个新进程时,它会被包装在 valgrind 中。
这仅适用于某些 C 调用,例如 execve()
和其他调用,而其他创建进程的晦涩方式可能无法利用包装。
如果我错了,最好知道:)
【讨论】:
谢谢艾登,这是个好主意。我将尝试包装可执行文件以创建另一个传递参数的进程实例,如建议的那样,看看是否有帮助。谢谢,维杰【参考方案2】:您能否将xyz
包装在一个批处理文件或另一个在 valgrind 中启动它的可执行文件中?
换句话说,将xyz
重命名为run_me_under_valgrind
,然后创建一个新的xyz
,在valgrind 下启动原来的run_me_under_valgrind
。
【讨论】:
【参考方案3】:关于包装器可执行文件,我已经为 PostgreSQL 找到了以下脚本。 (我已经删除了各种特定于 postgres 的部分,例如发现提供的 valgrind 抑制文件)。
#!/bin/bash
set -e -u -x
# Pop top two elements from path; the first is added by pg_regress
# and the next is us.
function join_by local IFS="$1"; shift; echo "$*";
IFS=':' read -r -a PATHA <<< "$PATH"
export PATH=$(join_by ":" "$PATHA[@]:2")
NEXT_POSTGRES=$(which postgres)
if [ "$NEXT_POSTGRES" -ef "./valgrind/postgres" ]; then
echo "ERROR: attempt to execute self"
exit 1
fi
echo "Running $NEXT_POSTGRES under Valgrind"
valgrind --leak-check=full --show-leak-kinds=definite,possible \
--gen-suppressions=all --verbose --time-stamp=yes \
--log-file=valgrind-$$-%p.log --trace-children=yes \
--track-origins=yes --read-var-info=yes --malloc-fill=8f \
--free-fill=9f --num-callers=30 postgres "$@"
注意PATH
操作,以确保我们不会再次尝试从同一个地方执行postgres
。在这种情况下,包装脚本也必须准确命名为 postgres
,因此我必须确保它不会递归执行自身。
另一种方法是使用whatis -a
在路径中查找下一个可执行文件并直接运行它。但我发现这对我的用例造成了其他问题。
顺便说一句,如果您遇到类似
的错误 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。
【讨论】:
以上是关于如何在不通过 valgrind 命令选项启动 Process 的每个实例的情况下对每个实例进行 valgrind memcheck的主要内容,如果未能解决你的问题,请参考以下文章
我们如何在不使用 `psql` 的命令或选项的情况下显示集群中的所有数据库? [复制]
如何在 Linux (redhat) 上通过 gdb 在 xterm 中使用 valgrind?