Skip to content
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

"methods whose bodies are too close to one another"? #5

Open
logiclrd opened this issue Apr 27, 2018 · 6 comments
Open

"methods whose bodies are too close to one another"? #5

logiclrd opened this issue Apr 27, 2018 · 6 comments
Assignees
Labels

Comments

@logiclrd
Copy link

I have a project where I am patching a bug in the WPF TreeView class by replacing one of its non-public methods with my own implementation. I am installing this "shim" with the following code:

	public static void Install()
	{
		var realMethod = typeof(System.Windows.Controls.TreeView).GetMethod("HandleMouseButtonDown", BindingFlags.Instance | BindingFlags.NonPublic);
		var replacementMethod = typeof(TreeViewShim).GetMethod(nameof(TreeView_HandleMouseButtonDown_shim), BindingFlags.Static | BindingFlags.NonPublic);

		Redirection.Redirect(realMethod, replacementMethod);
	}

This has been working fine on a variety of workstations for several months, but a co-worker's machine just the other day started throwing this exception:

        if ((sizeOfPtr == sizeof(long) && difference < 13) || (sizeOfPtr == sizeof(int) && difference < 7))
            throw new InvalidOperationException("Unable to redirect methods whose bodies are too close to one another.");

https://github.com/6A/Ryder/blob/master/Ryder.Lightweight/Ryder.Lightweight.cs#L61

To get things working for now, I am going to try a bit of an ugly work-around: I will make two identical copies of my shim method, and if one of them is too close, then in theory it should be impossible for the other one to also be too close (even if it is a trampoline). But, I'm trying to understand why:

a) this works fine on many other machines,

b) it just stopped working on this particular machine where it was working before, and

c) how methods in different classes can have entrypoints less than 13 bytes apart.

What is the correct fix in this situation??

@logiclrd
Copy link
Author

Update: The work-around did not succeed. Will try to gather further information.

@logiclrd
Copy link
Author

A further update: After restarting Windows, the problem went away. The person who observed the bug is pretty sure that this happened once before, as well -- a reboot fixed it, but then it recurred.

@71 71 self-assigned this Apr 28, 2018
@71 71 added the bug label Apr 28, 2018
@71
Copy link
Owner

71 commented Apr 28, 2018

Mhm, all this is very strange. Furthermore, I've only ever observed errors due to close method bodies on methods of a same class. I'll look into it.

@71
Copy link
Owner

71 commented Apr 28, 2018

Do you use the lightweight version (or the full version, if you don't mind recompiling it)? If so, can you try moving these lines below those ones?

I suspect none of the methods have been jitted yet, and thus point to temporary memory locations that might be close to one another.

Alternatively, you can try invoking your TreeView_HandleMouseButtonDown_shim method before creating the redirection, which will force its compilation (you can provide invalid arguments and make it throw, that's fine).

@logiclrd
Copy link
Author

I will try all those things if/when the problem recurs. As of right now, rebooting the system apparently fixed it, but my coworker will definitely reach out to me if it starts happening again. I also made a test application for him to run that fully annotates all values and the logic flow within the Redirection.Redirect method, so we're well equipped for when we see the problem again.

@71
Copy link
Owner

71 commented Apr 30, 2018

Okay, so hopefully we get to the bottom of this. But this kind of behavior makes me wonder how exactly I have control over it...

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

2 participants