views:

60

answers:

2

I'm a complete WinDbg newbie and I've been trying to debug a WindowsXP problem that a customer has sent me where our software and some third party software prevent windows from logging off. I've reproduced the problem and have verified that only when our software and the customers software are both installed (although not necessarily running at logoff) does the log off problem occur. I've observed that WM_ENDSESSION messages are not reaching the running windows when the user tries to log off and I know that the third party software uses a kernel driver.

I've been looking at the processes in WinDbg and I know that csrss.exe would normally send all the windows a WM_ENDSESSION message. When I ran:

!process 82356020 6

To look at csrss.exe's stack I can see:

WARNING: Frame IP not in any known module. Following frames may be wrong.
        00000000 00000000 00000000 00000000 00000000 0x7c90e514

        THREAD 8246d998  Cid 0248.02a0  Teb: 7ffd7000 Win32Thread: e1627008 WAIT: (WrUserRequest) UserMode Non-Alertable
            8243d9f0  SynchronizationEvent
            81fe0390  SynchronizationEvent
        Not impersonating
        DeviceMap                 e1004450
        Owning Process            82356020       Image:         csrss.exe
        Attached Process          N/A            Image:         N/A
        Wait Start TickCount      1813           Ticks: 20748 (0:00:05:24.187)
        Context Switch Count      3                 LargeStack
        UserTime                  00:00:00.000
        KernelTime                00:00:00.000
        Start Address 0x75b67cdf
        Stack Init f80bd000 Current f80bc9c8 Base f80bd000 Limit f80ba000 Call 0
        Priority 14 BasePriority 13 PriorityDecrement 0 DecrementCount 0
        Kernel stack not resident.
        ChildEBP RetAddr  Args to Child              
        f80bc9e0 80500ce6 00000000 8246d998 804f9af2 nt!KiSwapContext+0x2e (FPO: [Uses EBP] [0,0,4])
        f80bc9ec 804f9af2 804f986e e1627008 00000000 nt!KiSwapThread+0x46 (FPO: [0,0,0])
        f80bca24 bf80a4a3 00000002 82475218 00000001 nt!KeWaitForMultipleObjects+0x284 (FPO: [Non-Fpo])
        f80bca5c bf88c0a6 00000001 82475218 00000000 win32k!xxxMsgWaitForMultipleObjects+0xb0 (FPO: [Non-Fpo])
        f80bcd30 bf87507d bf9ac0a0 00000001 f80bcd54 win32k!xxxDesktopThread+0x339 (FPO: [Non-Fpo])
        f80bcd40 bf8010fd bf9ac0a0 f80bcd64 00bcfff4 win32k!xxxCreateSystemThreads+0x6a (FPO: [Non-Fpo])
        f80bcd54 8053d648 00000000 00000022 00000000 win32k!NtUserCallOneParam+0x23 (FPO: [Non-Fpo])
        f80bcd54 7c90e514 00000000 00000022 00000000 nt!KiFastCallEntry+0xf8 (FPO: [0,0] TrapFrame @ f80bcd64)

This waitForMultipleObjects looks interesting because I'm wondering if csrss.exe is waiting on some event which isn't arriving to allow the logoff. Can anyone tell me how I might find out what event it's waiting for anything else I might do to further investigate the problem?

+2  A: 

Hi there.

To start off, try !object 82475218 to see if that tells you what the object is.

If that fails to help, try this:

http://blogs.msdn.com/search/SearchResults.aspx?q=KeWaitForMultipleObjects

It's a search for KeWaitForMultipleObjects on the NT Debugging Blog, which is a great blog in for learning about Windows internals.

EDIT:

Here's the documentation for KeWaitForMultipleObjects:

http://msdn.microsoft.com/en-us/library/ff553324.aspx Cheers. Jas.

Jason Evans
Hmm, I see you got that from the arguments to KeWaitForMultipleObjects (cheers for that!). How come it only shows the first 3 arguments passed to the function? Can you get the others somehow?
Benj
I think you will need the `dd` command. Check out this page: http://windbg.info/doc/1-common-cmds.html there is a section about getting more then 3 arguments using the `dd` command. Sorry I can't give an example.
Jason Evans
Thanks I managed to figure it out: I just selected the right frame:.frame 3Then I examined the stack pointer with dd like you said:dd espThat showed me all the parameters
Benj
Awesome :) Love it when a plan comes together (Erm, I was a bit too cheesy there perhaps? :)
Jason Evans
A-Team quotes never qualify as cheese ;-)
Benj
+3  A: 

The objects being waited on are right there in the output:

    THREAD 8246d998  Cid 0248.02a0  Teb: 7ffd7000 Win32Thread: e1627008 WAIT: (WrUserRequest) UserMode Non-Alertable  
        8243d9f0  SynchronizationEvent  
        81fe0390  SynchronizationEvent  

I'll note though that the thread you're looking at is a common thread, just about every system that you look at will have it (not sure what that thread is for exactly, but I recognize the stack...Sometimes I feel like I've been doing this too long!).

I'll also note that you can't trust the parameters on the stack all of the time. See some details here: http://analyze-v.com/?p=7

-scott

snoone
Thanks! I should have spotted this really. Any idea why when I !object the first address I get:8243d9f0: Not a valid object (ObjectType.Name at 0x3d003c00 invalid)But when I !object the second one I get:kd> !object 81fe0390Object: 81fe0390 Type: (825c7708) Event ObjectHeader: 81fe0378 (old version) HandleCount: 1 PointerCount: 2
Benj
In the O/S, there's a base native type called the kernel event (KEVENT). This isn't much more than a signal state and list of threads waiting on the event.Leveraging the kernel event, the O/S also provides an event object. This is a KEVENT with a header slapped on that allows you to do things like give the event a name so that people can open it (this also provides a means for tracking the number of handles to the event, the reference count, etc).!object doesn't work on simple kernel events because there's no header, it only works on full event objects.Out of space :)-scott
snoone