Skip to content

[BUG] 进入世界即崩溃:JVM 原生崩溃(msvcp140.dll 空指针,1.0.18) #16

Description

@tlipoca-desu

现象

CoreSwap 接管主世界 chunk 生成(NOISE 阶段)后,进入世界即触发 JVM 原生崩溃(EXCEPTION_ACCESS_VIOLATION),崩在 JDK 自带的 msvcp140.dll 空指针解引用。已连续复现三次,每次都在 mod 接管 chunk 生成后、首次 fillBlocks(JNI 进 C++)时就崩。

两种触发场景

  • 先原版建世界(保存退出)→ 后加载 CoreSwap 重进能正常进入世界,但进入后立刻触 fatal(日志里 [Mixin] populateNoise intercepted chunk(15,-4) 之后即崩)。
  • 直接加载 CoreSwap 新建世界:在**"加入世界"界面就立刻崩**;且因区块尚未保存(仍驻内存),下一次启动会重新生成区块

崩溃复现记录(三次):

崩溃日志 时间 线程 运行到崩溃
hs_err_pid1664.log 20:34:16 Worker-Main-3 44.16s
hs_err_pid10708.log 20:35:47 Worker-Main-6 37.91s
hs_err_pid18336.log 22:12:28 Worker-Main-4 22.15s

简单说:只要 CoreSwap 接管主世界 chunk 的 populateNoise(NOISE 阶段),首次 fillBlocks(JNI 进入 C++)就在 msvcp140.dll 里解引用空指针崩溃。这与 #10 所述"进入世界崩溃由 VEH handler 导致"不在同一条路径(本崩溃帧是 C++ 运行库 msvcp140.dll,不是 VEH handler)。

游戏环境

Minecraft 1.20.1
Fabric Loader 0.19.3
Java 21.0.6.0 LTS
Windows 10 64bit (19041.6456)
AMD Ryzen 5 9600X (6C12T)
NVIDIA GeForce RTX 5060 Ti 16G
种子 -1556562625122493351

Mod列表

coreswap 1.20.1-1.0.18
sodium 0.5.13+mc1.20.1
iris 1.7.6+mc1.20.1
fabric-api 0.92.11+1.20.1
modmenu 7.2.2
wthit 8.21.1
xaerominimap 26.4.2
xaeroworldmap 1.45.0
replaymod 1.20.1-2.6.23
minihud 0.27.1
malilib 0.16.3
badpackets 0.4.3

重现步骤

场景 A

  1. 原版 Fabric 配置(不含 CoreSwap)创建世界,保存退出。
  2. mods/ 加入 coreswap-1.20.1-1.0.18.jar,启动,确认日志出现 [BenchMod] CoreSwap replace mode: C++ worldgen active
  3. 重进该存档——能进世界,但立刻 fatal

场景 B

  1. 直接以含 CoreSwap 的配置启动,新建世界。
  2. 在**"加入世界"界面**即崩溃;下一启动会重新生成区块。

日志

三份原始崩溃日志链接:
hs_err_pid18336.log: https://mclo.gs/MrtzEnE
hs_err_pid1664.log: https://mclo.gs/6lOCNlc
hs_err_pid_10708.log: https://mclo.gs/VjjdYs3

hs_err_pid18336.log 节选(03 次崩溃同帧):

# EXCEPTION_ACCESS_VIOLATION (0xc0000005) at pc=0x00007fffa0782f58
# Problematic frame:
# C  [msvcp140.dll+0x12f58]
siginfo: EXCEPTION_ACCESS_VIOLATION (0xc0000005), reading address 0x0000000000000000   <- 空指针解引用

调用栈(近一次,hs_err_pid18336.log):

C  [msvcp140.dll+0x12f58]                          <- 崩溃帧(MSVC 运行库)
j  wg.CppWorldgen.fillBlocks([I[I[[II)I             <- JNI 进入 C++ worldgen
J  ...handler$zze000$coreswap$wgPopulateNoise(...)  <- mod 接管 populateNoise
J  java.util.concurrent.CompletableFuture$UniCompose.tryFire(...)
J  java.util.concurrent.ForkJoinWorkerThread.run()V <- chunk 生成 worker 线程

发现(由Agent协助分析,仅供参考,不代表个人意见)

  1. 崩溃帧不在 VEH handler 路径msvcp140.dll+0x12f58 落在 JDK21 自带的 MSVC 运行库C:\Program Files\Java\jdk-21\bin\msvcp140.dll,基址 0x7fffa0770000,+0x12f58 = 崩溃 pc 0x7fffa0782f58),是 C++ STL 运行库里的空指针。与图形驱动、Sodium/Iris、VEH handler 均无关。
  2. 触发时机worldgen.dllhs_err_pid18336 中于 20.038s 才 Loaded,崩溃发生在 22.15s——即 DLL 加载后约 2 秒、首次 fillBlocks 批量生成即崩(另外两次分别在 Loaded 后约 0.8s/0.2s 崩)。
  3. 崩溃线程Worker-Main-* / ForkJoinWorkerThread(Minecraft chunk 生成 worker 池),_thread_in_native
  4. 本崩溃不经过 VEH,而是 fillBlocks 内解引用空指针 → 1.0.18 根因并未消除,只是换了崩溃点/触发条件。
  5. 产物worldgen.dll size=355840sha256=27d0499297e854a6...,加载自 ...\Temp\coreswap-native\worldgen.dllworldgenDir=...\Temp\coreswap-data\worldgen

补充分析(由Agent协助分析,仅供参考,不代表个人意见)

  • 崩溃在 C++ 侧 fillBlocks(经 JNI 调用)解引用空地址 0x0,属原生代码空指针 / 内存损坏,大概率与并发 batch缓存复用thread_local / FlatCache / Cache2D)有关;当前默认线程数 = hardware_concurrency()(12 逻辑线程),本机为 6 物理核。
  • 建议:符号化 msvcp140.dll+0x12f58 定位具体函数;用 -Dcoreswap.threads=1 串行复测排除并发竞争;给出修复版后按场景 A 复测(原版建世界 → 加 CoreSwap → 重进)。若把 v1.0.16进入世界崩溃 #10 视为"已修复并关闭",那么 1.0.18 在 Java 21 + Windows 10 上仍崩溃,说明 v1.0.16进入世界崩溃 #10 修复不彻底或引入了回归。优先级应设为 P0。

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions