ExceptionInspector throws NullReferenceException every frame when a patch method belongs to no mod (dynamic assembly)
还没有人认领这个 Issue。
评估
调研方向
从 Mods.AddMetadata 开始,然后追踪 ExceptionInfo.GetReport 如何创建 mod 详细信息,以及 Columns.Column 如何使用其元数据。使用动态程序集中的 Harmony 补丁方法以及一个经过该方法的异常来复现问题。当打开 inspector 时,针对没有 mod 元数据的补丁不再反复抛出异常,即为完成。
由索引模型根据 Issue 内容生成。
描述
Summary
When a captured exception has a stack frame whose method carries a Harmony patch from an assembly that no mod owns (for example a runtime-generated assembly), the inspector window throws a NullReferenceException on every frame. The log fills with thousands of errors and the window cannot be used.
Seen with Visual Exceptions 1.5.0.0 on RimWorld 1.7.5005, Harmony 3.
Cause
Mods.AddMetadata creates a ModInfo for every patch method, also when GetModMetaData(assembly) returns null:
static IEnumerable<ModInfo> AddMetadata(IEnumerable<MethodInfo> methods)
{
return methods.Select(method =>
{
var assembly = method.DeclaringType.Assembly;
var metaData = GetModMetaData(assembly);
return new ModInfo { method = method, metaData = metaData };
});
}
ExceptionInfo.GetReport then adds an ExceptionDetails.Mod with meta == null, and Columns.Column(this ExceptionDetails.Mod mod) dereferences it:
var name = mod.meta.Name.Truncate(200, truncatedModNamesCache);
Stack frames do not have this problem, because GetMetadataIfMod returns null for non-mod code and GetAllMethods skips those. Only patches are missing the check.
How it showed up
A player ran the Overclock mod with "Parallel pawn ticks (experimental)" on. That feature builds its prefix classes at runtime with AssemblyBuilder.DefineDynamicAssembly (types named IdPrefix_<n>_<method> and IdState_<n>) and patches thousands of mod methods with them. Those types are in no mod's loadedAssemblies.
During loading, another mod requested a graphic with a null texture path, which throws ArgumentNullException in ContentFinder<Texture2D>.Get. One frame of that exception had such a generated prefix on it. Once the inspector opened at the main menu:
Exception filling window for VisualExceptions.ExceptionInspector: System.NullReferenceException: Object reference not set to an instance of an object.
at VisualExceptions.Columns.Column_Patch1(Mod mod)
at VisualExceptions.ExceptionInspector.<>c.<DoWindowContents>b__9_2(Mod mod)
at System.Linq.Enumerable.ListSelectIterator`2.MoveNext()
at System.Linq.Enumerable.MaxFloat[TSource,TResult](IEnumerable`1 source, Func`2 selector)
at VisualExceptions.Columns.MaxWidth(IEnumerable`1 drawers)
at VisualExceptions.ExceptionInspector.DoWindowContents_Patch1(ExceptionInspector this, Rect inRect)
at Verse.Window.InnerWindowOnGUI_Patch3(Window this, Int32 x)
This repeated 2,515 times in under a minute.
Steps to reproduce
- Have any Harmony patch whose patch method is declared in a dynamic assembly, on a method of a mod.
- Throw an exception that passes through that method and is caught by one of the handlers Visual Exceptions instruments.
- Open the inspector.
- 主要语言
- C#
- 星标
- 10
- 派生
- 2
- PR 合并指标
- 30 天内没有已合并 PR
环境准备
这个项目没有提供开发容器、Dockerfile 或贡献指南,环境需要你自己搭建:先看它的 README,通用步骤见我们的新手贡献指南。
从这里开始
- 先读完整个 Issue,再读项目的贡献指南。
- 在 Issue 下留言说明你要接手 —— 这能避免两个人做同样的事。
- Fork 仓库,在一个分支上完成修改。
- 提交 Pull Request,并在描述里引用这个 Issue 编号。
相似的 Issue
-
area:repo elsa 3 prio low triaged type:bug
难度 2/5 1-3 小时 新手友好度 72/100
elsa-workflows/elsa-core#9258 ·
维护者通常 1 天内回复
-
难度 1/5 1 小时以内 新手友好度 90/100
iokode/OpinionatedFramework#140 ·
-
accessibility effort: small enhancement
难度 2/5 1-3 小时 新手友好度 78/100
pedersebastian/CustomBossChallenge#185 ·
维护者通常 1 天内回复
-
难度 2/5 1-3 小时 新手友好度 76/100
-
难度 2/5 1-3 小时 新手友好度 72/100
xceedsoftware/wpftoolkit#1812 ·