Home COM GDI+ WebBrowser Data Access

IMallocSpy Interface

 

IID_IMallocSpy

{0000001D-0000-0000-C000-000000000046}

 

 

The IMallocSpy interface is a debugging interface that allows application developers to monitor (spy on) memory allocation, detect memory leaks, and simulate memory failure in calls to IMalloc methods.

When an implementation of IMallocSpy is registered with CoRegisterMallocSpy, COM calls the pair of IMallocSpy methods around the corresponding IMalloc method. You would not make direct calls to IMallocSpy methods. The COM SDK contains a sample implementation of IMallocSpy. The call to the pre-method through the return from the corresponding post-method is guaranteed to be thread-safe in multithreaded operations.

Caution: The IMallocSpy interface is intended only for use in debugging application code under development. Do not ship this interface to retail customers of your application because it causes severe performance degradation and could conflict with user-installed software to produce unpredictable results.

 

 

Methods in VTable order

IUnknown Methods

Description

QueryInterface

Returns pointers to supported interfaces.

AddRef

Increments reference count.

Release

Decrements reference count.

IMallocSpy Methods

Description

PreAlloc

Called before invoking IMalloc::Alloc, and may extend or modify the allocation to store debug information.

PostAlloc

Called after invoking IMalloc::Alloc.

PreFree

Called before invoking IMalloc::Free.

PostFree

Called after invoking IMalloc::Free.

PreRealloc

Called before invoking IMalloc::Realloc.

PostRealloc

Called after invoking IMalloc::Realloc.

PreGetSize

Called before invoking IMalloc::GetSize.

PostGetSize

Called after invoking IMalloc::GetSize.

PreDidAlloc

Called before invoking IMalloc::DidAlloc.

PostDidAlloc

Called after invoking IMalloc::DidAlloc.

PreHeapMinimize

Called before invoking IMalloc::HeapMinimize.

PostHeapMinimize

Called after invoking IMalloc::HeapMinimize.

 

 

This is an implementation of the IMallocSpy interface. Register it as follows:

 

LOCAL pMallocSpy AS DWORD

LOCAL IMallocSpyVt AS IMallocSpyVtbl

LOCAL hr AS LONG

 

IMallocSpy_BuildVtbl IMallocSpyVt
pMallocSpy = VARPTR(IMallocSpyVt)

hr = CoRegisterMallocSpy(pMallocSpy)

 

CoRegisterMallocSpy will call IMallocSpy_QueryInterface, that will return a static pointer to the virtual table, so we can use local variables in the above code. IMallocSpy_QueryInterface doesn't do a call to IMallocSpy_AddRef because there is not memory to free when IMallocSpy_Release will be called. To unregister the interface call CoRevokeMallocSpy.

 

 

' ****************************************************************************************
' IMallocSpy Vtable
' ****************************************************************************************

TYPE IMallocSpyVtbl
   ' IUnknown interface
   pQueryInterface   AS DWORD
   pAddRef           AS DWORD
   pRelease          AS DWORD
   ' IMallocSpyVtbl interface
   pPreAlloc         AS DWORD
   pPostAlloc        AS DWORD
   pPreFree          AS DWORD
   pPostFree         AS DWORD
   pPreRealloc       AS DWORD
   pPostRealloc      AS DWORD
   pPreGetSize       AS DWORD
   pPostGetSize      AS DWORD
   pPreDidAlloc      AS DWORD
   pPostDidAlloc     AS DWORD
   pPreHeapMinimize  AS DWORD
   pPostHeapMinimize AS DWORD
END TYPE
' ****************************************************************************************

' ****************************************************************************************
' Builds the IMallocSpy Virtual Table
' ****************************************************************************************

SUB IMallocSpy_BuildVtbl (Vt AS IMallocSpyVtbl)

   Vt.pQueryInterface   = CODEPTR(IMallocSpy_QueryInterface)
   Vt.pAddRef           = CODEPTR(IMallocSpy_AddRef)
   Vt.pRelease          = CODEPTR(IMallocSpy_Release)
   Vt.pPreAlloc         = CODEPTR(IMallocSpy_PreAlloc)
   Vt.pPostAlloc        = CODEPTR(IMallocSpy_PostAlloc)
   Vt.pPreFree          = CODEPTR(IMallocSpy_PreFree)
   Vt.pPostFree         = CODEPTR(IMallocSpy_PostFree)
   Vt.pPreRealloc       = CODEPTR(IMallocSpy_PreRealloc)
   Vt.pPostRealloc      = CODEPTR(IMallocSpy_PostRealloc)
   Vt.pPreGetSize       = CODEPTR(IMallocSpy_PreGetSize)
   Vt.pPostGetSize      = CODEPTR(IMallocSpy_PostGetSize)
   Vt.pPreDidAlloc      = CODEPTR(IMallocSpy_PreDidAlloc)
   Vt.pPostDidAlloc     = CODEPTR(IMallocSpy_PostDidAlloc)
   Vt.pPreHeapMinimize  = CODEPTR(IMallocSpy_PreHeapMinimize)
   Vt.pPostHeapMinimize = CODEPTR(IMallocSpy_PostHeapMinimize)

END SUB
' ****************************************************************************************

' ****************************************************************************************
' HRESULT QueryInterface([in] *GUID riid, [out] **VOID ppvObj)
' ****************************************************************************************

FUNCTION IMallocSpy_QueryInterface (BYVAL pthis AS DWORD PTR, BYREF riid AS GUID, BYREF ppvObj AS DWORD) AS LONG
   STATIC pConSink AS DWORD
   STATIC IMallocSpyVt AS IMallocSpyVtbl
   LOCAL IID_IMallocSpy AS GUID
   IID_IMallocSpy = GUID$("{0000001D-0000-0000-C000-000000000046}")
   IF riid <> IID_IMallocSpy THEN
      FUNCTION = &H80004002 ' %E_NOINTERFACE
      EXIT FUNCTION
   END IF
   IF ISFALSE pConSink THEN
      IMallocSpy_BuildVtbl IMallocSpyVt
      pConSink = VARPTR(IMallocSpyVt)
   END IF
   ppvObj = VARPTR(pConSink)
   FUNCTION = 0 ' %S_OK
END FUNCTION
' ****************************************************************************************

' ****************************************************************************************
' UI4 AddRef()
' ****************************************************************************************

FUNCTION IMallocSpy_AddRef (BYVAL pthis AS DWORD PTR) AS DWORD
   FUNCTION = 1
END FUNCTION
' ****************************************************************************************

' ****************************************************************************************

' UI4 Release()
' ****************************************************************************************

FUNCTION IMallocSpy_Release (BYVAL pthis AS DWORD PTR) AS DWORD
   FUNCTION = 1
END FUNCTION
' ****************************************************************************************

' ****************************************************************************************
' Called before invoking IMalloc::Alloc, and may extend or modify the allocation to store
' debug information.
' ****************************************************************************************

FUNCTION IMallocSpy_PreAlloc (BYVAL pthis AS DWORD PTR, BYVAL cbRequest AS DWORD) AS LONG
   ' Put your code here
END FUNCTION
' ****************************************************************************************

' ****************************************************************************************
' Called after invoking IMalloc::Alloc.
' ****************************************************************************************

FUNCTION IMallocSpy_PostAlloc (BYVAL pthis AS DWORD PTR, BYVAL pActual AS DWORD) AS LONG
   ' Put your code here
END FUNCTION
' ****************************************************************************************

' ****************************************************************************************
' Called before invoking IMalloc::Free.
' ****************************************************************************************

FUNCTION IMallocSpy_PreFree (BYVAL pthis AS DWORD PTR, BYVAL pRequest AS DWORD, BYVAL fSpyed AS LONG) AS LONG
   ' Put your code here
END FUNCTION
' ****************************************************************************************

' ****************************************************************************************
' Called after invoking IMalloc::Free.
' ****************************************************************************************

FUNCTION IMallocSpy_PostFree (BYVAL pthis AS DWORD PTR, BYVAL fSpyed AS LONG) AS LONG
   ' Put your code here
END FUNCTION
' ****************************************************************************************

' ****************************************************************************************
' Called before invoking IMalloc::Realloc.
' ****************************************************************************************

FUNCTION IMallocSpy_PreRealloc (BYVAL pthis AS DWORD PTR, BYVAL pRequest AS DWORD, BYVAL cbRequest AS DWORD, BYREF ppNewRequest AS DWORD, BYVAL fSpyed AS LONG) AS LONG
   ' Put your code here
END FUNCTION
' ****************************************************************************************

' ****************************************************************************************
' Called after invoking IMalloc::Realloc.
' ****************************************************************************************

FUNCTION IMallocSpy_PostRealloc (BYVAL pthis AS DWORD PTR, BYVAL pActual AS DWORD, BYVAL fSpyed AS LONG) AS LONG
   ' Put your code here
END FUNCTION
' ****************************************************************************************

' ****************************************************************************************
' Called before invoking IMalloc::GetSize.
' ****************************************************************************************

FUNCTION IMallocSpy_PreGetSize (BYVAL pthis AS DWORD PTR, BYVAL pRequest AS DWORD, BYVAL fSpyed AS LONG) AS LONG
   ' Put your code here
END FUNCTION
' ****************************************************************************************

' ****************************************************************************************
' Called after invoking IMalloc::GetSize.
' ****************************************************************************************

FUNCTION IMallocSpy_PostGetSize (BYVAL pthis AS DWORD PTR, BYVAL cbActual AS DWORD, BYVAL fSpyed AS LONG) AS LONG
   ' Put your code here
END FUNCTION
' ****************************************************************************************

' ****************************************************************************************
' Called before invoking IMalloc::DidAlloc.
' ****************************************************************************************

FUNCTION IMallocSpy_PreDidAlloc (BYVAL pthis AS DWORD PTR, BYVAL pRequest AS DWORD, BYVAL fSpyed AS LONG) AS LONG
   ' Put your code here
END FUNCTION
' ****************************************************************************************

' ****************************************************************************************
' Called after invoking IMalloc::DidAlloc.
' ****************************************************************************************

FUNCTION IMallocSpy_PostDidAlloc (BYVAL pthis AS DWORD PTR, BYVAL pRequest AS DWORD, BYVAL fSpyed AS LONG, BYVAL fActual AS LONG) AS LONG
   ' Put your code here
END FUNCTION
' ****************************************************************************************

' ****************************************************************************************
' Called before invoking IMalloc::HeapMinimize.
' ****************************************************************************************

SUB IMallocSpy_PreHeapMinimize (BYVAL pthis AS DWORD PTR)
   ' Put your code here
END SUB
' ****************************************************************************************

' ****************************************************************************************
' Called after invoking IMalloc::HeapMinimize.
' ****************************************************************************************

SUB IMallocSpy_PostHeapMinimize (BYVAL pthis AS DWORD PTR)
   ' Put your code here
END SUB
' ****************************************************************************************
 

 

Page last updated on Monday, 03 April 2006 20:23:20 +0200