PyCharm退出码135(SIGBUS)报错全解析:从信号机制到实战排查

发布时间:2026/10/8 15:05:51
PyCharm退出码135(SIGBUS)报错全解析:从信号机制到实战排查
在PyCharm里写完脚本满怀期待地点下运行按钮结果控制台只甩出一行冷冰冰的提示Process finished with exit code 135 (interrupted by signal 7: SIGBUS)。如果你正对着这行字发呆恭喜你碰上了PyCharm里最容易让人一头雾水的一类错误。它不是语法错误也不是Python代码里抛出的异常而是操作系统直接以信号的方式把进程给杀了。尤其在Windows上跑得好好的脚本换到Linux服务器、远程解释器或者Docker容器里突然就崩这种“换个环境就出事”的剧本最容易让新手崩溃。这篇文章我会把这个错误拆开揉碎从信号机制讲到实际排查步骤再分享我自己踩过的三次真实事故最后给你一张可以直接抄作业的排查速查表。无论你是刚入门的Python学习者还是已经部署过几个项目的工程师都能在这里找到能直接落地的解决思路。1. 看懂135SIGBUS到底是什么1.1 退出码135与信号7的关系先解决一个认知问题135不是Python的退出码而是shell对“进程被信号杀死”的通用翻译。在Linux系统里只要进程因为接收信号而终止shell就会用“128信号编号”来报告退出状态。SIGBUS的信号编号正好是7所以1287135PyCharm就把这个数字原封不动展示给了你。再看后半句interrupted by signal 7: SIGBUS。这一句是PyCharm帮你做的翻译它非常明确地告诉你进程不是正常退出也不是抛出异常退出而是在某个瞬间触发了操作系统的信号处理机制被强制终止。这种终止方式有一个特点Python层面的try/except根本拦不住因为你连异常对象都没来得及创建进程就已经没了。所以遇到这个报错后第一反应不应该是去代码里找怎么捕获它而是先搞清楚底层到底发生了什么。常见的退出码对照可以参考退出码对应信号含义129SIGHUP终端挂断130SIGINTCtrlC中断137SIGKILL被强制杀死135SIGBUS总线错误1.2 SIGBUS与SIGSEGV的区别很多同学会把SIGBUS和另一个更常见的SIGSEGV混淆。简单说SIGSEGV是“段错误”发生在程序访问了无效内存地址的时候比如指针指向空、数组越界这是地址本身不合法而SIGBUS是“总线错误”发生在程序访问了一个硬件层面无法处理的合法地址的时候。我习惯用这个类比SIGSEGV是你拿钥匙去开一个地址根本不存在的门SIGBUS是你拿着钥匙走向一扇挂着正确门牌号的门结果走近发现这栋楼根本就不存在门只是画在墙上的。看起来都是开门失败但问题的层次完全不同。落到实际开发场景SIGBUS最常见的原因是访问了内存映射文件mmap里超出实际文件大小的区域以及物理IO失败导致页面无法换入内存。这类问题在本地磁盘上跑不容易触发但一旦换成网络文件系统、分布式存储或者容器环境概率就会明显上升。2. 六大典型原因按概率排序2.1 文件映射遭遇截断或磁盘异常这是最常见的原因没有之一。Python生态里有大量库在底层会用到mmap机制比如pyarrow读取Parquet文件、numpy的memmap数组、甚至某些数据库驱动。mmap的逻辑很直接把文件的一部分映射到进程地址空间程序访问这些地址时操作系统再按需从磁盘加载对应页。问题出在文件大小和映射区域的一致性上。如果进程A已经把文件映射好进程B在另一边把文件截断或者覆盖写小了进程A再访问后面那部分映射区域时操作系统会发现“地址存在但对应的文件内容已经不存在了”。此时它无法像读取正常文件那样补页进来只能回敬一个SIGBUS把进程打死。另外磁盘空间满了也会触发类似问题。当操作系统需要把内存页换出到swap分区时如果swap所在磁盘写不进去、网络挂载点失联、或者物理硬盘出现坏道内核也会用SIGBUS来终止正在等待换入换出的进程。你可以理解为操作系统想帮你把数据搬回来但搬数据的车半路抛锚了它干脆把你连人带车一起扔了。2.2 C扩展库与内存对齐问题第二个高发原因是Python的C扩展库特别是numpy、scipy、pandas这类重度依赖编译代码的库。这类库在底层会直接操作内存buffer如果某个库在编译时开启了特殊优化指令集或者在特定CPU架构上触发了未对齐访问就可能触发总线错误。这里有个很现实的使用场景你本地是x86的Windows跑得好好的代码放到一台ARM架构的服务器上跑结果刚import numpy就崩。x86架构对未对齐内存访问的容忍度比较高而ARM架构相对敏感一旦触碰到非法访问硬件直接抛总线错误。很多人在远程开发时才遇到这个问题其实不是代码变了是CPU架构变了。2.3 PyCharm缓存与索引损坏很多人想不到PyCharm自己的索引缓存损坏也会引发这种报错。PyCharm为了提升代码补全和文件搜索速度会把整个项目的结构、符号信息、虚拟环境状态做成索引和缓存存放在本地比如Windows下的%LOCALAPPDATA%\JetBrains、Linux下的~/.cache/JetBrains。如果IDE中途强退、磁盘满、或者缓存目录被清理工具误删这些索引文件就可能处于半损坏状态。表现就是PyCharm从启动开始行为就不正常有时是代码补全失效有时是一运行脚本就莫名其妙报信号类错误。我在实际中见过最极端的情况即使是一个只打印hello world的脚本只要在PyCharm里运行就崩但在命令行里怎么跑都没事。这种时候问题几乎可以断定出在IDE本身上了。2.4 解释器环境配置错误第四个常见原因是虚拟环境本身出了问题。特别是conda环境如果你把一台机器上的环境目录整个拷贝到另一台机器往往会出大问题。原因在于conda很多二进制文件在编译和链接时记录了绝对路径换机器后路径对不上动态库加载失败或者加载到旧版本的库这种诡异状态下什么错误都可能冒出来SIGBUS就是其中之一。还有一种情况是PyCharm里配置的解释器路径已经失效。比如你之前用的虚拟环境被删了、python二进制被换掉了但PyCharm的设置里还指认着老路径。运行脚本时PyCharm去找这个不存在的解释器启动阶段的初始化就会出问题表现出的错误五花八门。2.5 远程解释器与WSL/容器环境问题现在越来越多人在用PyCharm的远程解释器功能、WSL解释器、或者直接在IDE里操作Docker容器。这些环境下SIGBUS出现的概率比本机要高不少。以WSL为例如果你在Windows侧挂载的目录里运行Python脚本文件IO要跨越Windows和Linux两套文件系统内存映射的读写一致性在某些内核版本下实现得并不完美一旦触发就会崩。远程SSH解释器也一样如果网络不稳定远程环境读取网络挂载文件时IO失败SIGBUS就会悄然降临。这类问题有个共同特征换个本地目录跑或者换回本机解释器问题就消失了。2.6 硬件级别的内存或磁盘故障最后一种也是大家最不愿意面对的一种物理硬件出问题了。内存条接触不良、内存颗粒损坏、磁盘坏道都可能让内核在换页过程中遇到不可恢复的IO错误进而用SIGBUS终止进程。这类问题往往毫无规律你今天跑一个复杂脚本崩了明天跑同一个脚本又没事。如果排除了上面所有可能建议跑一遍内存检测工具别让硬件问题成为压垮你项目的最后一根稻草。3. 实操排查流程5步定位问题3.1 第1步最小化复现排除IDE干扰动手排查后第一件事就是确认问题到底出在哪个层面。新建一个只包含一行代码的脚本print(hello)然后在PyCharm里直接运行。如果这个脚本也崩了说明问题不在你的业务代码而在解释器、IDE或者系统环境如果这个脚本正常说明问题大概率出在你代码里某个库或者某个文件操作上。如果这个最小脚本崩了再做一个对比测试在命令行里直接用同一个解释器运行这个脚本conda activate your_env python test.py命令行也崩那基本可以断定是解释器或系统环境问题跟PyCharm无关。命令行不崩、PyCharm里崩那问题多半在PyCharm的配置或缓存上。这一步能帮你把排查范围缩小一大半。3.2 第2步查看系统日志锁凶在Linux环境下进程因信号被终止时内核通常会留下痕迹。执行dmesg | tail -30或者journalctl -k --since 10 minutes ago重点看有没有类似python3[12345]: bus error或者segfault的记录。日志里如果有进程名、地址信息排查范围会急剧缩小。比如日志里明确指向某个共享库文件那问题多半是动态库加载错误如果指向硬件错误那就要尽快检查磁盘和内存。这里有个容易忽略的点如果系统开启并设置了core dump你还可以在崩溃目录下找到core文件用gdb调试gdb /path/to/python core在gdb里输入bt查看崩溃时的调用栈。这是最精确的定位方式能直接告诉你崩溃发生在哪个函数里比瞎猜靠谱得多。3.3 第3步磁盘、内存与文件完整性检查用三板斧检查底层环境df -h free -m ls -lh /tmp重点关注三件事项目所在分区还剩多少空间、swap分区状态是否正常、/tmp目录是否几乎写满。很多程序会把临时数据放到/tmp如果这里满了mmap创建临时文件失败后续访问就会崩。如果你的脚本正在读取某个数据文件试着确认文件是否完整。比如统计文件大小是否与预期一致、用md5sum对比两次读取的哈希值、或者干脆把文件从NFS先拷贝到本地再读取。如果是线上系统最好加上文件版本校验逻辑不要直接跨网络读大文件。3.4 第4步清理PyCharm缓存并重建环境如果排查到这一步还没找到原因建议动一下PyCharm本身。先试试最经典的修复动作菜单栏选File → Invalidate Caches / Restart在弹出的对话框勾选Clear file system cache and Local History重启PyCharm后等待索引重建完成如果是解释器配置问题打开File → Settings → Project: xxx → Python Interpreter重新选择解释器或者干脆删除当前虚拟环境用conda重新创建一个全新的环境并安装依赖。我强烈建议不要直接拷贝别人给的环境目录老老实实用conda env export environment.yml然后在新机器上conda env create -f environment.yml这样可以避免动态库路径漂移带来的各种奇怪问题。3.5 第5步A/B对照测试如果上面四步都没定位到具体问题就做一个更彻底的对照实验。准备一台干净的机器可以是另一台服务器、一台虚拟机或者平时不怎么用的电脑在上面安装同样的Python版本、同样的依赖库运行同样的代码。如果干净机器上跑得好好的问题肯定出在原来的环境配置上如果干净机器也崩那问题出在代码或者公共依赖本身。这个过程就像做实验的时候换试剂每次只改一个变量。要么换环境、要么换数据、要么换机型改完跑一次看结果通过排除法一步步锁定元凶。4. 三次真实SIGBUS的排查记录4.1 案例一NFS数据文件被并发重写有一阵子我在做训练数据的预处理数据文件存放在公司的NFS服务器上读取端用pyarrow读Parquet格式另一边有定时任务每六小时重写一次数据目录。某天下午开始任务频繁崩溃控制台清一色的SIGBUS。一开始我还以为是数据格式问题反复检查代码没发现任何异常。后来把读取逻辑改成先把文件拷贝到本地/tmp临时目录再读取本地文件问题立即消失。这才意识到读取端打开文件时文件大小是A另一边的重写任务是删掉旧文件重建目录映射区域对应的文件瞬间变成了B甚至是不存在。进程再去访问已经失效的映射页内核直接送上了SIGBUS。这个案例给我最大的教训是不要在生产环境里直接跨网络读正在被并发修改的数据文件。至少要做文件版本控制或者在读取之前先检查文件的修改时间和大小。4.2 案例二conda环境整体搬家还有一次为了把项目从一台服务器迁移到另一台我图省事直接把整个conda环境目录打包拷了过去bin目录、lib目录一个不落。结果一运行脚本十次有八次崩在import pandas那一步表现就是SIGBUS。排查时先用命令行手动运行脚本也一样崩排除了PyCharm的因素。后来在一次闲聊中一位同事提醒我“你是不是直接把环境目录拷过去的conda很多so文件里记录的路径还是老的。”我回去查了那个环境的动态库依赖发现多个库的RPATH还是旧的绝对路径新机器上根本找不到对应的库文件。那次之后我所有环境迁移都老老实实用conda env export导出配置文件再到新机器重新创建。虽然多花了几分钟安装时间但换来的是稳定不再需要跟各种莫名其妙的内存错误作斗争。4.3 案例三PyCharm缓存损坏有一个比较特殊的案例出在PyCharm自己身上。某次IDE因为系统更新被强制重启之后无论运行什么脚本哪怕是hello world都在启动Python解释器的瞬间崩溃报错就是exit code 135。怪异的是在命令行里用同一个解释器跑同一个脚本毫无问题。当时我差点把解释器相关的配置全部删掉重建。最后抱着试试看的心态执行了Invalidate Caches / Restart清空缓存后重启问题直接消失。这类问题没有太多逻辑可言就是缓存文件在意外中断时损坏了。如果你怎么都排查不出环境问题记得先给PyCharm做一次“大扫除”。5. 排查速查表与避坑心得5.1 排查速查表把上面所有内容浓缩成一张表方便遇到问题时直接对照场景特征优先排查方向推荐做法只在PyCharm内崩命令行正常PyCharm缓存/索引损坏Invalidate Caches并重启读取网络挂载文件时崩文件被并发修改或IO失败本地拷贝后再读加版本校验conda环境搬家后开始崩动态库路径漂移conda env export重新创建换ARM架构机器后崩CPU内存对齐问题检查numpy等C扩展库版本跑复杂任务才崩简单脚本没事内存或磁盘硬件故障跑memtest并检查磁盘坏道容器或WSL环境才出现跨文件系统映射兼容性改用本地目录或换文件系统挂载方式过程随机无明显规律swap分区或磁盘空间问题检查df -h和swap状态5.2 几条实在的避坑心得第一不要把SIGBUS当成普通的Python异常来调试。它通常意味着你已经触碰到了操作系统和硬件的边界对应的排查思路应该是“这个进程为什么会被底层信号打死”而不是“代码哪里写错了”。换个角度很多问题会豁然开朗。第二批量操作大文件时注意文件锁和并发控制。数据文件被读取的同时被另一个进程重写是最常见的SIGBUS触发条件。如果你的业务流程里有“读旧文件、写新文件”的步骤尽量采用写临时文件再原子重命名的方式避免读取端看到文件被截断的中间状态。第三遇到这类问题不要急着重装PyCharm。我见过不少人因为一次报错就把整个IDE卸载重装结果什么问题都没解决还折腾了好几小时。正确顺序应该是先跑最小脚本排除业务代码问题再看系统日志排除硬件和环境问题最后才考虑动IDE。按照这个顺序走大多数问题都能在半小时内定位。第四如果是远程开发给文件操作加个超时和重试机制。网络文件系统不可能像本地磁盘那样稳定代码里直接假设每次读取都会成功本身就是一种隐患。在关键路径上做好异常兜底比事后排查信号错误要省力得多。我个人在实际排查中最大的体会是这种报错往往不是单一原因造成的而是“环境不规范数据操作太随意”叠加的结果。把代码写得健壮一点遇到跨平台部署时多留个心眼SIGBUS离你就会很遥远。如果看完这篇还是没能解决你的问题至少你现在知道该去看哪里了先最小脚本再系统日志然后磁盘内存最后清缓存重建环境一步步来别慌。