迁移J2EE应用至JBoss后JVM SIGSEGV崩溃问题排查求助
问题
我们正将J2EE应用从WebSphere迁移至JBoss,首次冒烟测试中多次出现JVM崩溃,但暂未找到稳定复现路径。JVM崩溃触发SIGSEGV信号,问题帧均指向自定义代码custom.package.ClientEnvironmentServiceImpl.isMobileDevice。此前在WebSphere环境(使用不同JVM)从未出现该问题,尝试模拟对应应用导航操作2次也未成功复现。
JVM崩溃日志
# A fatal error has been detected by the Java Runtime Environment: # # SIGSEGV (0xb) at pc=0x00007fff8df86788, pid=3555039, tid=821817 # # JRE version: OpenJDK Runtime Environment 18.9 (11.0.12+7) (build 11.0.12+7-LTS) # Java VM: OpenJDK 64-Bit Server VM 18.9 (11.0.12+7-LTS, mixed mode, tiered, compressed oops, g1 gc, linux-ppc64le) # Problematic frame: # J 210874 c2 custom.package.ClientEnvironmentServiceImpl.isMobileDevice(Ljava/lang/String;Ljavax/servlet/http/Cookie;)Ljava/lang/Boolean; (64 bytes) @ 0x00007fff8df86788 [0x00007fff8df85e80+0x0000000000000908]
服务器启动命令参数
Command Line: -D[Standalone] -Xlog:gc*:file=/logs/jboss/cert/Product/gc.log:time,uptimemillis:filecount=5,filesize=3M -Xms9216m -Xmx12288m -XX:MetaspaceSize=96M -XX:MaxMetaspaceSize=1024m -Djava.net.preferIPv4Stack=true -Djboss.modules.system.pkgs=org.jboss.byteman -Djboss.as.management.blocking.timeout=10800 -Djorg.jboss.resolver.warning=true -Djava.awt.headless=true -Dgw.server.mode=prod -Dgw.cc.env=FORM -Dgw.cc.serverid=FORM1NSSA -Duser.region=US --add-exports=java.base/sun.nio.ch=ALL-UNNAMED --add-exports=jdk.unsupported/sun.misc=ALL-UNNAMED --add-exports=jdk.unsupported/sun.reflect=ALL-UNNAMED -Dorg.jboss.boot.log.file=/logs/jboss/cert/Product/server.log -Dlogging.configuration=file:/product/jboss-servers/cert/Product/configuration/logging.properties -agentpath:/product/dynatrace/agent/bin/1.265.152.20230519-165227/linux-ppcle-64/liboneagentloader.so=loglevelcon=none,datastorage=/dynatrace/runtime,logdir=/dynatrace/logs /product/jboss-eap/cert/jboss-modules.jar -mp /product/jboss-eap/cert/modules org.jboss.as.standalone -Djboss.home.dir=/product/jboss-eap/cert -Djboss.server.base.dir=/product/jboss-servers/cert/Product -Djboss.server.base.dir=/product/jboss-servers/cert/Product -Djboss.server.config.dir=/product/jboss-servers/cert/Product/configuration -Djboss.server.data.dir=/product/jboss-servers/cert/Product/data -Djboss.server.log.dir=/product/jboss-servers/cert/Product/logs -Djboss.server.temp.dir=/product/jboss-servers/cert/Product/tmp -Djboss.server.deploy.dir=/product/jboss-servers/cert/Product/deployments --server-config=standalone-full.xml -Djboss.bind.address.management=0.0.0.0 -Djboss.bind.address=0.0.0.0 -Djboss.socket.binding.port-offset=100
底层组件信息
Host: POWER9 (architected), altivec supported, 40 cores, 22G, Red Hat Enterprise Linux release 8.5 (Ootpa)
线程栈追踪(上部)
Current thread (0x0000010064c4e800): JavaThread "webcontainer-worker task-68" [_thread_in_Java, id=821817, stack(0x00007fff197a0000,0x00007fff199a0000)] Stack: [0x00007fff197a0000,0x00007fff199a0000], sp=0x00007fff19999f50, free space=2023k Native frames: (J=compiled Java code, A=aot compiled Java code, j=interpreted, Vv=VM code, C=native code) J 210874 c2 custom.package.ClientEnvironmentServiceImpl.isMobileDevice(Ljava/lang/String;Ljavax/servlet/http/Cookie;)Ljava/lang/Boolean; (64 bytes) @ 0x00007fff8df86788 [0x00007fff8df85e80+0x0000000000000908] j custom.package.ClientEnvironmentServiceImpl.isMobileDevice(Ljavax/servlet/http/HttpServletRequest;)Ljava/lang/Boolean;+16 j custom.package.DeviceDetectionUtil.isMobile()Z+7 j pcfc.expressions.FNOLWizard_BasicInfoScreen_01autoExpressions$FNOLWizard_BasicInfoScreenExpressionsImpl.visible_152()Ljava/lang/Boolean;+4 jdk.internal.reflect.GeneratedMethodAccessor2744.invoke(Ljava/lang/Object;[Ljava/lang/Object;)Ljava/lang/Object;+36 J 201421 c2
涉及代码
private String resolveCookieName() { String customName = getCustomCookieName(); if (null != customName) { return customName; } return ClientEnvironmentConstants.COOKIE_DEVICE; }
排查与复现建议
针对JIT编译的验证
SIGSEGV发生在C2编译的代码帧中,优先排查JIT优化问题:
- 临时禁用C2编译器,添加JVM参数
-XX:TieredStopAtLevel=1(仅使用C1编译器),观察是否仍会崩溃。若问题消失,说明是C2优化的bug。 - 若禁用C2有效,进一步缩小范围,用
-XX:CompileCommand=exclude,custom/package/ClientEnvironmentServiceImpl,isMobileDevice单独排除该方法的C2编译,验证是否仅该方法的优化存在问题。
代码层面的全面检查
重点核查isMobileDevice方法的完整实现:
- 检查空指针风险:对传入的
String(如User-Agent)、Cookie对象是否做了null校验,避免直接调用Cookie.getName()、String.contains()等方法。 - 检查数组/字符串越界:若存在字符串拆分、数组索引操作,确认逻辑是否合法。
- 检查线程安全:类中的静态变量、成员变量是否在多线程环境下被不当修改,导致对象状态异常。
强化复现场景
手动复现失败时,尝试以下方式:
- 增加并发压力:用JMeter等工具模拟多线程并发访问触发
isMobileDevice的业务路径,匹配冒烟测试的流量规模。 - 构造边界用例:传入null的User-Agent/Cookie、超长字符串、含特殊字符的User-Agent,验证极端场景下的稳定性。
- 记录请求上下文:在
isMobileDevice方法中添加日志,记录每次调用的入参(User-Agent、Cookie信息),崩溃后对比最后几条请求,复用相同参数尝试复现。
环境与工具排查
- 移除第三方Agent:暂时去掉启动参数中的Dynatrace Agent,确认是否是Agent与OpenJDK的兼容性问题。
- 升级JDK版本:当前使用OpenJDK 11.0.12,尝试升级到同系列最新版本(如11.0.20+),排查是否已修复PPC架构下的JIT已知bug。
- 检查系统稳定性:查看服务器系统日志(
/var/log/messages),确认是否存在内存、硬件相关报错。
内容的提问来源于stack exchange,提问作者lorenzo
相关产品推荐
相关产品推荐

