question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Patch does not run if specific other patch exists

See original GitHub issue

Apologies in advance for the vague description. This is a mind boggling issue for me (I’m new to this) and I’m not even sure if Harmony is at fault. I’m hoping someone can point me in the right direction with this.

Consider this pseudo code:

void DoThings()
{
    OneThing();
    AnotherThing();
}

If I patch OneThing, that works as expected. Prefix, postfix, finalizer, all work fine.

Now, if I also patch DoThings, that works, but any patch for OneThing will now be skipped. That is to say, the debug logs say that the method did get patched, but the code does not run. It does not matter if it is a prefix, postfix, or finalizer. None of them run.

In fact, if the patch on DoThings is empty, like so:

void Prefix() { }

Obviously it will now not do anything, and yet it still breaks the other patch.

Is this expected behaviour?

The context in which I discovered this is the Unity game Valheim, and the bug (if it is one) happens in a mod I wrote, but was initially caused by another mod. Meaning, my mod had patched OneThing and that no longer worked because another mod had patched DoThings.

How can I debug this and figure out what’s actually going on “behind the scenes”?

Issue Analytics

  • State:open
  • Created 6 months ago
  • Comments:11 (5 by maintainers)

github_iconTop GitHub Comments

1reaction
ManlyMarcocommented, Apr 3, 2023

Thanks, @ghorsington will have to take a look at it.

0reactions
SpikeHimselfcommented, Apr 4, 2023

The more I think about this, the less sense it makes in my head. Why does the inner method get inlined when a harmony patch exists on the outer method, but not if it doesn’t?

Getting other mods to add a soft dependency on my mod would be an impossible task. There are a plethora of mods that patch the outer method. It seems that in a game where you can build stuff, lots of mods are interested in the build event for some reason! 😛 Renaming my mod isn’t great either as I would have to abandon the current mod and make a new one, risking my sanity as well as a loss in endorsements and users. Writing a preloader just because I want to know when a specific item is being built in a game seems like insane overkill, I’d like to avoid that approach at all costs.

I did write a silly work-around which checks the result of the inner method after a small delay, and in that way I am able to “emulate” the circumstances under which the inner patch “would have” run. It’s very ugly but I guess it’ll have to do.

Is there a way for me to detect that the outer method was patched? Because if it wasn’t, I can patch the inner method and everything will be fine, and I won’t need my work-around. I can then opt to only run my work-around if strictly necessary. (edit: I found Harmony.GetAllPatchedMethods(), yay!)

The only other thing for it, I suppose, would be to write “known issue” in the comment above my patch and move on with life.


Edit: Working around this issue like so:

var playerPlacePiecePatched =
    Harmony.GetAllPatchedMethods().Where(m => m.DeclaringType.Name.Equals("Player") && m.Name.Equals("PlacePiece")).Any();

if (!playerPlacePiecePatched)
{
    Log.Debug("Patching WearNTear.OnPlaced, yay!");
    patcher.PatchAll(typeof(WearNTear_OnPlaced));
}
else
{
    Log.Debug("Patching Piece.SetCreator, boo!");
    patcher.PatchAll(typeof(Piece_SetCreator));
}

Seems to get the job done when I patch the outer method myself.

(Piece.SetCreator is another inner method that is being called by the same outer method - it’s not the event I’m looking for, but in its postfix I can, after a small delay, check the results of the inlined method)

Now it doesn’t matter if my mod was loaded first or not - so long as the outer method was not patched yet, patching the inner one will work. And once the inner method is patched, patching the outer method does not cause problems.

Read more comments on GitHub >

github_iconTop Results From Across the Web

git: patch does not apply
I faced an issue with one file (present in old repo) getting removed in the repo. And when I apply the patch, it...
Read more >
Check if a file or folder has been patched already
No, 0 is correct. Patch would exit with non-zero if the dry-run failed for some reason, in which case the patch shouldn't be...
Read more >
Patch function error: The specified column does not exist
Solved: I have an Edit Form for a SharePoint list and a button that saves the data. Here is the OnSelect: Patch('SP List...
Read more >
Patch function error says that a column doesn't exist. No ...
I know that the column is definitely not being recognised, because the error tells me "The specified column 'Image' doesn't exists. The column ......
Read more >
How to apply a patch
This page explains how you can apply a patch file. ... (with the '--dry-run' option), to see if we are going to find...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found