fix: make HookManager.TrackedHooks thread-safe, might fix invalid CLR state

This commit is contained in:
goaaats 2022-01-12 18:33:40 +01:00
parent af4a25c74b
commit 0e95424704
No known key found for this signature in database
GPG key ID: F18F057873895461
4 changed files with 16 additions and 6 deletions

View file

@ -49,7 +49,7 @@ namespace Dalamud.Hooking
this.statsMethod.GetILGenerator().Emit(OpCodes.Ret); this.statsMethod.GetILGenerator().Emit(OpCodes.Ret);
var dele = this.statsMethod.CreateDelegate(typeof(Action)); var dele = this.statsMethod.CreateDelegate(typeof(Action));
HookManager.TrackedHooks.Add(new HookInfo(this, dele, Assembly.GetCallingAssembly())); HookManager.TrackedHooks.TryAdd(Guid.NewGuid(), new HookInfo(this, dele, Assembly.GetCallingAssembly()));
} }
/// <summary> /// <summary>
@ -79,7 +79,7 @@ namespace Dalamud.Hooking
this.statsMethod.GetILGenerator().Emit(OpCodes.Ret); this.statsMethod.GetILGenerator().Emit(OpCodes.Ret);
var dele = this.statsMethod.CreateDelegate(typeof(Action)); var dele = this.statsMethod.CreateDelegate(typeof(Action));
HookManager.TrackedHooks.Add(new HookInfo(this, dele, Assembly.GetCallingAssembly())); HookManager.TrackedHooks.TryAdd(Guid.NewGuid(), new HookInfo(this, dele, Assembly.GetCallingAssembly()));
} }
/// <summary> /// <summary>

View file

@ -75,7 +75,7 @@ namespace Dalamud.Hooking
this.hookImpl = ReloadedHooks.Instance.CreateHook<T>(detour, address.ToInt64()); this.hookImpl = ReloadedHooks.Instance.CreateHook<T>(detour, address.ToInt64());
} }
HookManager.TrackedHooks.Add(new HookInfo(this, detour, callingAssembly)); HookManager.TrackedHooks.TryAdd(Guid.NewGuid(), new HookInfo(this, detour, callingAssembly));
} }
/// <summary> /// <summary>

View file

@ -1,4 +1,5 @@
using System; using System;
using System.Collections.Concurrent;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;
using System.Runtime.InteropServices; using System.Runtime.InteropServices;
@ -28,7 +29,7 @@ namespace Dalamud.Hooking.Internal
/// <summary> /// <summary>
/// Gets a static list of tracked and registered hooks. /// Gets a static list of tracked and registered hooks.
/// </summary> /// </summary>
internal static List<HookInfo> TrackedHooks { get; } = new(); internal static ConcurrentDictionary<Guid, HookInfo> TrackedHooks { get; } = new();
/// <summary> /// <summary>
/// Gets a static dictionary of original code for a hooked address. /// Gets a static dictionary of original code for a hooked address.

View file

@ -1,4 +1,5 @@
using System; using System;
using System.Collections.Generic;
using System.Linq; using System.Linq;
using System.Reflection; using System.Reflection;
@ -174,6 +175,8 @@ namespace Dalamud.Interface.Internal.Windows
ImGui.EndTabItem(); ImGui.EndTabItem();
} }
var toRemove = new List<Guid>();
if (ImGui.BeginTabItem("Hooks")) if (ImGui.BeginTabItem("Hooks"))
{ {
ImGui.Columns(4); ImGui.Columns(4);
@ -204,10 +207,13 @@ namespace Dalamud.Interface.Internal.Windows
ImGui.Separator(); ImGui.Separator();
ImGui.Separator(); ImGui.Separator();
foreach (var trackedHook in HookManager.TrackedHooks) foreach (var (guid, trackedHook) in HookManager.TrackedHooks)
{ {
try try
{ {
if (trackedHook.Hook.IsDisposed)
toRemove.Add(guid);
if (!this.showDalamudHooks && trackedHook.Assembly == Assembly.GetExecutingAssembly()) if (!this.showDalamudHooks && trackedHook.Assembly == Assembly.GetExecutingAssembly())
continue; continue;
@ -265,7 +271,10 @@ namespace Dalamud.Interface.Internal.Windows
if (ImGui.IsWindowAppearing()) if (ImGui.IsWindowAppearing())
{ {
HookManager.TrackedHooks.RemoveAll(h => h.Hook.IsDisposed); foreach (var guid in toRemove)
{
HookManager.TrackedHooks.TryRemove(guid, out _);
}
} }
ImGui.EndTabBar(); ImGui.EndTabBar();