替换DLL后设置类布尔值触发System.BadImageFormatException问题排查
异常问题排查与解决方案咨询
问题核心
触发System.BadImageFormatException的时机异常:并非在预期的DLL加载阶段,而是在替换磁盘上的DLL后,给类中的bool字段PM.AiRestarting设为true时出现。该问题可稳定复现,且仅近一周才出现,此前相同操作无异常。
异常表现细节
- 调试器外运行时:控制台输出“未处理的异常。无法打印异常字符串,因为Exception.ToString()失败”
- 调试器中捕获异常时:查看PM的所有属性(非字段)都会抛出相同异常,提示“path/to/dll 签名不正确”
- 执行
PM.AiRestarting = true时:异常消息为“Bad IL Range”,堆栈跟踪指向代码中的正确位置,但_stackTraceString变量内容混乱,后续会导致调试器退出并弹出相关提示
环境与更新流程
- 硬件设备的后端服务和Web应用基于.NET/Blazor开发,运行在Linux系统,通过Windows端远程程序进行更新,服务需重启后更新生效
- 更新流程:
- 手动更新:直接覆盖文件,确认权限设置正确后重启设备
- 自动更新:通过tar包替换文件,脚本先删除指定目录及旧文件,执行命令
sudo tar --same-owner --touch --overwrite -xzf path/to/tarball.tar -C /解压包,完成权限管理后脚本退出,触发重启时出现错误
问题触发代码
问题出在以下代码的PM.AiRestarting = true;行:
private int HandleInstallFirmwareUpdateStep2(byte[] arrUserCred, byte[] arrCmdData, StringBuilder logMsg, out byte[] arrRespData) { if (PM is { AssetMgr: { } }) // PM在此处可正常访问 { foreach (MachineDriveTrain mdt in PM.AssetMgr.Machines) mdt.Run = false; } int nRet; try { nRet = csc.Execute(); // 执行安装脚本,停止分析循环的所有工作 if (nRet == ClientServer.CSR_OK) { PM.AiRestarting = true; // 该行持续触发异常 // 等待1秒后重启设备 var t = new Thread(() => { PM.RestartAppliance(false); }); t.Start(); } else { Utils.StartPostgreSqlService(out _, out _); RestoreWebAppAndDbConnection(); } } catch (Exception ex) { nRet = ClientServer.CSR_InstallVersionUpdateFailure; } return nRet; }
推测与需求
推测问题源于磁盘文件替换后的签名校验,现需了解如何在重启前的2秒内阻止程序读取该DLL。
内容的提问来源于stack exchange,提问作者Isaac
相关产品推荐
相关产品推荐

