如何知道一个进程是不是已启动但在 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 中崩溃的主要内容,如果未能解决你的问题,请参考以下文章

linux 查看zookeeper是不是启动

如何查看linux kibana 是不是启动

Delphi的几个难题?

如何用linux命令查看nginx是不是在正常运行

linux如何添加端口,并且查询此端口是不是已开启?

Linux中启动进程的方法都有哪些?哪种更好用?