diff --git a/dll/win32/shell32/precomp.h b/dll/win32/shell32/precomp.h index 98fc09cb37b..f56bf9cd8f8 100644 --- a/dll/win32/shell32/precomp.h +++ b/dll/win32/shell32/precomp.h @@ -143,6 +143,8 @@ AddPropSheetPageCallback(HPROPSHEETPAGE hPage, LPARAM lParam) return FALSE; } +#define SHAlloc CoTaskMemAlloc + HRESULT SHELL32_ShowPropertiesDialog(IDataObject *pdtobj); HRESULT diff --git a/dll/win32/shell32/wine/shell32_main.h b/dll/win32/shell32/wine/shell32_main.h index db03e2ad794..1de9f829b2f 100644 --- a/dll/win32/shell32/wine/shell32_main.h +++ b/dll/win32/shell32/wine/shell32_main.h @@ -204,6 +204,8 @@ LPWSTR SH_FormatFileSizeWithBytes(PULARGE_INTEGER lpQwSize, LPWSTR pszBuf, UINT HRESULT WINAPI DoRegisterServer(void); HRESULT WINAPI DoUnregisterServer(void); +#define SHAlloc CoTaskMemAlloc + #ifdef __cplusplus } /* extern "C" */ #endif diff --git a/dll/win32/shell32/wine/shellole.c b/dll/win32/shell32/wine/shellole.c index 6ede109f92e..530baf6cb56 100644 --- a/dll/win32/shell32/wine/shellole.c +++ b/dll/win32/shell32/wine/shellole.c @@ -301,6 +301,7 @@ HRESULT WINAPI SHGetMalloc(LPMALLOC *lpmal) * SEE ALSO * CoTaskMemAlloc, SHLoadOLE */ +#undef SHAlloc LPVOID WINAPI SHAlloc(SIZE_T len) { LPVOID ret; @@ -309,6 +310,7 @@ LPVOID WINAPI SHAlloc(SIZE_T len) TRACE("%u bytes at %p\n",len, ret); return ret; } +#define SHAlloc CoTaskMemAlloc /************************************************************************* * SHFree [SHELL32.195] diff --git a/sdk/lib/rtl/heap.c b/sdk/lib/rtl/heap.c index 781c2276c49..c2662de5e8e 100644 --- a/sdk/lib/rtl/heap.c +++ b/sdk/lib/rtl/heap.c @@ -2046,7 +2046,7 @@ RtlpAllocateNonDedicated(PHEAP Heap, * @implemented */ PVOID NTAPI -RtlAllocateHeap(IN PVOID HeapPtr, +RtlAllocateHeap2(IN PVOID HeapPtr, IN ULONG Flags, IN SIZE_T Size) { @@ -2264,7 +2264,7 @@ RtlAllocateHeap(IN PVOID HeapPtr, * * @implemented */ -BOOLEAN NTAPI RtlFreeHeap( +BOOLEAN NTAPI RtlFreeHeap2( HANDLE HeapPtr, /* [in] Handle of heap */ ULONG Flags, /* [in] Heap freeing flags */ PVOID Ptr /* [in] Address of memory to free */ @@ -2388,6 +2388,179 @@ BOOLEAN NTAPI RtlFreeHeap( return TRUE; } +#define NUM_FRAMES 6 +struct +{ + PVOID Ptr; + ULONG BacktraceHash; +} HeapAllocations[8192]; +LONG HeapAllocationHint; +struct +{ + ULONG BacktraceHash; + PVOID Backtrace[NUM_FRAMES]; + LONG Count; +} HeapCallers[16384]; + +VOID +DumpTopCallers(VOID) +{ +#define N_MAX 5 + ULONG Index; + LONG MaxCount[N_MAX] = { 0 }; + ULONG MaxIndex[N_MAX] = { 0 }; + ULONG iMax; + static LARGE_INTEGER LastDumpTime = { { 0 } }; + LARGE_INTEGER CurrentTime; + + NtQuerySystemTime(&CurrentTime); + if (CurrentTime.QuadPart - LastDumpTime.QuadPart < 2000000) // Divided by 10 + { + return; + } + LastDumpTime = CurrentTime; + + for (Index = 0; Index < RTL_NUMBER_OF(HeapCallers); Index++) + { + for (iMax = 0; iMax < N_MAX; iMax++) + { + if (HeapCallers[Index].Count > MaxCount[iMax]) + { + if (iMax < N_MAX - 1) + { + MoveMemory(&MaxIndex[iMax + 1], + &MaxIndex[iMax], + (N_MAX - iMax - 1) * sizeof(MaxIndex[0])); + MoveMemory(&MaxCount[iMax + 1], + &MaxCount[iMax], + (N_MAX - iMax - 1) * sizeof(MaxCount[0])); + } + MaxIndex[iMax] = Index; + MaxCount[iMax] = HeapCallers[Index].Count; + break; + } + } + } + + for (iMax = 0; iMax < N_MAX; iMax++) + { + DPRINT1("[%wZ] Top %lu caller with %ld allocations is %p %p %p %p %p %p\n", + &NtCurrentPeb()->ProcessParameters->ImagePathName, iMax + 1, MaxCount[iMax], + HeapCallers[MaxIndex[iMax]].Backtrace[0], HeapCallers[MaxIndex[iMax]].Backtrace[1], + HeapCallers[MaxIndex[iMax]].Backtrace[2], HeapCallers[MaxIndex[iMax]].Backtrace[3], + HeapCallers[MaxIndex[iMax]].Backtrace[4], HeapCallers[MaxIndex[iMax]].Backtrace[5]); + } +} + +PVOID NTAPI +RtlAllocateHeap( + _In_ PVOID HeapPtr, + _In_ ULONG Flags, + _In_ SIZE_T Size) +{ + LONG Index; + ULONG Iterations = 0; + PVOID Ptr; + PVOID Backtrace[NUM_FRAMES]; + ULONG Hash = 0; + LONG Value; + + Ptr = RtlAllocateHeap2(HeapPtr, Flags, Size); + if (Ptr == NULL) + { + return Ptr; + } + + while (Iterations++ < RTL_NUMBER_OF(HeapAllocations)) + { + Index = (InterlockedIncrement(&HeapAllocationHint) - 1) % RTL_NUMBER_OF(HeapAllocations); + if (Index == RTL_NUMBER_OF(HeapAllocations) - 1) + { + DumpTopCallers(); + } + if (InterlockedCompareExchangePointer(&HeapAllocations[Index].Ptr, Ptr, NULL) == NULL) + { + RtlCaptureStackBackTrace(1, NUM_FRAMES, Backtrace, &Hash); + HeapAllocations[Index].BacktraceHash = Hash; + break; + } + } + if (Hash == 0) + { + //ASSERT(Hash != 0); + return Ptr; + } + for (Index = 0; Index < RTL_NUMBER_OF(HeapCallers); Index++) + { + if (HeapCallers[Index].BacktraceHash == Hash) + { + Value = InterlockedIncrement(&HeapCallers[Index].Count); + ASSERT(Value > 0); + break; + } + if (HeapCallers[Index].BacktraceHash == 0) + { + if (InterlockedCompareExchange((PLONG)&HeapCallers[Index].BacktraceHash, Hash, 0) == 0) + { + Value = InterlockedIncrement(&HeapCallers[Index].Count); + ASSERT(Value > 0); + RtlCopyMemory(HeapCallers[Index].Backtrace, + Backtrace, + sizeof(Backtrace)); + break; + } + else + { + Index--; + } + } + } + ASSERT(Index != RTL_NUMBER_OF(HeapCallers)); + return Ptr; +} + +BOOLEAN NTAPI RtlFreeHeap( + _In_ HANDLE HeapPtr, + _In_ ULONG Flags, + _In_ PVOID Ptr) +{ + LONG Index; + BOOLEAN Ret; + ULONG Hash = 0; + LONG Value; + + for (Index = 0; Index < RTL_NUMBER_OF(HeapAllocations); Index++) + { + if (HeapAllocations[Index].Ptr == Ptr) + { + Hash = HeapAllocations[Index].BacktraceHash; + HeapAllocations[Index].BacktraceHash = 0; + if (InterlockedExchangePointer(&HeapAllocations[Index].Ptr, NULL) != Ptr) + { + ASSERT(FALSE); + } + break; + } + } + //ASSERT(Hash != 0); + if (Hash != 0) + { + for (Index = 0; Index < RTL_NUMBER_OF(HeapCallers); Index++) + { + if (HeapCallers[Index].BacktraceHash == Hash) + { + Value = InterlockedDecrement(&HeapCallers[Index].Count); + ASSERT(Value >= 0); + break; + } + } + ASSERT(Index != RTL_NUMBER_OF(HeapCallers)); + } + Ret = RtlFreeHeap2(HeapPtr, Flags, Ptr); + return Ret; +} + + BOOLEAN NTAPI RtlpGrowBlockInPlace (IN PHEAP Heap, IN ULONG Flags,