-
-
Notifications
You must be signed in to change notification settings - Fork 511
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
NullReferenceException is thrown if CommonDialog.ShowDialog is patched #640
Comments
Trying to figure out what trigger this issue in
It needs |
Something is weird in your test. The field has no way to influence the patch. I just added a test that is essentially the same as your case and it does not fail: 4852c9c |
With certain conditions, the test actually fails. I have to investigate more. |
For now this seems like a WONTFIX until we maybe get an idea on what exactly the runtime does with Nullable. Let me cite some of the things devs from the .NET team wrote:
|
After conducting research, it was found that the issue lies in MonoMod CLR ABI says,
That said, reference types do not have return buffer. Removing the ABI fix wrapper makes it work. So, the root cause is that the caller does not prepare return buffer, but callee expects a Why dosen't
|
I already opened an issue yesterday in MonoMod: MonoMod/MonoMod#206 and my first guess was the return argument being passed as a pointer (there are other cases besides The tricky part here is to fix this systematically, for all .net versions, all operating systems and all processors as well as for all return types. |
Describe the bug
NullReferenceException
is thrown on calling target function.To Reproduce
Steps to reproduce the behavior:
CommonDialog.ShowDialog
on (Microsoft.Win32
)ShowDialog
Expected behavior
Not throw exception
Screenshots / Code
Runtime environment (please complete the following information):
Additional context
harmony.Patch
I can get replacementMethodInfo
, invoke it works properlyLog
Harmony id=a, version=2.3.3.0, location=, env/clr=4.0.30319.42000, platform=Win32NT
Started from static System.Void ConsoleApp2.Program::Main(System.String[] args), location
At 2024-12-19 10.38.46
Patch: virtual System.Nullable`1<System.Boolean> Microsoft.Win32.CommonDialog::ShowDialog()
Replacement: static System.Nullable`1<System.Boolean> Microsoft.Win32.CommonDialog::Microsoft.Win32.CommonDialog.ShowDialog_Patch1(Microsoft.Win32.CommonDialog this)
IL_0000: Local var 0: System.IntPtr
IL_0000: Local var 1: MS.Win32.HwndWrapper
IL_0000: Local var 2: System.Nullable
1<System.Boolean> IL_0000: Local var 3: System.Nullable
1<System.Boolean>IL_0000: Local var 4: System.Boolean
IL_0000: ldloca 3 (System.Nullable
1[System.Boolean]) IL_0004: initobj System.Nullable
1[System.Boolean]IL_000A: ldc.i4 0
IL_000F: stloc 4 (System.Boolean)
IL_0013: ldc.i4.1
IL_0014: stloc 4 (System.Boolean)
IL_0018: ldloc 4 (System.Boolean)
IL_001C: brfalse => Label1
IL_0021: ldloca 3 (System.Nullable
1[System.Boolean]) IL_0025: call static System.Boolean ConsoleApp2.Patch::Prefix(System.Nullable
1& __result)IL_002A: stloc 4 (System.Boolean)
IL_002E: Label1
IL_002E: nop
IL_002F: ldloc 4 (System.Boolean)
IL_0033: brfalse => Label0
IL_0038: // start original
IL_0038: ldarg.0
IL_0039: callvirt virtual System.Void Microsoft.Win32.CommonDialog::CheckPermissionsToShowDialog()
IL_003E: call static System.Boolean System.Environment::get_UserInteractive()
IL_0043: brtrue => Label2
IL_0048: ldstr "CantShowModalOnNonInteractive"
IL_004D: call static System.String System.Windows.SR::Get(System.String id)
IL_0052: newobj System.Void System.InvalidOperationException::.ctor(System.String message)
IL_0057: throw
IL_0058: Label2
IL_0058: call static System.IntPtr MS.Win32.UnsafeNativeMethods::GetActiveWindow()
IL_005D: stloc.0
IL_005E: ldloc.0
IL_005F: ldsfld System.IntPtr System.IntPtr::Zero
IL_0064: call static System.Boolean System.IntPtr::op_Equality(System.IntPtr value1, System.IntPtr value2)
IL_0069: brfalse => Label3
IL_006E: call static System.Windows.Application System.Windows.Application::get_Current()
IL_0073: brfalse => Label4
IL_0078: call static System.Windows.Application System.Windows.Application::get_Current()
IL_007D: callvirt System.IntPtr System.Windows.Application::get_ParkingHwnd()
IL_0082: stloc.0
IL_0083: Label3
IL_0083: Label4
IL_0083: ldnull
IL_0084: stloc.1
.try
{
IL_0085: ldloc.0
IL_0086: ldsfld System.IntPtr System.IntPtr::Zero
IL_008B: call static System.Boolean System.IntPtr::op_Equality(System.IntPtr value1, System.IntPtr value2)
IL_0090: brfalse => Label5
IL_0095: ldc.i4.0
IL_0096: ldc.i4.0
IL_0097: ldc.i4.0
IL_0098: ldc.i4.0
IL_0099: ldc.i4.0
IL_009A: ldc.i4.0
IL_009B: ldc.i4.0
IL_009C: ldstr ""
IL_00A1: ldsfld System.IntPtr System.IntPtr::Zero
IL_00A6: ldnull
IL_00A7: newobj System.Void MS.Win32.HwndWrapper::.ctor(System.Int32 classStyle, System.Int32 style, System.Int32 exStyle, System.Int32 x, System.Int32 y, System.Int32 width, System.Int32 height, System.String name, System.IntPtr parent, MS.Win32.HwndWrapperHook[] hooks)
IL_00AC: stloc.1
IL_00AD: ldloc.1
IL_00AE: callvirt System.IntPtr MS.Win32.HwndWrapper::get_Handle()
IL_00B3: stloc.0
IL_00B4: Label5
IL_00B4: ldarg.0
IL_00B5: ldloc.0
IL_00B6: stfld System.IntPtr Microsoft.Win32.CommonDialog::_hwndOwnerWindow
.try
{
IL_00BB: call static System.Void System.Windows.Interop.ComponentDispatcher::CriticalPushModal()
IL_00C0: ldarg.0
IL_00C1: ldloc.0
IL_00C2: callvirt abstract virtual System.Boolean Microsoft.Win32.CommonDialog::RunDialog(System.IntPtr hwndOwner)
IL_00C7: newobj System.Void System.Nullable
1<System.Boolean>::.ctor(System.Boolean value) IL_00CC: stloc.2 IL_00CD: leave => Label6 IL_00D2: leave => (autogenerated) } // end try .finally { IL_00D7: call static System.Void System.Windows.Interop.ComponentDispatcher::CriticalPopModal() IL_00DC: endfinally IL_00DD: leave => (autogenerated) } // end handler IL_00DE: leave => (autogenerated) } // end try .finally { IL_00E3: ldloc.1 IL_00E4: brfalse => Label7 IL_00E9: ldloc.1 IL_00EA: callvirt virtual System.Void MS.Win32.HwndWrapper::Dispose() IL_00EF: Label7 IL_00EF: endfinally IL_00F0: leave => (autogenerated) } // end handler IL_00F1: Label6 IL_00F1: ldloc.2 IL_00F2: // end original IL_00F2: stloc 3 (System.Nullable
1[System.Boolean])IL_00F6: Label0
IL_00F6: ldloc 3 (System.Nullable`1[System.Boolean])
IL_00FA: ret
DONE
The text was updated successfully, but these errors were encountered: