CLR SPY and Customer Debug Probes: The Disconnected Context and Unmarshalable Interface Probes


When managed code interacts with COM objects via RCWs, the CLR handles the COM plumbing for you.  An important part of this plumbing involves marshaling wrapped interface pointers across contexts.  When a COM interface pointer needs to be marshaled from one context to another, the CLR calls CoMarshalInterface in the original context to marshal the pointer to a stream.  If this succeeds, the interface pointer can be unmarshaled from the stream in the new context using CoUnmarshalInterface.  If the attempt to marshal the pointer to a stream fails, the CLR doesn’t give up; it simply goes against the COM protocol and uses the raw interface pointer in the new context.


Because this “interface smuggling” could cause undesirable behavior for the COM components in use, the goal of the Disconnected Context and Unmarshalable Interface probes is to warn you about this situation.  The reason that there are two probes is that there are two potential causes of failure in this scenario.


For performance reasons, marshaling an interface pointer to a stream is done “lazily” – the stream is only created if and when it’s necessary.  This is important for understanding the timing of the messages from these probes.  When an interface pointer without a corresponding stream requires unmarshaling, the CLR transitions to the original context, marshals the pointer to a stream, then returns to the original context.  In many cases, this is a one-time transition, but if the stream expires (typically after 12 minutes of inactivity), then the CLR will once again transition back to the original context to re-marshal the stream.


If these attempts to transition to the original context fail for any reason, the Disconnected Context probe emits the following warning:


  Failed to enter object context.  No proxy will be used.


If a context transition succeeds but the call to CoMarshalInterface fails, the Unmarshalable Interface probe emits the following warning:


  Component is not marshalable.  No proxy will be used.


For example, if the COM object whose interface pointer needs to be marshaled implements IMarshal, CoMarshalInterface invokes the methods of this IMarshal implementation.  The CLR is then at the mercy of the COM object to make the marshaling successful.

Comments (6)

  1. Sam Gentile says:

    When a COM interface pointer needs to be marshaled from one context to another, the CLR calls CoMarshalInterface in the original context to marshal the pointer to a stream. If this succeeds, the interface pointer can be unmarshaled from the stream in the new context using CoUnmarshalInterface.

    Is it CoMarshalInterface or CCoMarshalInterThreadInterfaceInStream? It would seem to be the latter to me

  2. Adam Nathan says:

    The CLR effectively calls CoMarshalInterThreadInterfaceInStream, doing the same kind of work that that API does, which involves calling CoMarshalInterface.

  3. Kevin Westhead says:

    Out of curiosity, where can I find more information on CDPs? There doesn’t appear to be any information on MSDN or in my "SDKv1.1Tool Developers Guidedocs" folder.

  4. Dmitriy Zaslavskiy says:

    "the CLR transitions to the original context, marshals the pointer to a stream, then returns to the original context."
    Adam could explain this again. Are you saying CLR will jump between threads just to get to the original context? Is it using some internal APIs for that? I though I new COM quite well, but I don’t understand what you mean here.
    Also how does CLR determine that it need to marshal? undoc stuff again?
    I have a problem that when I use explorer interfaces from a thread pool (which I assumed would be fine, since CLR/COM would take care of marshaling). And after about some time those interfaces will stop functionioning could you tell me what’s happening?

    Thank you very much for your book and blog.