You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

程序崩溃时Linux会生成SIGHUP信号吗?Ubuntu Python脚本异常终止排查

验证Python脚本莫名终止原因的实用方法

先快速澄清一个关键点:程序自身崩溃不会直接触发SIGHUP信号。SIGHUP通常是终端会话关闭(比如SSH断开、终端窗口意外关闭)时,由会话管理器发送给后台进程的信号。不过脚本崩溃可能会通过其他信号(比如SIGSEGV段错误、SIGABRT异常终止)或者未捕获的异常导致退出,下面是具体的验证步骤:


1. 给脚本添加信号捕获与日志记录

修改你的Python脚本,主动捕获常见的终止信号,并记录详细的上下文信息,这样能明确进程是收到了什么信号才终止的。示例代码如下:

import signal
import sys
import logging
from datetime import datetime

# 配置日志到文件,持久化记录
logging.basicConfig(
    filename='script_signals.log',
    level=logging.INFO,
    format='%(asctime)s - %(message)s'
)

def signal_handler(signum, frame):
    signal_name = signal.Signals(signum).name
    logging.info(f"Received signal: {signal_name} ({signum})")
    logging.info(f"Current stack frame snapshot: {frame}")
    # 可选:添加必要的清理逻辑后退出
    sys.exit(1)

# 注册需要监控的关键信号:覆盖SIGHUP、崩溃类信号、常规终止信号
for sig in [signal.SIGHUP, signal.SIGSEGV, signal.SIGABRT, signal.SIGTERM, signal.SIGINT]:
    signal.signal(sig, signal_handler)

# 记录脚本正常退出的情况
def exit_handler():
    logging.info("Script exited normally without receiving termination signals")

import atexit
atexit.register(exit_handler)

# 你的原有脚本代码
# ...

运行修改后的脚本,当它终止时,script_signals.log会清晰记录是收到了信号终止,还是正常退出。


2. 捕获Python崩溃的Traceback与核心转储

如果脚本是因为未捕获的Python异常崩溃,它会将错误栈(traceback)输出到标准错误流(stderr)。你可以将stderr重定向到文件,保存这些关键信息:

python your_script.py 2> script_errors.log

如果script_errors.log里有完整的traceback,就能直接定位到脚本的Bug位置。

如果是底层的C扩展或Python解释器崩溃(比如段错误),可以开启核心转储来深入分析:

  1. 临时开启核心转储(仅当前终端会话有效):ulimit -c unlimited
  2. 运行脚本,若崩溃会生成名为core的核心文件
  3. 用GDB分析核心文件:gdb python core,输入bt命令查看崩溃的调用栈,定位问题根源。

3. 用系统工具跟踪进程的终止信号

用strace监控信号交互

strace可以跟踪进程的所有系统调用,包括信号接收:

strace -e signal -o strace_output.log python your_script.py

查看strace_output.log,里面会清晰记录进程收到的每一个信号,比如如果是SIGHUP,你会看到类似--- SIGHUP {si_signo=SIGHUP, si_code=SI_USER, si_pid=1234, si_uid=1000} ---的记录,同时能看到信号的发送者PID和UID。

用auditd监控进程终止事件

安装auditd工具(sudo apt install auditd),然后添加监控规则:

# 可以用进程名监控,替换为你的脚本实际运行的进程名
sudo auditctl -a exit,always -F arch=b64 -S exit_group -F comm=python

之后查看审计日志:

sudo cat /var/log/audit/audit.log | grep exit_group

日志里会包含进程终止的信号、退出码、父进程PID等关键信息,能帮你区分是外部发送的信号还是进程自身崩溃退出。


4. 排查SIGHUP的真正来源

如果确实发现是SIGHUP导致终止,那大概率不是脚本崩溃触发的,而是外部会话结束导致的:

  • 用pstree -p <script_pid>查看脚本的父进程,如果父进程是某个shell(比如bash),那当这个shell退出时(比如SSH断开),会给子进程发送SIGHUP。
  • 可以用nohup运行脚本,让它脱离终端会话:nohup python your_script.py > script_output.log 2>&1 &,如果这样脚本不再被终止,就说明之前的SIGHUP来自终端会话关闭。

内容的提问来源于stack exchange,提问作者jsstuball

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.28 09:39:57