Help! WSDAPI crashes after my service method returns!

I'm going to take a quick detour from WSDAPI 101 to comment on an issue you may have seen when developing and testing a service or client based on WSDAPI.

The symptoms of this crash
This problem may arise in two scenarios:

  1. You have a service object hosted by the WSDAPI device host.  A wire message triggers a call into this service method.  Shortly after your service method returns, your application crashes.
  2. You have a client-side event sink and have subscribed to events from a service.  When an event arrives, WSDAPI enters your event sink method.  Shortly after your event sink method returns, your application crashes.

In both cases, this problem only applies to applications running on the desktop version of WSDAPI (i.e., under Windows Vista or Server 2008).  This does not apply to WSDAPI-based apps running under Windows CE. 

You may see this manifest in a handful of different ways:

  • If it's under a debugger, your application may issue an Access Violation (AV).
  • If not, your application may crash and trigger a Watson error.
  • You may receive a Data Execution Prevention popup.

The explanation behind the crash 
In all cases, the cause is the same: a difference in the calling convention is causing your service method (or client-side event sink) to corrupt the stack when it returns control to WSDAPI.  WSDAPI expects that your service method will use the __stdcall calling convention, but it's common for applications to be compiled with __cdecl (or even __fastcall) conventions, especially if built in Visual Studio.

How to fix this crash
To fix this problem, you need to change your compilation options to use __stdcall (/Gz) instead of other calling conventions.  Since this problem is most prevalent in the Visual Studio build environment (which defaults to __cdecl), here are directions for fixing this in VS 2005:

  1. In the Solution Explorer, right-click on your project and select Properties
  2. Navigate to Configuration Properties, C/C++, Advanced
  3. Be sure to select All Configurations in the Configuration drop-down
  4. Change the Calling Convention dropdown to __stdcall (/Gz)

At right is a screenshot that describes this property page and the changes you need to select.  The areas of interest are highlighted in red.

We're also going to fix this for the next version of WsdCodeGen, so you can use whatever calling convention you'd like in your application.  Until then, changing this option will allow your service methods to safely return without crashing the application.