Common WWSAPI errors: usage asserts
One of the design principles of WWSAPI is to be very stringent at the API contract, as we believe ambiguous or loose API contract does not help developers write high quality applications. Being stringent means not only to document the API contract clearly, but also to enforce at runtime that the contract is honored. Considering the fact that it’s very easy to overlook special remarks on API contract in the documentation, we built many usage asserts into the product to ensure the integrity of WWSAPI objects or the contract of using the objects and API. The asserts are placed near the API entry points to make application failure more diagnosable. These asserts, when hit, will bring down the application (and therefore require immediate fixes). The user may see the Windows Error Reporting popup.
Here are the common API contract violations that will lead to usage asserts and bring down applications:
1. Free WWSAPI objects in wrong states: e.g. freeing a WS_SERVICE_PROXY object without closing it first will crash your application.
2. Use a single-threaded object in multiple threads concurrently: this is commonly seen in the use of WS_HEAP, but could happen to the other objects like WS_MESSAGE, WS_ERROR, WS_XML_READER and WS_XML_WRITER due to their dependency on WS_HEAP
3. Use a freed WWSAPI object
If a debugger is attached to the crashing application with proper Windows symbols loaded, you may see a function near the top of the stack with self-explanatory name webservices!HandleApiContractViolation. You may see a more specific function above it like highlighted part in the example below:
KERNELBASE!DebugBreak+0x2
webservices!ReportFatalException+0xa4
webservices!MultiThread_not_allowed_fatal_error+0x32
webservices!HandleApiContractViolation+0xf6
Most of the contract violations will be caught at the first time you run the offending code. The asserts of single-threaded objects may not be easily caught due to the undeterministic nature of multi-threaded execution.