Identifying the Caller From the Server Thread

It is possible to determine what made a given RPC call, even if the only information you have is the server thread that serviced the call.

This can be very useful -- for example, to find out who passed invalid parameters to an RPC call.

Depending on which protocol sequence is used by this particular call, you can get varying degrees of detail. Some protocols (such as NetBios) do not have this information at all.

Identifying the caller from the server thread

  1. Start a user-mode debugger with the server thread as the target.

  2. Get the process ID by using the | (Process Status) command:

    0:001> |
      0     id: 3d4 name: rtsvr.exe
  3. Get the active calls in this process by using the !rpcexts.getcallinfo extension. (See the reference page for an explanation of the syntax.) You need to supply the process ID of 0x3D4:

    0:001> !rpcexts.getcallinfo 0 0 FFFF 3d4
    Searching for call info ...
    03d4 0000.0004 02 000 19bb5061 0000.0002 00000001 00000001 00a1aced 0000.0003

    Look for calls with status 02 or 01 (dispatched or active). In this example, the process only has one call. If there were more, you would have to use the !rpcexts.getdbgcell extension with the cell number in the THRDCELL column. This would allow you to examine the thread IDs so you could determine which call you were interested in.

  4. After you know which call you are interested in, look at the cell number in the CONN/CLN column. This is the cell ID of the connection object. In this case, the cell number is 0000.0003. Pass this cell number and the process ID to !rpcexts.getdbgcell:

    0:001> !rpcexts.getdbgcell 3d4 0.3
    Getting cell info ...
    Connection flags: Exclusive
    Authentication Level: Default
    Authentication Service: None
    Last Transmit Fragment Size: 24 (0x6F56D)
    Endpoint for the connection: 0x0.1
    Last send time (in seconds since boot):10595.565 (0x2963.235)
    Last receive time (in seconds since boot):10595.565 (0x2963.235)
    Getting endpoint info ...
    Process object for caller is 0xFF9DF5F0

This extension will display all the information available about the client of this connection. The amount of actual information will vary, depending on the transport being used.

In this example, local named pipes are being used as the transport and the process object address of the caller is displayed. If you attach a kernel debugger (or start a local kernel debugger), you can use the !process extension to interpret this process address.

If LRPC is used as the transport, the process ID and thread ID of the caller will be displayed.

If TCP is used as the transport, the IP address of the caller will be displayed.

If remote named pipes are used as the transport, no information will be available.

Note   The previous example shows how to find the client thread if you know the server thread. For an example of the reverse technique, see Analyzing a Stuck Call Problem.