Improve the mono init debug logic to be simplified and works on Unity 5.4 and older #70
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
This takes a bit of explanation and it fixes #69 , but in an interesting way: we just don't call
mono_debug_domain_create
. I initially wanted to fix this with a simple NULL check, but @js6pak proposed an alternative that I found was working and I have good reasons to think it will keep working. This is what this pr does.Essentially, it unifies the debug init logic to always call the following in that exact order:
mono_jit_parse_options
mono_debug_init
mono_jit_init_version
We already called 1 before the other 2, but the last 2 is where I assumed something wrong: I thought the mono version directed what order they should be called, but that is not the case. What's happening is that
mono_jit_init_version
eventually will callmono_domain_create
which is what callsmono_debug_domain_create
. In other words:mono_debug_create
never needed to be called by doorstop becausemono_jit_init_version
would call it internally. This explains why if I commented out the call in my testing, symbols were still loading fine and the game was as debuggable as any other.That second explicit call is likely what caused problems because not only there's that weird export problem, but because it was assumed to be needed, it made old mono behave differently depending on when you called it. Since it was just found that it wasn't needed to call it in the first place, it allows to simplify the logic to the above on ALL mono versions.
Once I saw it was working on unity 4.6.6p3, 5.5.4 and 2018.4.12, I had to check the unity player dll under ghidra: was this the correct way to do it?
Turns out yes: in all dev builds of the player I could find, it was ALWAYS done in the order above and the player never called
mono_debug_domain_create
directly. Release builds were the same, but without the debug stuff inmono_jit_parse_options
andmono_debug_init
was just not called. That brings me a lot of confidence that this logic is correct as far as I can tell and that at least it's been maintaining for a very wide range of unity versions.The original pr I did to add old mono support did however got one thing right: it is still correct to handle the
mono_jit_parse_options
differently depending on the runtime being v2.x or v4.x. That's something I confirmed with the ghidra analysis too.So we are left with this logic which is simpler, better AND adds support for even older unity games (5.4 and older). As far as I could tell in my testing, the debugging experience should be the same and even symbols (mdb here) would load correctly and I could breakpoint + eval stuff.