01 November 2008

Wild World of Visual Studio -- Proxies confront Hooks

How can Internet Explorer settings interfere with productivity add-in to Visual Studio, such as ReSharper? And even lead to Visual Studio crash when doing some seemingly unrelated operations, like checking out source code from Team Foundation Server?

Story 3 -- Proxies confront Hooks

We've got a number of reports about Visual Studio crash when doing repository operations using TFS. Of course, when ReSharper is disabled, no crashes occurs, which make users think ReSharper is guilty. We couldn't reproduce the problem in the labs, and we again tried to assert/log/verify everything we can think about. We even got some dumps with the crash, but could not find anything really useful there, besides evidence that there are numerous SecurityExceptions instances in the managed heap waiting to be collected. We needed reproducible case with WinDbg attached. Thanks to Vasily, we got one.

It is funny how we were debugging this crash. Since we were not able to reproduce the problem in the labs, we needed access to the faulty computer. However, due to corporate rules on the user's side, we were not able to arrange real remote session. But we had WinDbg with command line interface, and we had instant messaging. So I was sending WinDbg commands, he copied them into WinDbg, executed, and then copied back the result. We laughed about it and were kidding about extension to WinDbg which would be Jabber client :)

After several days being in this copy-paste process, we finally found the problem. Three components playing together made it explosive:

  • Connecting to web site with HTTP when automatic proxy configuration script is enabled (It is basically JScript function which gives proxy address for given host)
  • Managed hooks installed (here is ReSharper's role in the problem, but could be any other plugin)
  • Pumping messages during JScript code execution

Remove one, and all is fine again. So, what is happening in our case? Now, watch my hands.

  1. TeamFoundation client is going to communicate to server.
  2. It initiates connection to web service.
  3. HttpWebRequest is asking for proxy information.
  4. WebProxy detects that automatic proxy configuration script is enabled.
  5. AutoWebProxyScriptEngine downloads script and uses JScript engine to execute it
  6. JScript engine restricts code permissions to execute only.
  7. Exception happens while executing JScript and dialog is going to be shown with error information. This is who pumps messages.
  8. Our managed hook is executed and attempts to use CallNextHookEx to pass data to other hooks.
  9. Code Access Security system demands UnmanagedCode permission.
  10. Due to restricted mode in which JScript executes, demand fails and SecurityException is rised.
  11. Exception causes corruption of some internal Visual Studio COM objects, which instantly leads to Access Violation.

Well, actually, this one was our fault. I added SecurityPermissionAttribute asserting UnmanagedCode permission to the hook procedure and ReSharper is shining like a diamond again.

Case closed, lessons learned.

3 comments:

Libor said...

lol, nice one. that remote debugging part had to be really tedious, hadnt it? :) from my experience I dare say that the most annoying bugs are the most easiest to fix, like comment a line of code, do a one-line fix and so on, but it takes hours (days) to figure out whats wrong and it also require a lot of patience :) but if you take it as a challange, then it can be fun

Sean Kearon said...

Hi Ilya, great that you have found all these...well done! Any idea of when you will be relasing fixes (EAP or patch)?

Ilya Ryzhenkov said...

Sean, nightly builds for ReSharper 4.1 already contain fixes for all that depends on us.