Repository navigation
Unable to patch methods which DeclaringType is null #445
Description
Activity
Can you please verify with master that the issue is solved and reopen it if it isn't?
Ping @GeorgyPorgy
I checked the behavior with the new changes and it seems some of the problems have already been fixed, but the patching has not yet ended successfully.
Patching work finished with following error : System.InvalidCastException: Unable to cast object of type 'ModifierType' to type 'System.Type'.The last line in the Harmony debug log reports :
### Replacement: static System.UInt32 GLOBALTYPE::GLOBALTYPE.MethodBlaBlaBla(System.Byte* arg1, ....while in the application log the messages list is as follows :
ERROR - System.InvalidCastException: Unable to cast object of type 'ModifierType' to type 'System.Type'.
at HarmonyLib.InlineSignatureParser.g__ReadTypeSignature|0_4(<>c__DisplayClass0_0& )
at HarmonyLib.InlineSignatureParser.g__ReadMethodSignature|0_0(InlineSignature method, <>c__DisplayClass0_0& )
at HarmonyLib.InlineSignatureParser.ImportCallSite(Module moduleFrom, Byte[] data)
at HarmonyLib.MethodBodyReader.ReadOperand(ILInstruction instruction)
at HarmonyLib.MethodBodyReader.ReadInstructions()
at HarmonyLib.MethodPatcher.CreateReplacement(Dictionary`2& finalInstructions)
at HarmonyLib.PatchFunctions.UpdateWrapper(MethodBase original, PatchInfo patchInfo)
at HarmonyLib.PatchProcessor.Patch()Runtime environment :
-
OS: Windows 10, 64bit -
.NET version 4.7.2 -
Harmony version 2.2.0.0-master branch
-
Right now, I can only guess the problem because I have no idea how to write a test for such a method. If you know a way to reference such a method in a test please let me know.
Also the stacktrace indicates that your original method has some very unusual IL codes that trigger the InlineSignature parser. Could you tell me more about your original method and maybe list it’s IL code. Parsing inline IL is still new and not much tested either and has nothing to do with the method being without type.
On further inspection, the stacktrace isn’t helpful because there are several casts to
Typethat could fail so if you could be so kind to make your debugger stop at the exception and maybe give us some overview of what bytes the reader is reading, then me and @0x0ade who wrote the code can help you better.Thanks for your efforts, Andreas.
The method IL code can be seen at the link below :
https://drive.google.com/file/d/1Jq3teFou0PC4ZW0jnGvxcAaMZopZGJYr/view?usp=sharingThe instruction list was generated with ILSpy.
I will attempt to extract additional information with the help of the debugger and provide it as soon as possible.
P.S.
I modified the function "ReadInstructions()" to log the information about the position of the currently processed instruction, but before analyzing its operand ...
The last reported number is 0x0019, which means that the exception occurs when processing the operand in the 'calli' instruction.At this point it is unclear if it is at all possible to create the correct result from this calli due to my possible limitations in the c# reflection api.
I spoke with @0x0ade and it looks like there might be a very convoluted way to support this but at this point it’s unclear if and who could implement this. It’s a rather difficult topic.
Hello Andreas,
https://www.codeproject.com/Articles/1244372/Reflecting-Within-a-Method-Body
section 'InlineSig'Would this article help us ?
regards
That article just shows the basics. Our code here handles this case already:
Harmony/Harmony/Internal/MethodCopier.cs
Line 381 in 3c4cd7f
case OperandType.InlineSig: It’s the parser that fails the case because it is more complicated than the article suggests.
- added a commit that references this issue
on Feb 1, 2024
Describe the bug
When a target method is resolved via Module.ResolveMethod(int Token) its DeclaringType property is null and future attempt to patch the method triggers "System.NullReferenceException: Object reference not set to an instance of an object" at CreateDynamicMethod(MethodBase original, String suffix, Boolean debug)
In fact, the problem described is similar to that described in an already closed ticket. : "Unable to patch methods located inside the GlobalType (aka. ) #235 "
To Reproduce
Steps to reproduce the behavior:
ERROR - System.NullReferenceException: Object reference not set to an instance of an object.
at HarmonyLib.MethodPatcher.CreateDynamicMethod(MethodBase original, String suffix, Boolean debug)
at HarmonyLib.MethodPatcher..ctor(MethodBase original, MethodBase source, List
1 prefixes, List1 postfixes, List1 transpilers, List1 finalizers, Boolean debug)at HarmonyLib.PatchFunctions.UpdateWrapper(MethodBase original, PatchInfo patchInfo)
at HarmonyLib.PatchProcessor.Patch()
Expected behavior
The patch gets applied.
Runtime environment (please complete the following information):