JVM coredump分析系列(4):常见的SIGBUS案例分析

文章介绍了SIGBUS错误在机器物理内存故障和文件映射异常访问两种场景下的表现、排查方法及复现用例。对于内存故障,通过分析hs_err_pid文件和系统日志可以发现物理内存问题。在文件映射异常中,多线程并发操作同一文件可能导致SIGBUS,通过检查hs_err_pid文件和业务日志能定位问题。提供了具体的Java应用复现案例。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

前言

笔者先前遇到多个SIGBUS crash问题,在此处归纳整理下问题定位思路并且给出复现的用例,以便提升定位同类问题的效率。通常访问内存触发 SIGBUS 有如下几种场景:

(1)未对齐内存的读写

(2)机器物理内存故障

(3)文件映射异常访问

本文主要从 机器物理内存故障 和 文件映射异常访问 两个场景分别阐述问题发生的现象、排查方法以及复现的用例。

机器物理内存故障触发的SIGBUS

机器上很多进程都会出现crash,每次出现crash的堆栈不一样,并且有些进程crash在系统库上,例如 libc.so、libpthread.so。

1. 排查方法

(1)分析 hs_err_pid 文件

从hs_err_pid文件中可以看出访问地址 0x000000054c0bc000 触发 SIGBUS,并且 si_code 为 4 (BUS_MCEERR_AR)。

从官方 sigaction 用户手册中[1]查看到 si_code 中 BUS_MCEERR_AR (4) 、BUS_MCEERR_AO (5) 表示物理内存故障。

BUS_ADRALN
    Invalid address alignment.

BUS_ADRERR
    Nonexistent physical address.

BUS_OBJERR
    Object-specific hardware error.

BUS_MCEERR_AR (since Linux 2.6.32)
    Hardware memory error consumed on a machine check;
    action required.

BUS_MCEERR_AO (since Linux 2.6.32)
    Hardware memory error detected in process but not
    consumed; action optional.

(2)分析系统日志

查看出现crash前后时间点的系统日志,可以看到打印出很多 kernel 异常信息(Hardware Error ,hardware memory error等),从系统日志中进一步佐证是由于物理内存故障导致访问内存crash。

文件映射异常访问触发的SIGBUS

文件映射访问异常触发 SIGBUS 在用户态最为常见[2],也最容易触发。通常来说根本原因都是进程 mmap 了一个文件后,另外的进程把这个文件截断了,导致 mmap 出来的某些内存页超出文件的实际大小,访问那些超出的内存页就会触发 SIGBUS。具体来说有以下几种场景:

(1)进程 mmap 一个文件后,其它进程 truncate 该文件到更小;

(2)动态库更新,直接 cp 覆盖;

(3)可执行文件更新,直接 cp 覆盖。

1. 排查方法

我们可以按照如下步骤排查文件映射异常访问触发的SIGBUS:

(1)查看 hs_err_pid 文件 T H R E A D 信息中打印的 si_addr;

(2)查看 hs_err_pid 文件 Dynamic libraries 找到 si_addr 映射的文件;

(3)在业务日志中打印对应文件的操作记录,查看是否存在并发读写问题。

2. 复现案例

在Java应用中,每次文件映射异常访问触发的SIGBUS的线程堆栈可能不一样,下面笔者在下文中阐述下最常见的两个案例。

案例一:并发处理同一文件触发SIGBUS

笔者在业务中多次碰到在x86_64机器中调用 ~StubRoutines::jlong_disjoint_arrayc

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值