“vshost32.exe has stopped working”

This is another one of the common errors developers get and ask about: vshost32.exe has stopped working.

Problem Statement

When I run my project (or a particular usecase), it displays an error: vshost32.exe has stopped working

Assessment

vshost was introduced in Visual Studio 2005 (only for use in VS). These are files that contains vshost in the file name and are placed under the output (default bin) folder of the application. It is the “hosting process” created when we build a project in Visual Studio.

It has following core responsibilities:

  • to provide support for improved F5 performance
    To run a managed application in debug mode using F5 command, Visual Studio would need an AppDomain to provide a place for the runtime environment within which the application can run. It takes quite a bit of time to create an AppDomain and initialize the debugger along with it. The hosting process speeds up this process by doing all of this work in the background before we hit F5, and keeps the state around between multiple runs of the application.
  • for partial trust debugging
    To simulate a partial trust environment within Visual Studio under the debugger would require special initialization of the AppDomain. This is handled by the hosting process
  • for design time expression evaluation
    To test code in the application from the immediate window, without actually having to run the application. The hosting process is used to execute code under design time expression evaluation.

More details can be read here.

With above details, there could be issues while interacting with Operating System through this AppDomain and thus causing an error.

Possible Resolutions

Generally, it would be to figure out if the issue is specifically because of Visual Studio hosting process or there are other issues at play interacting with vshost.

Scenario 1:

It’s 64 bit OS, app is configured to build as AnyCPU, yet we get an error

Try:
32 bit/64 bit issues usually plays a role in relation to OS features and locations that are different. There is a setting in Build configuration that drives the debugger behavior when it is setup for AnyCPU. You need to turn off (un-tick checkbox) the Prefer 32 bit flag to run in 64 bit mode.

Now, even with above change, we can face issues that fall into 32/64 bit region. This is where vshost is still playing a role. Irrespective of above, flag vshost continues to work in 32 bit mode (platform config AnyCPU). Now, calls to certain APIs can be affected when the hosting process is enabled. In these cases, it is necessary to disable the hosting process to return the correct results. Details about how to turn it off in Debug tab: How to: Disable the Hosting Process

With above changes, AnyCPU configuration would be equivalent to the app as platform target x64 configuration.

Scenario 2:

Application is configured to build as x86 (or AnyCPU)

Try:
If the workflow is related to a third party, for 32 bit applications, use 32 bit runtime, irrespective of the OS being 32 bit or 64 bit.

Scenario 3:

Application is throwing an error for a specific code work flow that involves unmanaged assembly

Try:
If the workflow includes an interop call to an external assembly (unmanaged code that is executed outside the control of CLR), there might be incorrect usage of the function all. I have seen examples where a wrong return type can cause a vshost error. Return type of the external DLL cannot be string, it must be IntPtr.

[DllImport("Some.dll", CallingConvention = CallingConvention.Cdecl)]
private static extern IntPtr SomeMethod();
Scenario 4:

Application is throwing an error for a specific code work flow that is in realms of managed code (by CLR)

Try:
It could be that the process is taking time while executing that particular workflow. If the process is busy for a long time, it can throw an error. One of the solve would be to try the entire long operation on a BackgroundWorker thread and free up UI thread.

Conclusion

We can turn off the vshost as long as we are okay without it. It always helps to have same debugging environment (32/64 bit) as the app is expected to run in. We should be cognizant of the operations done with third party assemblies or unmanaged ones and have the right set of code/files interacting with application.

Happy troubleshooting!

Samples GitHub Profile Readme

“Unable to evaluate expression because the code is optimized or a native frame is on top of the call stack”

This is one of the common runtime error reported by a lot of ASP.NET users.

Problem description

A successfully compiled code at runtime throws the following error during an operation:

“Unable to evaluate expression because the code is optimized or a native frame is on top of the call stack.”

Typically, this happens when the Response.EndResponse.Redirect, or Server.Transfer method is used.

Assessment

This happens because current page execution is stopped and execution is sent to the Application_EndRequest event in the application’s event pipeline.

The duty of Response.End method is to stop the page execution and raise the EndRequest event. Thus, the line of code that follows Response.End is not executed. Error occurs with Response.Redirect and Server.Transfer methods too because both the methods call Response.End internally.

When a call is made to the Abort method to destroy a thread, the CLR throws a ThreadAbortException. It is a special exception that can be caught, but will automatically be raised again at the end of the catch block. When this exception is re-raised, the CLR executes all the finally blocks before ending the thread.

Using Visual Studio debugger, we can see the internal message for the exception as “Thread was being aborted.”

Resolution

Try one of the following that suits your workflow:

  • Use a try-catch statement to catch the exception if needed
try { 
  // your code here
} 
catch (System.Threading.ThreadAbortException ex){ 
  // log/handle it
}
  • For Response.End:
    Invoke HttpContext.Current.ApplicationInstance.CompleteRequest method instead of Response.End to bypass the code execution to the Application_EndRequest event
  • For Response.Redirect
    Use an overload,  Response.Redirect(String url, bool endResponse) that passes false for endResponse parameter to suppress the internal call to Response.End
Response.Redirect ("mynextpage.aspx", false);
  • For Server.Transfer
    Use Server.Execute method to bypass abort. When Server.Execute is used, execution of code happens on the new page, post which the control returns to the initial page, just after where it was called.

Refer:
Microsoft Support Article – 312629
MSDN: HttpResponse.Redirect Method
MSDN: HttpResponse.End Method
MSDN: ThreadAbortException Class
MSDN: HttpServerUtility.Execute Method

Conclusion

This is as designed. This exception has bad effect on Web application performance, which is why handling the scenario correctly is important.

Keep learning!

“Cannot evaluate expression because the code of the current method is optimized”

This is one the common error faced by a lot of Visual Studio users.

Problem description

Typically, they get the below error message during debugging:

“Cannot evaluate expression because the code of the current method is optimized.”

Assessment

In .NET, “Function Evaluation (funceval)” is the ability of CLR to inject some arbitrary call while the debuggee is stopped somewhere. Funceval takes charge of the debugger’s chosen thread to execute requested method. Once funceval finishes, it fires a debug event. Technically, CLR have defined ways for debugger to issue a funceval.

CLR allows to initiate funceval only on those threads that are at GC safe point (i.e. when the  thread will not block GC) and Funceval Safe (FESafe) point (i.e. where CLR can actually do the hijack for the funceval.) together.

Thus, possible scenarios for CLR, a thread must be:
1. stopped in managed code  (and at a GC safe point): This implies that we cannot do a funceval in native code. Since, native code is outside the CLR’s control, it is unable to setup the funceval.
2. stopped at a 1st chance or unhandled managed exception (and at a GC safe point): i.e at time of exception, to inspect as much as possible to determine why that exception occurred. (e.g: debugger may try to evaluate and see the Message property on raised exception.)

Overall, common ways to stop in managed code include stopping at a breakpoint, step, Debugger.Break call, intercepting an exception, or at a thread start. This helps in evaluating the method and expressions.
Refer: MSDN Blog: Rules of Funceval

Possible resolutions

Based on the assessment, if thread is not at a FESafe and GCSafe points, CLR will not be able to hijack the thread to initiate funceval. Generally, following helps to make sure funceval initiates when expected:

Step #1:
Make sure that you are not trying to debug a “Release” build. Release is fully optimized and thus will lead to the error in discussion. By using the Standard toolbar or the Configuration Manager, you can switch between Debug & Release.
For more details about it: How to: Set Debug and Release Configurations

Step #2:
If you still get the error, “Debug option” might be set for optimization. Verify & Uncheck the “Optimize code” property under Project “Properties”:

  • Right click the Project
  • Select option “Properties”
  • Go to “Build” tab
  • Uncheck the checkbox “Optimize code”

Step #3:
If you still get the error, “Debug Info” mode might be incorrect. Verify & set it to “full” under “Advanced Build Settings”:

  • Right click the Project
  • Select option “Properties”
  • Go to “Build” tab
  • Click “Advanced” button
  • Set “Debug Info” as “full”

Step #4:
If you still face the issue, try the following:

  • Do a “Clean” & then a “Rebuild” of your solution file
  • While debugging:
    1. Go to modules window (VS Menu -> Debug -> Windows -> Modules)
    2. Find your assembly in the list of loaded modules.
    3. Check the Path listed against the loaded assembly is what you expect it to be
    4. Check the modified Timestamp of the file to confirm that the assembly was actually rebuilt
    5. Check whether or not the loaded module is optimised or not
  • Remote chance could be that your call stack is getting optimized because your method signature is too large (more than 256 argument bytes). Read more about it at this MSDN blog

Conclusion

It’s not an error but an information based on certain settings and as designed based on how .NET runtime works.

Keep learning!