如何知道一个进程是不是已启动但在 Linux 中崩溃
Posted
技术标签:
【中文标题】如何知道一个进程是不是已启动但在 Linux 中崩溃【英文标题】:How to know if a process had been started but crashed in Linux如何知道一个进程是否已启动但在 Linux 中崩溃 【发布时间】:2009-05-26 09:28:39 【问题描述】:考虑以下情况:- 我正在使用 Linux。 我怀疑我的应用程序已经崩溃。 我没有启用核心转储。 日志中没有信息。
如何确定在系统重启后我的应用程序已启动,但现在它没有运行,因为它已经崩溃了。
我的应用被配置为服务,用 C/C++ 编写。
在某种程度上:如何获取系统启动后执行的所有进程/服务名称?甚至有可能吗?
我知道,我可以启用日志记录并再次启动该进程以解决崩溃问题。
【问题讨论】:
【参考方案1】:此功能包含在 Linux 内核中。它叫:BSD process accounting.
【讨论】:
也可以考虑使用 atop。这两者结合起来应该涵盖所有内容,大多数事情都不止一种。【参考方案2】:标准做法是为您的守护程序(/var/run/$NAME.pid)创建一个 pid 文件,您可以在其中找到它的进程 ID,而无需手动解析进程树。然后,您可以检查该进程的状态,或者让您的守护进程响应信号(通常是 SIGHUP),并报告其状态。最好确保这个 pid 仍然属于你的进程,最简单的方法是检查 /proc/$PID/cmdline。
附录: 如果您只使用较新的 fedora 或 ubuntu,您的 init 系统是 upstart,它内置了监控和触发功能。
正如@emg-2 所指出的,BSD 进程记帐是可用的,但我认为这不是针对这种情况的正确方法。
【讨论】:
还要记住进程 ID 翻转,因此在检查活动 PID 时,请确保它确实是正在运行的应用程序。一种方法是查看 /proc/PID/cmdline 好点布赖恩 - 我假设一定程度的安全编程实践;)为了彻底,我会添加它。【参考方案3】:我建议您将您开始时的事实写入某种日志文件,可以是在每次启动时被覆盖的私有文件,也可以是通过 syslogd 覆盖的日志文件。
此外,您还可以记录时间戳心跳,以便准确了解崩溃的时间。
【讨论】:
【参考方案4】:您可能可以制作一个诱饵,即一个应用程序或 shell 脚本,它只是真正应用程序的包装,但添加了一些日志记录,例如“应用程序已启动”。 然后更改原始应用的名称,并将原始名称赋予诱饵。
【讨论】:
【参考方案5】:正如 JimB 所提到的,您让守护程序编写一个 PID 文件。您可以通过kill(2)
系统调用或kill(1)
程序向其发送信号0
来判断它是否正在运行。返回状态会告诉你是否存在具有该 PID 的进程。
【讨论】:
【参考方案6】:守护程序应始终: 1) 使用 getpid() (man getpid) 或您的语言的等效命令将当前正在运行的实例的进程写入 /var/run/$NAME.pid。 2) 将标准日志文件写入 /var/log/$NAME.log(对于当前运行的日志,较大的日志文件应拆分为 .0.log,对于其他日志,应将其拆分为 .X.log.gz,其中 X 是一个数字较低是较新的) 3) /Should/ 有一个兼容 LSB 的运行脚本,至少接受启动停止状态和重新启动标志。状态可用于检查守护进程是否正在运行。
【讨论】:
【参考方案7】:我不知道获取所有已执行进程名称的标准方法;不过,SystemTap 可能有办法做到这一点。
如果你只是想监控你的进程,我建议在 fork 之后使用 waitid (man 2 wait),而不是分离和守护进程。
【讨论】:
【参考方案8】:如果您的应用崩溃了,这与“您的应用从未启动”是无法区分的,除非您的应用写入系统日志。 syslog(3)
是你的朋友。
要找到您的应用,您可以尝试多种想法:
查看/proc
文件系统
运行ps
命令
尝试killall appname -0
并检查返回码
【讨论】:
以上是关于如何知道一个进程是不是已启动但在 Linux 中崩溃的主要内容,如果未能解决你的问题,请参考以下文章