Bootstrap

WinDBG查找C++句柄泄露

C++代码(频繁点击About按钮导致Mutex句柄泄露)

HANDLE _mutexHandle;

LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
    switch (message)
    {
    case WM_COMMAND:
        {
            int wmId = LOWORD(wParam);
            // 分析菜单选择:
            switch (wmId)
            {
            case IDM_ABOUT:
                _mutexHandle = CreateMutex(NULL, FALSE, L"abc");
                DialogBox(hInst, MAKEINTRESOURCE(IDD_ABOUTBOX), hWnd, About);
                break;
            case IDM_EXIT:
                DestroyWindow(hWnd);
                break;
            default:
                return DefWindowProc(hWnd, message, wParam, lParam);
            }
        }
        break;
    case WM_PAINT:
        {
            PAINTSTRUCT ps;
            HDC hdc = BeginPaint(hWnd, &ps);
            // TODO: 在此处添加使用 hdc 的任何绘图代码...
            EndPaint(hWnd, &ps);
        }
        break;
    case WM_DESTROY:
        PostQuitMessage(0);
        break;
    default:
        return DefWindowProc(hWnd, message, wParam, lParam);
    }
    return 0;
}

编译后生成exe程序,设置WinDBG的源码目录和pdb目录:

File-->Settings-->

 File-->Start debugging

选择目标exe文件启动进程,点击左上角Go按钮,让ui显式,点击Break按钮让进程暂停,在WinDBG的命令行输入:

!htrace -enable

!htrace -snapshot

点击WinDBG左上角的Go按钮继续执行,点击UI上的按钮造成泄露;

点击WinDBG左上角的Break按钮进入调试模式;

在命令行输入:

!htrace 或 !htrace -diff,查看句柄泄露信息:

0:006> !htrace -diff
Handle tracing information snapshot successfully taken.
0x1a new stack traces since the previous snapshot.
Ignoring handles that were already closed...
Outstanding handles opened since the previous snapshot:
--------------------------------------
Handle = 0x00000000000002c0 - OPEN
Thread ID = 0x000000000000172c, Process ID = 0x0000000000003d7c

0x00007ffac544eb64: ntdll!NtCreateMutant+0x0000000000000014
0x00007ffac2d38fa8: KERNELBASE!CreateMutexExW+0x0000000000000058
0x00007ff6436c6f00: CPPWindowsProject1!WndProc+0x00000000000000d0
0x00007ffac50cef5c: USER32!UserCallWinProcCheckWow+0x000000000000050c
0x00007ffac50ce684: USER32!DispatchMessageWorker+0x0000000000000494
0x00007ff6436c1d57: CPPWindowsProject1!wWinMain+0x0000000000000117
0x00007ff6436c2c62: CPPWindowsProject1!invoke_main+0x0000000000000032
0x00007ff6436c2b12: CPPWindowsProject1!__scrt_common_main_seh+0x0000000000000132
0x00007ff6436c29ce: CPPWindowsProject1!__scrt_common_main+0x000000000000000e
0x00007ff6436c2cfe: CPPWindowsProject1!wWinMainCRTStartup+0x000000000000000e
0x00007ffac37e7374: KERNEL32!BaseThreadInitThunk+0x0000000000000014
0x00007ffac53fcc91: ntdll!RtlUserThreadStart+0x0000000000000021
--------------------------------------
Handle = 0x00000000000002bc - OPEN
Thread ID = 0x000000000000172c, Process ID = 0x0000000000003d7c

0x00007ffac544eb64: ntdll!NtCreateMutant+0x0000000000000014
0x00007ffac2d38fa8: KERNELBASE!CreateMutexExW+0x0000000000000058
0x00007ff6436c6f00: CPPWindowsProject1!WndProc+0x00000000000000d0
0x00007ffac50cef5c: USER32!UserCallWinProcCheckWow+0x000000000000050c
0x00007ffac50ce684: USER32!DispatchMessageWorker+0x0000000000000494
0x00007ff6436c1d57: CPPWindowsProject1!wWinMain+0x0000000000000117
0x00007ff6436c2c62: CPPWindowsProject1!invoke_main+0x0000000000000032
0x00007ff6436c2b12: CPPWindowsProject1!__scrt_common_main_seh+0x0000000000000132
0x00007ff6436c29ce: CPPWindowsProject1!__scrt_common_main+0x000000000000000e
0x00007ff6436c2cfe: CPPWindowsProject1!wWinMainCRTStartup+0x000000000000000e
0x00007ffac37e7374: KERNEL32!BaseThreadInitThunk+0x0000000000000014
0x00007ffac53fcc91: ntdll!RtlUserThreadStart+0x0000000000000021
--------------------------------------
Handle = 0x00000000000002b8 - OPEN
Thread ID = 0x000000000000172c, Process ID = 0x0000000000003d7c

0x00007ffac5450d84: ntdll!NtTraceControl+0x0000000000000014
0x00007ffac53f2f86: ntdll!EtwpRegisterProvider+0x00000000000000ba
0x00007ffac53f30e5: ntdll!EtwNotificationRegister+0x00000000000000a5
0x00007ffac53f2ea0: ntdll!EtwEventRegister+0x0000000000000020
0x00007ffac36ec5ef: MSCTF!TraceLoggingRegisterEx_EventRegister_EventSetInformation+0x0000000000000053
0x00007ffac36ec579: MSCTF!wil::TraceLoggingProvider::Register+0x0000000000000019
0x00007ffac36e46b4: MSCTF!wil::details::static_lazy<CtfTraceLoggingTelemetry>::get+0x0000000000000094
0x00007ffac36e460c: MSCTF!CtfTraceLoggingTelemetry::IsEnabled+0x0000000000000010
0x00007ffac36e42ac: MSCTF!CtfTraceLoggingTelemetry::InputSessionStarted<unsigned short (&)[41],unsigned long &,_GUID &,_GUID &,unsigned short &,bool &,unsigned long &,unsigned long &,unsigned long &,bool &,unsigned long,bool &>+0x0000000000000034
0x00007ffac36e40b8: MSCTF!CInputSessionMgr::UpdateInputSession+0x0000000000000338
0x00007ffac36f378b: MSCTF!SYSTHREAD::RouteKeyToInputService+0x0000000000000103
0x00007ffac36f33f1: MSCTF!SYSTHREAD::OnKeyboardEvent+0x00000000000000d1
--------------------------------------
Handle = 0x00000000000002b4 - OPEN
Thread ID = 0x000000000000172c, Process ID = 0x0000000000003d7c

0x00007ffac5450d84: ntdll!NtTraceControl+0x0000000000000014
0x00007ffac53f2f86: ntdll!EtwpRegisterProvider+0x00000000000000ba
0x00007ffac53f30e5: ntdll!EtwNotificationRegister+0x00000000000000a5
0x00007ffac53f2ea0: ntdll!EtwEventRegister+0x0000000000000020
0x00007ffac46f261f: ole32!InitializeTracing+0x000000000000016f
0x00007ffac4709727: ole32!DllMain+0x0000000000000033
0x00007ffac470650f: ole32!dllmain_dispatch+0x000000000000008f
0x00007ffac53c9a1d: ntdll!LdrpCallInitRoutine+0x0000000000000061
0x00007ffac541d2f7: ntdll!LdrpInitializeNode+0x00000000000001d3
0x00007ffac541d08a: ntdll!LdrpInitializeGraphRecurse+0x0000000000000042
0x00007ffac53ed947: ntdll!LdrpPrepareModuleForExecution+0x00000000000000bf
0x00007ffac53cfbae: ntdll!LdrpLoadDllInternal+0x000000000000019a
--------------------------------------
Handle = 0x00000000000002b0 - OPEN
Thread ID = 0x000000000000172c, Process ID = 0x0000000000003d7c

0x00007ffac5450d84: ntdll!NtTraceControl+0x0000000000000014
0x00007ffac53f2f86: ntdll!EtwpRegisterProvider+0x00000000000000ba
0x00007ffac53f30e5: ntdll!EtwNotificationRegister+0x00000000000000a5
0x00007ffac53f2ea0: ntdll!EtwEventRegister+0x0000000000000020
0x00007ffac46f25b3: ole32!InitializeTracing+0x0000000000000103
0x00007ffac4709727: ole32!DllMain+0x0000000000000033
0x00007ffac470650f: ole32!dllmain_dispatch+0x000000000000008f
0x00007ffac53c9a1d: ntdll!LdrpCallInitRoutine+0x0000000000000061
0x00007ffac541d2f7: ntdll!LdrpInitializeNode+0x00000000000001d3
0x00007ffac541d08a: ntdll!LdrpInitializeGraphRecurse+0x0000000000000042
0x00007ffac53ed947: ntdll!LdrpPrepareModuleForExecution+0x00000000000000bf
0x00007ffac53cfbae: ntdll!LdrpLoadDllInternal+0x000000000000019a
--------------------------------------
Handle = 0x00000000000002ac - OPEN
Thread ID = 0x000000000000172c, Process ID = 0x0000000000003d7c

0x00007ffac5450d84: ntdll!NtTraceControl+0x0000000000000014
0x00007ffac53f2f86: ntdll!EtwpRegisterProvider+0x00000000000000ba
0x00007ffac53f30e5: ntdll!EtwNotificationRegister+0x00000000000000a5
0x00007ffac53f2aaa: ntdll!EtwRegisterTraceGuidsW+0x000000000000009a
0x00007ffac46f2564: ole32!InitializeTracing+0x00000000000000b4
0x00007ffac4709727: ole32!DllMain+0x0000000000000033
0x00007ffac470650f: ole32!dllmain_dispatch+0x000000000000008f
0x00007ffac53c9a1d: ntdll!LdrpCallInitRoutine+0x0000000000000061
0x00007ffac541d2f7: ntdll!LdrpInitializeNode+0x00000000000001d3
0x00007ffac541d08a: ntdll!LdrpInitializeGraphRecurse+0x0000000000000042
0x00007ffac53ed947: ntdll!LdrpPrepareModuleForExecution+0x00000000000000bf
0x00007ffac53cfbae: ntdll!LdrpLoadDllInternal+0x000000000000019a
--------------------------------------
Handle = 0x0000000000000298 - OPEN
Thread ID = 0x000000000000388c, Process ID = 0x0000000000003d7c

0x00007ffac544dc74: ntdll!NtDuplicateObject+0x0000000000000014
0x00007ffac2d6b37c: KERNELBASE!DuplicateHandle+0x000000000000004c
0x00007ffac35b0e03: RPCRT4!THREAD::THREAD+0x0000000000000087
0x00007ffac35b0d58: RPCRT4!ThreadSelfHelper+0x0000000000000028
0x00007ffac35c5850: RPCRT4!RpcpSetThreadpoolCallbackInstance+0x0000000000000050
0x00007ffac35d1343: RPCRT4!PerformGarbageCollection+0x0000000000000023
0x00007ffac5422719: ntdll!TppTimerpExecuteCallback+0x00000000000000a9
0x00007ffac53fd79a: ntdll!TppWorkerThread+0x000000000000068a
0x00007ffac37e7374: KERNEL32!BaseThreadInitThunk+0x0000000000000014
0x00007ffac53fcc91: ntdll!RtlUserThreadStart+0x0000000000000021
--------------------------------------
Handle = 0x0000000000000294 - OPEN
Thread ID = 0x000000000000388c, Process ID = 0x0000000000003d7c

0x00007ffac544ddf4: ntdll!NtCreateEvent+0x0000000000000014
0x00007ffac2d66dfb: KERNELBASE!CreateEventW+0x000000000000006b
0x00007ffac35b2bc5: RPCRT4!EVENT::EVENT+0x000000000000002d
0x00007ffac35b0da6: RPCRT4!THREAD::THREAD+0x000000000000002a
0x00007ffac35b0d58: RPCRT4!ThreadSelfHelper+0x0000000000000028
0x00007ffac35c5850: RPCRT4!RpcpSetThreadpoolCallbackInstance+0x0000000000000050
0x00007ffac35d1343: RPCRT4!PerformGarbageCollection+0x0000000000000023
0x00007ffac5422719: ntdll!TppTimerpExecuteCallback+0x00000000000000a9
0x00007ffac53fd79a: ntdll!TppWorkerThread+0x000000000000068a
0x00007ffac37e7374: KERNEL32!BaseThreadInitThunk+0x0000000000000014
0x00007ffac53fcc91: ntdll!RtlUserThreadStart+0x0000000000000021
--------------------------------------
Handle = 0x0000000000000280 - OPEN
Thread ID = 0x000000000000172c, Process ID = 0x0000000000003d7c

0x00007ffac544eb64: ntdll!NtCreateMutant+0x0000000000000014
0x00007ffac2d38fa8: KERNELBASE!CreateMutexExW+0x0000000000000058
0x00007ff6436c6f00: CPPWindowsProject1!WndProc+0x00000000000000d0
0x00007ffac50cef5c: USER32!UserCallWinProcCheckWow+0x000000000000050c
0x00007ffac50ce684: USER32!DispatchMessageWorker+0x0000000000000494
0x00007ff6436c1d57: CPPWindowsProject1!wWinMain+0x0000000000000117
0x00007ff6436c2c62: CPPWindowsProject1!invoke_main+0x0000000000000032
0x00007ff6436c2b12: CPPWindowsProject1!__scrt_common_main_seh+0x0000000000000132
0x00007ff6436c29ce: CPPWindowsProject1!__scrt_common_main+0x000000000000000e
0x00007ff6436c2cfe: CPPWindowsProject1!wWinMainCRTStartup+0x000000000000000e
0x00007ffac37e7374: KERNEL32!BaseThreadInitThunk+0x0000000000000014
0x00007ffac53fcc91: ntdll!RtlUserThreadStart+0x0000000000000021
--------------------------------------
Displayed 0x9 stack traces for outstanding handles opened since the previous snapshot.

代码中构造的mutex泄露,查找!htrace -diff输出内容,找到CPPWindowsProject1!WndProc+0x00000000000000d0

使用lsa CPPWindowsProject1!WndProc+0x00000000000000d0查看代码,如下:

   143:             {
   144:             case IDM_ABOUT:
   145:                 //_condition_variable = new std::condition_variable();
   146:                 //_mutex = new std::mutex();
>  147:                 _mutexHandle = CreateMutex(NULL, FALSE, L"abc");
   148:                 DialogBox(hInst, MAKEINTRESOURCE(IDD_ABOUTBOX), hWnd, About);
   149:                 break;
   150:             case IDM_EXIT:
   151:                 DestroyWindow(hWnd);
   152:                 break;

找到147行的代码位置。

windbg的lsa指令:显式指令对应的源码 

;