问题描述
我在使用 BazaarPlusPlus 时遇到过一次偶发崩溃:按 F8 打开 HistoryPanel 后,The Bazaar 进程崩溃退出。
这个问题目前无法稳定复现,但从 Windows Error Reporting、Player-prev.log 以及相关代码路径看,崩溃可能与 HistoryPanel 的 preview board 异步渲染流程有关。
我整理了一个脱敏后的证据包:
bpp-f8-historypanel-crash-evidence.zip
bpp-f8-historypanel-crash-evidence.zip
其中包含:
wer-summary.txt:Windows Error Reporting 中与 TheBazaar.exe APPCRASH 相关的关键字段;
player-prev-historypanel-preview-excerpt.txt:从 Player-prev.log 中截取并脱敏后的 HistoryPanel preview board 渲染日志片段;
source-files.txt:本次排查涉及的本地源码路径和对应代码关注点。
崩溃信息
Windows Error Reporting 记录到一次 TheBazaar.exe 的 APPCRASH:
EventType=APPCRASH
Sig[0].Value=TheBazaar.exe
Sig[1].Value=6000.3.11.239
Sig[3].Value=StackHash_9372
Sig[6].Value=c0000374
Sig[7].Value=PCH_0E_FROM_ntdll+0x000000000009E0F4
0xc0000374 看起来更像 native heap corruption,而不是普通的 C# managed exception。因此 BepInEx 日志中没有看到直接的 managed exception stack trace。
相关日志
崩溃 session 对应的 Player-prev.log 尾部可以看到 HistoryPanel preview board 创建和渲染相关日志:
[BPP][PreviewBoardSurface] SetVisible root='HistoryPanelPlayerBoard' visible=False
[BPP][PreviewBoardSurface] Created board root='HistoryPanelPlayerBoard'
[BPP][PreviewBoardSurface] SetVisible root='HistoryPanelOpponentBoard' visible=False
[BPP][PreviewBoardSurface] Created board root='HistoryPanelOpponentBoard'
[BPP][PreviewBoardRenderTarget] ApplyVisibilityAsync cleared surface because visible=false
[BPP][PreviewBoardSurface] SetVisible root='HistoryPanelPlayerBoard' visible=True
[BPP][PreviewBoardRenderTarget] QueueRenderAsync signature=<redacted>
[BPP][PreviewBoardRenderTarget] RenderSurfaceAsync start signature=<redacted>
[BPP][PreviewBoardSurface] RenderAsync start root='HistoryPanelPlayerBoard' signature=<redacted>
[BPP][PreviewBoardSurface] RenderAsync completed root='HistoryPanelPlayerBoard' signature=<redacted>
[BPP][PreviewBoardRenderTarget] RenderSurfaceAsync completed signature=<redacted>
完整脱敏片段见附件中的:
player-prev-historypanel-preview-excerpt.txt
初步排查
F8 会打开 HistoryPanel:
bazaarplusplus-mod/Game/HistoryPanel/HistoryPanel.cs
ToggleHistoryPanelBindingPath = "<Keyboard>/f8"
打开 HistoryPanel 后,会进入历史战斗 preview 渲染路径,相关代码包括:
HistoryPanelPreviewRenderer.RenderPreview
PreviewBoardRenderTarget.QueueRenderAsync
PreviewBoardSurface.RenderAsync
这条路径会创建、销毁或操作 Unity 对象,例如:
GameObject
Transform
RenderTexture
Camera
- preview card objects
但 PreviewBoardRenderTarget 当前通过 async Task 串行化这些 preview render work,并且 continuation chain 中使用了 ConfigureAwait(false)。
由于该路径会操作 Unity 对象,如果 continuation 脱离 Unity 主线程执行,就可能破坏 Unity/native 状态。这与我观察到的 ntdll.dll / 0xc0000374 native crash 表现比较吻合。
期望行为
按 F8 打开 HistoryPanel 时,不应导致游戏崩溃。
实际行为
按 F8 打开 HistoryPanel 后,游戏存在偶发 native crash。
复现情况
目前无法稳定复现。这个问题看起来像 Unity 对象生命周期 / async continuation / 线程上下文相关的偶发问题。
建议检查方向
建议检查 HistoryPanel preview board 渲染管线,确保所有 Unity object lifecycle work 都留在 Unity 主线程执行。
可能的修复方向包括:
- 移除该路径中的
ConfigureAwait(false),避免 preview render continuation 脱离 Unity 捕获的 synchronization context;
- 或者将 preview render queue 改成显式的 Unity coroutine / main-thread dispatcher;
- 检查 HistoryPanel 关闭、切场景、preview render 未完成时的 dispose 逻辑,避免 pending render work 与 Unity object destruction 发生竞态。
由于这是偶发崩溃,我目前无法提供稳定复现步骤;但 WER 崩溃类型、Player-prev.log 尾部日志和相关代码路径都指向 HistoryPanel preview board 渲染流程,建议优先检查这一部分。
问题描述
我在使用 BazaarPlusPlus 时遇到过一次偶发崩溃:按 F8 打开 HistoryPanel 后,The Bazaar 进程崩溃退出。
这个问题目前无法稳定复现,但从 Windows Error Reporting、Player-prev.log 以及相关代码路径看,崩溃可能与 HistoryPanel 的 preview board 异步渲染流程有关。
我整理了一个脱敏后的证据包:
bpp-f8-historypanel-crash-evidence.zipbpp-f8-historypanel-crash-evidence.zip
其中包含:
wer-summary.txt:Windows Error Reporting 中与TheBazaar.exeAPPCRASH 相关的关键字段;player-prev-historypanel-preview-excerpt.txt:从Player-prev.log中截取并脱敏后的 HistoryPanel preview board 渲染日志片段;source-files.txt:本次排查涉及的本地源码路径和对应代码关注点。崩溃信息
Windows Error Reporting 记录到一次
TheBazaar.exe的 APPCRASH:0xc0000374看起来更像 native heap corruption,而不是普通的 C# managed exception。因此 BepInEx 日志中没有看到直接的 managed exception stack trace。相关日志
崩溃 session 对应的
Player-prev.log尾部可以看到 HistoryPanel preview board 创建和渲染相关日志:完整脱敏片段见附件中的:
初步排查
F8 会打开 HistoryPanel:
bazaarplusplus-mod/Game/HistoryPanel/HistoryPanel.csToggleHistoryPanelBindingPath = "<Keyboard>/f8"打开 HistoryPanel 后,会进入历史战斗 preview 渲染路径,相关代码包括:
HistoryPanelPreviewRenderer.RenderPreviewPreviewBoardRenderTarget.QueueRenderAsyncPreviewBoardSurface.RenderAsync这条路径会创建、销毁或操作 Unity 对象,例如:
GameObjectTransformRenderTextureCamera但
PreviewBoardRenderTarget当前通过 asyncTask串行化这些 preview render work,并且 continuation chain 中使用了ConfigureAwait(false)。由于该路径会操作 Unity 对象,如果 continuation 脱离 Unity 主线程执行,就可能破坏 Unity/native 状态。这与我观察到的
ntdll.dll/0xc0000374native crash 表现比较吻合。期望行为
按 F8 打开 HistoryPanel 时,不应导致游戏崩溃。
实际行为
按 F8 打开 HistoryPanel 后,游戏存在偶发 native crash。
复现情况
目前无法稳定复现。这个问题看起来像 Unity 对象生命周期 / async continuation / 线程上下文相关的偶发问题。
建议检查方向
建议检查 HistoryPanel preview board 渲染管线,确保所有 Unity object lifecycle work 都留在 Unity 主线程执行。
可能的修复方向包括:
ConfigureAwait(false),避免 preview render continuation 脱离 Unity 捕获的 synchronization context;由于这是偶发崩溃,我目前无法提供稳定复现步骤;但 WER 崩溃类型、Player-prev.log 尾部日志和相关代码路径都指向 HistoryPanel preview board 渲染流程,建议优先检查这一部分。