Platform SDK: MAPI |
The entries in this section control debugging features in the MAPI memory allocator.
Anyone using the Microsoft RPC libraries who needs to use virtual allocation flags should set the VirtualMemory entry to 4 in both the [General] and [Memory Management] sections of MAPIDBG.INI. This includes anyone using EMSMDB.DLL or EMSABP.DLL. Microsoft RPC requires memory allocators to align memory at least as well as the operating system's allocator. The MAPI Virtual Memory allocator aligns on 4-byte boundaries when set to 4. Setting VirtualMemory to 1 does not do this in order to catch even single-byte overwrites immediately.
Enabling virtual allocation increases the MAPI subsystem's demand for system resources. On Win32, MAPI uses 64K of virtual address space for each allocation. On Win16, MAPI uses the GlobalAlloc function for each allocation, so it is possible to run out of selectors. Depending on the overall load your test scenario places on the system, you may need to narrow down the scenario enough to reproduce the problem without running out of system resources.
Clients and service providers can trace memory leaks by setting the DumpLeaks entry in the [Memory Management] section to 1, MAPI produces debug trace output for each leaked block of memory. For each leaked block, MAPI lists:
One technique for turning the stack traceback into a usable symbolic trace is to save the debug output to a text file, get your application back into the WINDBG debugger in a steady state, and convert the hexadecimal numbers to symbols using the 'list near' command. This command prints the nearest symbols before and after a given address. It is helpful to use a macro in your preferred editor to convert the MAPI trace, which looks like this:
Memory leak 'Proxy/Stub Object' in MAPIX Internal Heap @ 004E0770, Allocation #18, Size: 48 [0] 6C4C3B2F [1] 6C4C401D [2] 77CF7AB7 [3] 77D30E30 [4] 77CC9076
into a string of "list near" commands that looks like this (it gives you the closest symbol before and after the address):
> ln 6C4C3B2F; ln 6C4C401D; ln 77CF7AB7; ln 77D30E30; ln 77CC9076
When run in the WINDBG command window, this string produces a list of symbols like the following (there are two symbols for each address, the first is almost always the one you want):
MAPI32!operator new(unsigned int)+0x2f MAPI32!operator delete(void *)-0x31 MAPI32!StdPSFactory::CreateProxy(IUnknown *, const _GUID &, IRpcProxyBuffer * *, void * *)+0xbd MAPI32!StdPSFactory::CreateStub(const _GUID &, IUnknown *, IRpcStubBuffer * *)-0xe3 OLE32!?CreateInterfaceProxy@CRemoteHdlr@@AAEPAVCPSIX@@ABU_GUID@@PAPAXPAJ@Z+0x7d OLE32!?CreateInterfaceStub@CRemoteHdlr@@AAEPAVCPSIX@@ABU_GUID@@PAJ@Z-0xc1 OLE32!_IEnumUnknown_RemoteNext_Proxy@16+0xf OLE32!_IEnumUnknown_RemoteNext_Thunk@4-0x6 OLE32!?AddRef@CRemoteHdlr@@UAGKXZ+0 OLE32!?GetRH@CStdIdentity@@AAEPAUIRemoteHdlr@@XZ-0x11
MAPI does not expose an API to trigger an allocation dump.
It is most efficient to address memory leaks as they occur instead of waiting until there is a large number.