BUG: You receive a "0xC0000005" error code when a native event is fired or unhooked (811193)



The information in this article applies to:

  • Microsoft Visual C++ .NET (2002)

SYMPTOMS

When you fire the __raise event, or you unhook (__unhook) native events, in an unmanaged application, you may receive the following error message:
Unhandled exception at virtual address in executable: 0xC0000005: Access violation reading location virtual address
where virtual address and executable are values that are specific to your application.

CAUSE

The problem occurs when the constructor of the event source is defined outside the class scope. The event handler list is not initialized in the constructor of the event source in the injected code. Therefore, the access violation occurs when the uninitialized memory is accessed.

WORKAROUND

To work around this problem, use one of the following methods:

Method 1

Define the constructor of the event source in its class scope. To do this, replace the existing code:
struct A {
	__event void Event(); 
	A(); 
	void bar(){} 
};
//Constructor defined outside class scope.
A::A() { } 
with the following code:
struct A {
	__event void Event(); 
	A() { }; //Contructor defined in class scope.
	void bar(){} 
};

Method 2

Include the eventHandlerList initialization code in the event source constructor. This assumes that the .cpp file that contains the event source class definition is event.cpp. The injected code that is generated by the compiler can be stored in an intermediate file with help of the /Fx command line compiler option.
  1. At the command prompt, type the following command:
    cl /Fx event.cpp
    The injected code that is generated by the compiler is saved in a file with the .mrg.cpp extension. For event.cpp, the file with the injected code is event.mrg.cpp.
  2. In the intermediate file that is generated (event.mrg.cpp), add the following code to the event source constructor:
    • If the event source class that is named A is defined in a namespace X, add the following code:
      __eventHandlerList_X_A_Event = 0;
      to the constructor for A.
    • If the event source class that is named A is not defined in any namespace, add the following code:
      __eventHandlerList_A_Event = 0;
      to the constructor for A.
    Where A is the event source class, X is the namespace for A, and Event is the event identified by the __event keyword in the event source class.
  3. Compile the intermediate file at the command prompt with the following command:
    cl event.mrg.cpp

STATUS

Microsoft has confirmed that this is a bug in the Microsoft products that are listed at the beginning of this article.

MORE INFORMATION

Steps to Reproduce the Behavior


You can reproduce the problem with either of the following two scenarios:

Scenario 1

Define an event source inside a namespace. Additionally, the event source and the event receiver are implemented by the same class or struct. To do this, follow these steps:
  1. In Visual Studio .NET, create a Visual C++ Win32 Console Application project.
  2. In the default .cpp file that is generated for your application, replace the existing code with the following code:
    #include "stdafx.h"
    namespace X 
    { 
    //Both event source and event receiver
    	struct A {
    	 	__event void Event(); 
    		A(); 
    		void bar(){} 
    	};
    }
     
    X::A::A() { } 
    
    int main()
    { 
    	X::A a; 
    	__hook(&X::A::Event, &a, &X::A::bar, &a); 
    	a.Event(); 
    	__unhook(&X::A::Event, &a, &X::A::bar, &a); 
    } 
  3. Build and run the application.
You receive the error message that is described in the "Symptoms" section of this article.

Scenario 2

Define an event source and event receiver in two different classes or structs. To do this, follow these steps:
  1. In Visual Studio .NET, create a Visual C++ Win32 Console Application project.
  2. In the default .cpp file that is generated for your application, replace the existing code with the following code:
    #include "stdafx.h"
    //Event source
    struct A {
    	__event void Event();
    	A();
    };
     
    //Event Receiver
    struct B
    {
    	void bar();
    };
    
    void B::bar(){} 
    A::A() { } 
    
    int main()
    {
    	A a;
    	B b;
    	__hook(&A::Event, &a, &B::bar, &b);
    	a.Event();
    	__unhook(&A::Event, &a, &B::bar, &b); 
    }
  3. Build and run the application.
You receive the error message that is described in the "Symptoms" section of this article.

The problem occurs because the compiler generates incorrect injected code for the constructor of the event source. To view the injected code that is generated by the compiler, compile the earlier code at the command prompt as follows:
cl /Fx event.cpp
where the code is saved in event.cpp. The code that is generated by the compiler is available in a file that is named event.mrg.cpp. The event class constructor does not contain the following eventHandlerList initialization code when the event class constructor is defined outside the class scope:
  • When the event source class that is named A is defined in a namespace X
    __eventHandlerList_X_A_Event = 0;
  • When the event source class that is named A is not defined in any namespace
    __eventHandlerList_A_Event = 0;
Where A is the event source class, X is the namespace for A, and Event is the event that is identified by the __event keyword in the event source class.

Note Similarly the __raise event keyword shows the same behavior that is displayed by the __unhook event keyword.

REFERENCES

For additional information about native event handling keywords and attributes, see the following MSDN Web site:

Modification Type:MinorLast Reviewed:1/18/2006
Keywords:kbCompiler kberrmsg kbBug KB811193 kbAudDeveloper kbAudITPRO