2014-12-08 1 views
-2

시간이 지남에 따라 많은 메모리를 사용하는 ATL COM 서버에 문제가 있습니다. 메모리 누출을 의심하고 있지만 그 원인을 찾아 낼 수는 없습니다. 이 서비스는 48 시간 스트레스 테스트 동안 메모리를 천천히 추가합니다.시간이 지남에 따라 C++ COM 서버 메모리 사용량이 증가합니다 - WinDBG의 분석가

다음은 1 시간 후에 프로세스를 분석하여 WinDBG에서 수집 한 것입니다. 여기에 대부분의 메모리를 차지하는 객체를 배치합니다.

size  #blocks  total  (%) (percent of total busy bytes) 
190  6c3  - a90b0 (32.86) 
30   1507  - 3f150 (12.26) 

!heap -flt s 190 

!heap -p -a 0000000002ae0ee0 
address 0000000002ae0ee0 found in 
_HEAP @ 1a40000 
      HEAP_ENTRY Size Prev Flags   UserPtr UserSize - state 
    0000000002ae0eb0 001c 0000 [00] 0000000002ae0ee0 00190 - (busy) 
     combase!CStdIdentity::`vftable' 
    7ffd1aa71be7 ntdll!RtlAllocateHeap+0x000000000006fb17 
    7ffd18676158 combase!CIDObject::GetOrCreateStdID+0x0000000000000128 
    7ffd1867a788 combase!CDestObjectWrapper::MarshalInterface+0x00000000000006ca 
    7ffd186795c2 combase!CoMarshalInterface+0x00000000000001a2 
    7ffd1868145f combase!MarshalHelperMulti+0x000000000000006f 
    7ffd1868139f combase!GetInstanceHelperMulti+0x0000000000000083 
    7ffd18681129 combase!CObjServer::CreateInstance+0x0000000000000467 
    7ffd18b02385 RPCRT4!Invoke+0x0000000000000065 
    7ffd18b0ae16 RPCRT4!NdrStubCall2+0x000000000000038b 
    7ffd18b170eb RPCRT4!NdrStubCall3+0x000000000000014a 
    7ffd187a05ff combase!CStdStubBuffer_Invoke+0x0000000000000067 
    7ffd187a04d9 combase!SyncStubInvoke+0x0000000000000306 
    7ffd18633fc9 combase!CCtxComChnl::ContextInvoke+0x0000000000000279 
    7ffd187a13ff combase!AppInvoke+0x000000000000018f 
    7ffd187a0e9b combase!ComInvokeWithLockAndIPID+0x0000000000000661 
    7ffd187a184e combase!ThreadInvoke+0x0000000000000481 
    7ffd18b02614 RPCRT4!DispatchToStubInCNoAvrf+0x0000000000000014 
    7ffd18b02517 RPCRT4!RPC_INTERFACE::DispatchToStubWorker+0x0000000000000177 
    7ffd18b16ebf RPCRT4!LRPC_SCALL::DispatchRequest+0x0000000000000531 
    7ffd18b02cc1 RPCRT4!LRPC_SCALL::HandleRequest+0x0000000000000201 
    7ffd18b02a97 RPCRT4!LRPC_SASSOCIATION::HandleRequest+0x0000000000000237 
    7ffd18b01d04 RPCRT4!LRPC_ADDRESS::ProcessIO+0x000000000000036d 
    7ffd18b01afe RPCRT4!LrpcIoComplete+0x00000000000000ae 
    7ffd1a9fd394 ntdll!TppAlpcpExecuteCallback+0x0000000000000204 
    7ffd1a9fb96d ntdll!TppWorkerThread+0x00000000000003ad 
    7ffd184f15bd KERNEL32!BaseThreadInitThunk+0x000000000000000d 
    7ffd1aa343d1 ntdll!RtlUserThreadStart+0x000000000000001d 

!heap -flt s 30 
!heap -p -a 0000000002af5960 
address 0000000002af5960 found in 
_HEAP @ 1a40000 
      HEAP_ENTRY Size Prev Flags   UserPtr UserSize - state 
    0000000002af5930 0006 0000 [00] 0000000002af5960 00030 - (busy) 
    7ffd1aa71be7 ntdll!RtlAllocateHeap+0x000000000006fb17 
    7ffd1a9e0056 ntdll!RtlpAddDebugInfoToCriticalSection+0x0000000000000012 
    7ffd1aa79db4 ntdll!RtlInitializeCriticalSectionAndSpinCount+0x0000000000055dd4 
    7ffd18674b24 combase!CStdIdentity::CStdIdentity+0x00000000000002d4 
    7ffd1867618d combase!CIDObject::GetOrCreateStdID+0x000000000000015d 
    7ffd1867a788 combase!CDestObjectWrapper::MarshalInterface+0x00000000000006ca 
    7ffd186795c2 combase!CoMarshalInterface+0x00000000000001a2 
    7ffd1868145f combase!MarshalHelperMulti+0x000000000000006f 
    7ffd1868139f combase!GetInstanceHelperMulti+0x0000000000000083 
    7ffd18681129 combase!CObjServer::CreateInstance+0x0000000000000467 
    7ffd18b02385 RPCRT4!Invoke+0x0000000000000065 
    7ffd18b0ae16 RPCRT4!NdrStubCall2+0x000000000000038b 
    7ffd18b170eb RPCRT4!NdrStubCall3+0x000000000000014a 
    7ffd187a05ff combase!CStdStubBuffer_Invoke+0x0000000000000067 
    7ffd187a04d9 combase!SyncStubInvoke+0x0000000000000306 
    7ffd18633fc9 combase!CCtxComChnl::ContextInvoke+0x0000000000000279 
    7ffd187a13ff combase!AppInvoke+0x000000000000018f 
    7ffd187a0e9b combase!ComInvokeWithLockAndIPID+0x0000000000000661 
    7ffd187a184e combase!ThreadInvoke+0x0000000000000481 
    7ffd18b02614 RPCRT4!DispatchToStubInCNoAvrf+0x0000000000000014 
    7ffd18b02517 RPCRT4!RPC_INTERFACE::DispatchToStubWorker+0x0000000000000177 
    7ffd18b16ebf RPCRT4!LRPC_SCALL::DispatchRequest+0x0000000000000531 
    7ffd18b02cc1 RPCRT4!LRPC_SCALL::HandleRequest+0x0000000000000201 
    7ffd18b02a97 RPCRT4!LRPC_SASSOCIATION::HandleRequest+0x0000000000000237 
    7ffd18b01d04 RPCRT4!LRPC_ADDRESS::ProcessIO+0x000000000000036d 
    7ffd18b01afe RPCRT4!LrpcIoComplete+0x00000000000000ae 
    7ffd1a9fd394 ntdll!TppAlpcpExecuteCallback+0x0000000000000204 
    7ffd1a9fb96d ntdll!TppWorkerThread+0x00000000000003ad 
    7ffd184f15bd KERNEL32!BaseThreadInitThunk+0x000000000000000d 
    7ffd1aa343d1 ntdll!RtlUserThreadStart+0x000000000000001d 

다른 목적 :

size  #blocks  total  (%) (percent of total busy bytes) 
48  6c2  - 1e690 (91.91) 
1000  1  - 1000 (3.02) 

!heap -flt s 48 
!heap -p -a 0000000002ab8000 
address 0000000002ab8000 found in 
_HEAP @ 1a40000 
      HEAP_ENTRY Size Prev Flags   UserPtr UserSize - state 
    0000000002ab7fd0 0007 0000 [00] 0000000002ab8000 00048 - (busy) 
     combase!g_ForwardingVtbl 
    7ffd1aa71be7 ntdll!RtlAllocateHeap+0x000000000006fb17 
    7ffd18674115 combase!CreateStubFromTypeInfo+0x0000000000000061 
    7ffd18b58f63 RPCRT4!CreateStubFromTypeInfo+0x0000000000000043 
    7ffd1908dcf8 OLEAUT32!CUnivStubWrapper::Invoke+0x0000000000000098 
    7ffd187a04d9 combase!SyncStubInvoke+0x0000000000000306 
    7ffd18633fc9 combase!CCtxComChnl::ContextInvoke+0x0000000000000279 
    7ffd187a13ff combase!AppInvoke+0x000000000000018f 
    7ffd187a0e9b combase!ComInvokeWithLockAndIPID+0x0000000000000661 
    7ffd187a184e combase!ThreadInvoke+0x0000000000000481 
    7ffd18b02614 RPCRT4!DispatchToStubInCNoAvrf+0x0000000000000014 
    7ffd18b02517 RPCRT4!RPC_INTERFACE::DispatchToStubWorker+0x0000000000000177 
    7ffd18b16ebf RPCRT4!LRPC_SCALL::DispatchRequest+0x0000000000000531 
    7ffd18b02cc1 RPCRT4!LRPC_SCALL::HandleRequest+0x0000000000000201 
    7ffd18b02a97 RPCRT4!LRPC_SASSOCIATION::HandleRequest+0x0000000000000237 
    7ffd18b01d04 RPCRT4!LRPC_ADDRESS::ProcessIO+0x000000000000036d 
    7ffd18b01afe RPCRT4!LrpcIoComplete+0x00000000000000ae 
    7ffd1a9fd394 ntdll!TppAlpcpExecuteCallback+0x0000000000000204 
    7ffd1a9fb96d ntdll!TppWorkerThread+0x00000000000003ad 
    7ffd184f15bd KERNEL32!BaseThreadInitThunk+0x000000000000000d 
    7ffd1aa343d1 ntdll!RtlUserThreadStart+0x000000000000001d 

!heap -p -a 000000000282f280 
address 000000000282f280 found in 
_HEAP @ 20a0000 
      HEAP_ENTRY Size Prev Flags   UserPtr UserSize - state 
    000000000282f250 0007 0000 [00] 000000000282f280 00048 - (busy) 
     ccprovsp!ATL::CComObject<MyCOM>::`vftable' 
    7ffd1aa71be7 ntdll!RtlAllocateHeap+0x000000000006fb17 
    140028c87 ccprovsp!malloc+0x0000000000000067 
    14002815e ccprovsp!operator new+0x000000000000000e 
    14000280b ccprovsp!ATL::CComCreator<ATL::CComObject<MyCOM> >::CreateInstance+0x000000000000005b 
    14000239c ccprovsp!ATL::CComCreator2<ATL::CComCreator<ATL::CComObject<MyCOM> >,ATL::CComFailCreator<-2147221232> >::CreateInstance+0x000000000000002c 
    1400085a7 ccprovsp!ATL::CComClassFactory::CreateInstance+0x0000000000000077 
    7ffd1868134c combase!GetInstanceHelperMulti+0x0000000000000034 
    7ffd18681129 combase!CObjServer::CreateInstance+0x0000000000000467 
    7ffd18b02385 RPCRT4!Invoke+0x0000000000000065 
    7ffd18b0ae16 RPCRT4!NdrStubCall2+0x000000000000038b 
    7ffd18b170eb RPCRT4!NdrStubCall3+0x000000000000014a 
    7ffd187a05ff combase!CStdStubBuffer_Invoke+0x0000000000000067 
    7ffd187a04d9 combase!SyncStubInvoke+0x0000000000000306 
    7ffd18633fc9 combase!CCtxComChnl::ContextInvoke+0x0000000000000279 
    7ffd187a13ff combase!AppInvoke+0x000000000000018f 
    7ffd187a0e9b combase!ComInvokeWithLockAndIPID+0x0000000000000661 
    7ffd187a184e combase!ThreadInvoke+0x0000000000000481 
    7ffd18b02614 RPCRT4!DispatchToStubInCNoAvrf+0x0000000000000014 
    7ffd18b02517 RPCRT4!RPC_INTERFACE::DispatchToStubWorker+0x0000000000000177 
    7ffd18b16ebf RPCRT4!LRPC_SCALL::DispatchRequest+0x0000000000000531 
    7ffd18b02cc1 RPCRT4!LRPC_SCALL::HandleRequest+0x0000000000000201 
    7ffd18b02a97 RPCRT4!LRPC_SASSOCIATION::HandleRequest+0x0000000000000237 
    7ffd18b01d04 RPCRT4!LRPC_ADDRESS::ProcessIO+0x000000000000036d 
    7ffd18b01afe RPCRT4!LrpcIoComplete+0x00000000000000ae 
    7ffd1a9fd394 ntdll!TppAlpcpExecuteCallback+0x0000000000000204 
    7ffd1a9fb96d ntdll!TppWorkerThread+0x00000000000003ad 
    7ffd184f15bd KERNEL32!BaseThreadInitThunk+0x000000000000000d 
    7ffd1aa343d1 ntdll!RtlUserThreadStart+0x000000000000001d 

내가 다음에 무엇을해야 하는가에 대한 어떤 힌트?

+0

COM의 개체 수명주기 관리는 참조 횟수를 기반으로합니다. 호출 스택을 기반으로 누수가 발생한 원인을 알기는 정말 어렵습니다. Windbg 대신 debugdiag 시도 – Matt

답변

0

우선, 메모리 할당을 추적하기 위해 GFlags를 올바르게 설정 한 것으로 보입니다. 이는 좋은 일이며 문제를 찾는 데 확실히 도움이 될 것입니다. 그러나 게시 된 객체는 현재 사용 중이 아닌지 여부를 알 수 없기 때문에 무의미합니다.

WinDbg에서 분석을하는 것은 상당히 어려우며 많은 수작업이 필요합니다. 다행히도 그러한 시나리오에서 도움이 될 UMDH (MSDN)이 있습니다. (1 시간 괜찮 600 킬로바이트)를 사용하면 비교적 짧은 시간에 문제를 재현 할 수 있기 때문에

을 진행하는 방법

은, 그렇게. 반복적으로 응용 프로그램에서 동일한 상태에 도달하고 모든 메모리가 다시 해제되어야하는 시나리오를 만듭니다. 1 시간이 넘으면 항상 상태에 도달하면 UMDH 스냅 샷을 만듭니다. 나중에 로그 파일을 분석하십시오 (이 방법을 "모드 2"라고 함).

UMDH는 모든 메모리 할당을 호출 스택별로 정렬합니다. 시간 경과에 따른 할당 그래프를 그릴 수 있다면 Excel에서는 한 줄이 떠오르는 것을 볼 수 있습니다. 그것은 잠재적으로 범인입니다. 그런 그래프를 생성하기 위해 HeapProfiler을 시도해 볼 수 있습니다 (불행히도 이번에 출시 될 준비가되지 않은 그래프를 작성하기위한 자체 도구가 있기 때문에 전에 사용하지 않았습니다).

잃어버린 개체의 유형을 알면 호출 스택에서 할당 된 위치를 알 수 있습니다. 그런 다음 코드 검토를 수행하고 코드 검토가 필요한 곳을 찾습니다. 왜 그것이 공개되지 않는지 알아 내려고 노력하십시오 (그리고 그것은 정말로 어려운 부분입니다).

타릭 Soulami에 의해 추가 읽기

Inside Windows Debugging (Amazaon)는 장에서 UMDH를 포함 8

또한 읽거나 예를 들어, 일부 온라인 자습서, 청취 할 수 있습니다

Using UMDH to Find a User-Mode Memory Leak 또는 Finding Memory Leaks with UMDH