|
SmartHeap's Automatic DLL Patching
Only the SmartHeap DLL does any patching of DLLs. If your app is statically linked to SmartHeap, SmartHeap will not do any patching.
From the SmartHeap Getting Started guide:
"When you link with the DLL version of SmartHeap, SmartHeap automatically patches heap routines in compiler DLLs, such as the C runtime and MFC DLLs. If you're using MFC, OWL, or other DLLs that share heap memory with their client EXE, this patching is required to ensure that objects allocated in these DLLs can be safely freed by your application's EXE.
SmartHeap "patching" does not affect the on-disk copy of any DLLs, and it does not affect other applications that use the DLLs that SmartHeap patches. SmartHeap modifies only the in-memory copy of the DLL that is private to your application's process. Runtime SmartHeap patches only those DLLs in your process that export heap APIs such as malloc or new. Debug SmartHeap also patches all DLLs that have PDB debug information and that contain statically linked heap API definitions."
SmartHeap patches all DLLs present in the process into which the SmartHeap DLL is loaded, including dynamically-loaded DLLs that were loaded before or after the SmartHeap DLL was loaded. SmartHeap searches the entire address space for DLLs when it is loaded, and it patches LoadLibrary to catches DLLs that are later loaded.
Note: SmartHeap only patches DLLs that export CRT heap routines -- namely, CRT DLLs. DLLs or EXEs that use a CRT DLL do not have their own private heaps. The CRT DLL heap is process-wide, so there is no way to patch for only selected DLLs/EXEs that use the CRT DLL; they either must all be patched or none of them can be patched.
If CRT heap calls were made prior to SmartHeap loading, for example calls from the init routines of DLLs that the OS loaded before SmartHeap, SmartHeap's patching will affect the existing DLLs/EXE that do not in any way reference SmartHeap. Any pre-existing allocations are handled correctly; any future allocations will be managed by SmartHeap.
Here's an example that demonstrates why SmartHeap must patch DLLs regardless of when they are loaded or whether they reference SmartHeap:
A VB app dynamically loads a 3rd-party custom control DLL that links with the SmartHeap DLL. Both the VB system DLL and the control DLL reference the CRT and MFC DLLs. The VB system DLL and CRT DLL are already in memory before the control DLL loads, and neither references SmartHeap. When the control DLL creates an MFC object, new is called within the MFC DLL; when it frees the object, delete is called within the control DLL. Thus, the MFC DLL must be patched by SmartHeap even though it was already in memory and has already performed allocations before SmartHeap loaded. And as a consequence, all the VB DLLs in the process must use SmartHeap for all memory management once the control DLL is loaded, since they also share heap with the MFC DLL.
If your application consists of an EXE and one or more DLLs, your best option is to link the SmartHeap or HeapAgent (i.e., debug SmartHeap) DLL with the EXE, specifying that lib as the first lib on the EXE's link command line. This insures that the SmartHeap DLL is loaded before other DLLs and that patching occurs before the process performs any allocations.
Note: See the SmartHeap Getting Started guide for specific and detailed instructions on linking with SmartHeap.
There is no need to link SmartHeap with other DLLs as long as
- They don't statically link the CRT.
- They don't call SmartHeap APIs.
If either of these aren't true for a given DLL, then that DLL must also link with the SmartHeap DLL.
If SmartHeap is linked with a DLL but not the EXE, or if it is linked after another DLL on the EXE command line, then other DLL(s) will load before the SmartHeap DLL. The init routines of these DLLs will execute before the SmartHeap DLL is loaded, and these init routines most likely allocate memory. This will work, since SmartHeap correctly handles pre-existing heap allocations, but SmartHeap will only manage those allocations created after it is loaded.
Note: the EXE's init routine (which calls static C++ constructors, etc.) executes after all DLLs referenced by the EXE are loaded, so linking the SmartHeap DLL first with the EXE insures that SmartHeap is loaded before anything else happens. The Quick Start instructions (in the SmartHeap Getting Started guide) make the SmartHeap DLL automatically link/load first.
|