【问题标题】:How to run valgrind for the server?如何为服务器运行 valgrind?
【发布时间】:2019-11-26 06:35:46
【问题描述】:

我是 valgrind 的新手。我需要为用 C++ 编写的服务器运行 valgrind。服务器监听一个端口。在 Valgrind 中运行服务器时,我无法与服务器通信。端口未在监听。

valgrind --tool=memcheck --leak-check=yes --log-file=valgrind_log.txt /binary_path-c

当我使用 valgrind 运行时,我需要服务器监听端口。

【问题讨论】:

  • strace -e trace=network 是否确认您的程序不是binding 端口或accepting 连接?
  • 请出示您的minimal reproducible example 来证明问题
  • 您确定服务器在尝试与其通信之前已完全启动?

标签: c++ memory-leaks valgrind


【解决方案1】:

如果您已经确认完全相同的二进制文件正在执行所需的网络套接字 open() 并且它在 Valgrind 中不起作用,请继续阅读。

Valgrind 仅适用于二进制文件,不能附加到已运行的进程(如 here 所述)。

Valgrind 对有效 UID 的更改也很敏感,尤其是在从根 UID 运行时。您不能将 sudo 与 valgrind (detailed here) 一起使用。

您不能对启用了 Linux 功能位 (details here) 的可执行二进制文件进行 Valgrind。

Valgrind 无法处理 NFS 文件系统上的 root setuid(即使安装时允许这样做)。解决方法是将构建或二进制文件移动到非 NFS 分区。

上面说了这么多,这是一个时间问题,Valgrind 让事情变得更慢,并且你的代码的控制流“错过了它的标记”来执行对网络套接字的打开。唯一的方法是在整个代码中加入调试打印语句并确定时序逻辑。

或者... 要查看生产级守护程序从一开始就在做什么,请执行:

valgrind --trace-children=yes /usr/skin/<your-server-binary>

还有另一种监控网络套接字的方法,请继续阅读...

从执行开始跟踪

您可以从一开始就执行strace,并通过以下方式找出打开了哪个网络套接字(稍后将描述,显示其缓冲区内容):

strace -eopen <your-server-binary> <server-arguments>

记下所需的fd(文件描述符)编号。

与启动进程时的任何strace 命令一样,按Ctrl-C 将停止该进程。但是在实时进程上使用 strace,您可以使用 Ctrl-C 安全地从其目标进程中分离(并让该进程继续运行)并返回到您的命令 shell 提示符。

附加到已经运行的服务器

但是您可以使用 strace 监控已经在运行的生产守护程序服务器,但很难为您的网络套接字找到打开的 fd 编号。简单地执行上一步以获取 fd

使用 ps auxw 找出您的 PID。

然后在此处插入您的服务器/守护进程的 PID:

 strace -f -p <your-server-PID -fnetwork

找出它的fd号码。

精确的套接字监控

使用已识别的fd,重新运行 strace 以附加到该生产服务器:

strace -f -eread=<fd> -ewrite=<fd> -p<your-daemon-PID>

网络故障排除清单

  • lsof -i -n 开放端口列表
  • strace
  • netstat -lt
  • tcpdump/wireshark

herehere 和最全面的here 提供了 Linux 网络故障排除工具列表。

【讨论】:

  • 谢谢约翰。它很有帮助。会检查。
猜你喜欢
  • 2015-09-08
  • 2014-05-30
  • 2014-12-31
  • 2012-01-18
  • 1970-01-01
  • 1970-01-01
  • 2011-05-20
  • 1970-01-01
  • 2018-05-19
相关资源
最近更新 更多