VirtualBox

source: vbox/trunk/src/VBox/Main/win/dllmain.cpp@ 32056

Last change on this file since 32056 was 32056, checked in by vboxsync, 14 years ago

Applied a simple memory leak detector to libjpeg and VBoxC (Windows host only), the code completely disabled by default.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 8.0 KB
Line 
1/** @file
2 *
3 * DLLMAIN - COM DLL exports
4 *
5 */
6
7/*
8 * Copyright (C) 2006-2007 Oracle Corporation
9 *
10 * This file is part of VirtualBox Open Source Edition (OSE), as
11 * available from http://www.virtualbox.org. This file is free software;
12 * you can redistribute it and/or modify it under the terms of the GNU
13 * General Public License (GPL) as published by the Free Software
14 * Foundation, in version 2 as it comes in the "COPYING" file of the
15 * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
16 * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
17 */
18
19#include "VBox/com/defs.h"
20
21#include <SessionImpl.h>
22
23#include <atlbase.h>
24#include <atlcom.h>
25
26#include <iprt/initterm.h>
27
28/* Memory leak detection. */
29#ifdef VBOX_WITH_VRDP_MEMLEAK_DETECTOR
30typedef struct _MLDMemBlock
31{
32 unsigned uSignature;
33 struct _MLDMemBlock *next;
34 struct _MLDMemBlock *prev;
35 const char *pszCaller;
36 int iLine;
37 bool fTmp;
38 size_t size;
39 void *pv;
40} MLDMemBlock;
41
42static MLDMemBlock *gMemBlockListHead;
43static RTCRITSECT g_critsect;
44static const char *gszMDLPrefix = "MLDMEM";
45static int gAllocated = 0;
46static int gFreed = 0;
47static bool gfMLD = false;
48
49
50#define MLD_BLOCK_TO_PTR(__p) ((__p)? (void *) ( (uint8_t *)(__p) + sizeof (MLDMemBlock) ) : NULL)
51#define MLD_PTR_TO_BLOCK(__p) ((__p)? (MLDMemBlock *)((uint8_t *)(__p) - sizeof (MLDMemBlock)): NULL)
52
53#define MLD_BLOCK_SIGNATURE 0xFEDCBA98
54
55static void vrdpMemLock (void)
56{
57 int rc = RTCritSectEnter (&g_critsect);
58 AssertRC(rc);
59}
60
61static void vrdpMemUnlock (void)
62{
63 RTCritSectLeave (&g_critsect);
64}
65
66static void vrdpMemAppendBlock (MLDMemBlock *pBlock)
67{
68 pBlock->next = gMemBlockListHead;
69 pBlock->prev = NULL;
70
71 if (gMemBlockListHead)
72 {
73 gMemBlockListHead->prev = pBlock;
74 }
75 gMemBlockListHead = pBlock;
76}
77
78static void vrdpMemExcludeBlock (MLDMemBlock *pBlock)
79{
80 /* Assert that the block is in the list. */
81 MLDMemBlock *pIter = gMemBlockListHead;
82
83 while (pIter && pIter != pBlock)
84 {
85 pIter = pIter->next;
86 }
87
88 Assert (pIter == pBlock);
89
90 /* Exclude the block from list. */
91 if (pBlock->next)
92 {
93 pBlock->next->prev = pBlock->prev;
94 }
95 else
96 {
97 /* do nothing */
98 }
99
100 if (pBlock->prev)
101 {
102 pBlock->prev->next = pBlock->next;
103 }
104 else
105 {
106 gMemBlockListHead = pBlock->next;
107 }
108
109 pBlock->next = NULL;
110 pBlock->prev = NULL;
111}
112
113void *MLDMemAllocDbg (size_t cb, bool fTmp, bool fZero, const char *pszCaller, int iLine)
114{
115 size_t cbAlloc;
116 MLDMemBlock *pBlock;
117
118 // LogFlowFunc(("cb = %d, fTmp = %d, fZero = %d, pszCaller = %s, iLine = %d\n",
119 // cb, fTmp, fZero, pszCaller, iLine));
120
121 vrdpMemLock ();
122
123 cbAlloc = cb + sizeof (MLDMemBlock);
124
125 pBlock = (MLDMemBlock *)RTMemAlloc (cbAlloc);
126
127 if (pBlock)
128 {
129 if (fZero)
130 {
131 memset (pBlock, 0, cbAlloc);
132 }
133
134 pBlock->pszCaller = pszCaller;
135 pBlock->iLine = iLine;
136 pBlock->size = cb;
137 pBlock->fTmp = fTmp;
138 pBlock->uSignature = MLD_BLOCK_SIGNATURE;
139 pBlock->pv = MLD_BLOCK_TO_PTR(pBlock);
140
141 vrdpMemAppendBlock (pBlock);
142
143 gAllocated++;
144 }
145
146 vrdpMemUnlock ();
147
148 return MLD_BLOCK_TO_PTR(pBlock);
149}
150
151void *MLDMemReallocDbg (void *pv, size_t cb, const char *pszCaller, int iLine)
152{
153 MLDMemBlock *pBlock;
154
155 // LogFlowFunc(("pv = %p, cb = %d, pszCaller = %s, iLine = %d\n",
156 // pv, cb, pszCaller, iLine));
157
158 vrdpMemLock ();
159
160 pBlock = MLD_PTR_TO_BLOCK(pv);
161
162 if (pBlock)
163 {
164 size_t cbAlloc = cb + sizeof (MLDMemBlock);
165
166 Assert(pBlock->uSignature == MLD_BLOCK_SIGNATURE);
167 Assert(!pBlock->fTmp); /* Tmp blocks are not to be reallocated. */
168 Assert(pBlock->pv == pv);
169
170 vrdpMemExcludeBlock (pBlock);
171
172 pBlock = (MLDMemBlock *)RTMemRealloc (pBlock, cbAlloc);
173
174 pBlock->pszCaller = pszCaller;
175 pBlock->iLine = iLine;
176 pBlock->size = cb;
177
178 vrdpMemAppendBlock (pBlock);
179
180 pv = MLD_BLOCK_TO_PTR(pBlock);
181
182 pBlock->pv = pv;
183 }
184 else
185 {
186 pv = MLDMemAllocDbg (cb, false /* fTmp */, false /* fZero */, pszCaller, iLine);
187 }
188
189 vrdpMemUnlock ();
190
191 return pv;
192}
193
194void MLDMemFreeDbg (void *pv, bool fTmp)
195{
196 MLDMemBlock *pBlock;
197
198 // LogFlowFunc(("pv = %d, fTmp = %d\n",
199 // pv, fTmp));
200
201 vrdpMemLock ();
202
203 pBlock = MLD_PTR_TO_BLOCK(pv);
204
205 if (pBlock)
206 {
207 Assert(pBlock->uSignature == MLD_BLOCK_SIGNATURE);
208 Assert(pBlock->fTmp == fTmp);
209 Assert(pBlock->pv == pv);
210
211 vrdpMemExcludeBlock (pBlock);
212
213 RTMemFree (pBlock);
214 gFreed++;
215 }
216
217 vrdpMemUnlock ();
218}
219
220
221void MLDMemDump (void)
222{
223 MLDMemBlock *pBlock = gMemBlockListHead;
224
225 int c = 0;
226 size_t size = 0;
227 while (pBlock)
228 {
229 LogRel(("%s-MLDMEM: %p 0x%8X bytes %d %s@%d\n", gszMDLPrefix, pBlock, pBlock->size, pBlock->fTmp, pBlock->pszCaller, pBlock->iLine));
230 c++;
231 size += pBlock->size;
232 pBlock = pBlock->next;
233 }
234
235 LogRel(("%s-MLDMEM: %d/%d/%d blocks allocated/freed/left, total %dKb in use.\n", gszMDLPrefix, gAllocated, gFreed, c, size / 1024));
236}
237
238static int gcRefsMem = 0;
239
240void MLDMemInit (const char *pszPrefix)
241{
242 if (++gcRefsMem == 1)
243 {
244 int rc = RTCritSectInit (&g_critsect);
245 AssertRC(rc);
246 gMemBlockListHead = NULL;
247 gszMDLPrefix = pszPrefix;
248 gAllocated = 0;
249 gFreed = 0;
250 gfMLD = true;
251 }
252}
253
254void MLDMemUninit (void)
255{
256 MLDMemDump();
257
258 if (--gcRefsMem == 0)
259 {
260 gfMLD = false;
261 gMemBlockListHead = NULL;
262
263 if (RTCritSectIsInitialized (&g_critsect))
264 {
265 RTCritSectDelete (&g_critsect);
266 }
267 }
268}
269
270void* operator new (std::size_t size) throw (std::bad_alloc)
271{
272 if (gfMLD)
273 return MLDMemAllocDbg (size, false /* bool fTmp */, true /* bool fZero */, __FILE__, __LINE__);
274 else
275 return malloc(size);
276}
277
278void operator delete (void* ptr) throw ()
279{
280 if (gfMLD)
281 MLDMemFreeDbg (ptr, false /* bool fTmp */);
282 else
283 free(ptr);
284}
285
286#endif /* !VBOX_WITH_VRDP_MEMLEAK_DETECTOR */
287
288CComModule _Module;
289
290BEGIN_OBJECT_MAP(ObjectMap)
291 OBJECT_ENTRY(CLSID_Session, Session)
292END_OBJECT_MAP()
293
294/////////////////////////////////////////////////////////////////////////////
295// DLL Entry Point
296
297extern "C"
298BOOL WINAPI DllMain(HINSTANCE hInstance, DWORD dwReason, LPVOID /*lpReserved*/)
299{
300 if (dwReason == DLL_PROCESS_ATTACH)
301 {
302 _Module.Init(ObjectMap, hInstance, &LIBID_VirtualBox);
303 DisableThreadLibraryCalls(hInstance);
304
305 // idempotent, so doesn't harm, and needed for COM embedding scenario
306 RTR3Init();
307
308#ifdef VBOX_WITH_VRDP_MEMLEAK_DETECTOR
309 MLDMemInit("VBOXC");
310#endif /* !VBOX_WITH_VRDP_MEMLEAK_DETECTOR */
311 }
312 else if (dwReason == DLL_PROCESS_DETACH)
313 {
314 _Module.Term();
315
316#ifdef VBOX_WITH_VRDP_MEMLEAK_DETECTOR
317 MLDMemUninit();
318#endif /* !VBOX_WITH_VRDP_MEMLEAK_DETECTOR */
319 }
320 return TRUE;
321}
322
323/////////////////////////////////////////////////////////////////////////////
324// Used to determine whether the DLL can be unloaded by OLE
325
326STDAPI DllCanUnloadNow(void)
327{
328 return (_Module.GetLockCount()==0) ? S_OK : S_FALSE;
329}
330
331/////////////////////////////////////////////////////////////////////////////
332// Returns a class factory to create an object of the requested type
333
334STDAPI DllGetClassObject(REFCLSID rclsid, REFIID riid, LPVOID* ppv)
335{
336 return _Module.GetClassObject(rclsid, riid, ppv);
337}
338
339/////////////////////////////////////////////////////////////////////////////
340// DllRegisterServer - Adds entries to the system registry
341
342STDAPI DllRegisterServer(void)
343{
344 // registers object, typelib and all interfaces in typelib
345 return _Module.RegisterServer(TRUE);
346}
347
348/////////////////////////////////////////////////////////////////////////////
349// DllUnregisterServer - Removes entries from the system registry
350
351STDAPI DllUnregisterServer(void)
352{
353 return _Module.UnregisterServer(TRUE);
354}
Note: See TracBrowser for help on using the repository browser.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette