2 Bacula® - The Network Backup Solution
4 Copyright (C) 2000-2010 Free Software Foundation Europe e.V.
6 The main author of Bacula is Kern Sibbald, with contributions from
7 many others, a complete list can be found in the file AUTHORS.
8 This program is Free Software; you can redistribute it and/or
9 modify it under the terms of version two of the GNU General Public
10 License as published by the Free Software Foundation and included
13 This program is distributed in the hope that it will be useful, but
14 WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 General Public License for more details.
18 You should have received a copy of the GNU General Public License
19 along with this program; if not, write to the Free Software
20 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
23 Bacula® is a registered trademark of Kern Sibbald.
24 The licensor of Bacula is the Free Software Foundation Europe
25 (FSFE), Fiduciary Program, Sumatrastrasse 25, 8006 Zürich,
26 Switzerland, email:ftf@fsfeurope.org.
31 Smart Memory Allocator
33 Evolved over several years, starting with the initial
34 SMARTALLOC code for AutoSketch in 1986, guided by the Blind
35 Watchbreaker, John Walker. Isolated in this general-purpose
36 form in September of 1989. Updated with be more POSIX
37 compliant and to include Web-friendly HTML documentation in
38 October of 1998 by the same culprit. For additional
39 information and the current version visit the Web page:
41 http://www.fourmilab.ch/smartall/
45 #define _LOCKMGR_COMPLIANT
48 /* Use the real routines here */
54 /* We normally turn off debugging here.
55 * If you want it, simply #ifdef all the
64 #define Dmsg2(l,f,a1,a2)
65 #define Dmsg3(l,f,a1,a2,a3)
66 #define Dmsg4(l,f,a1,a2,a3,a4)
70 uint64_t sm_max_bytes = 0;
71 uint64_t sm_bytes = 0;
72 uint32_t sm_max_buffers = 0;
73 uint32_t sm_buffers = 0;
77 static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
79 extern char my_name[]; /* daemon name */
81 typedef unsigned short sm_ushort;
83 #define EOS '\0' /* End of string sentinel */
84 #define sm_min(a, b) ((a) < (b) ? (a) : (b))
86 /* Queue data structures */
88 /* Memory allocation control structures and storage. */
91 struct b_queue abq; /* Links on allocated queue */
92 unsigned ablen; /* Buffer length in bytes */
93 const char *abfname; /* File name pointer */
94 sm_ushort ablineno; /* Line number of allocation */
95 bool abin_use; /* set when malloced and cleared when free */
98 static struct b_queue abqueue = { /* Allocated buffer queue */
103 static bool bufimode = false; /* Buffers not tracked when True */
105 #define HEAD_SIZE BALIGN(sizeof(struct abufhead))
108 /* SMALLOC -- Allocate buffer, enqueing on the orphaned buffer
111 static void *smalloc(const char *fname, int lineno, unsigned int nbytes)
115 /* Note: Unix MALLOC actually permits a zero length to be
116 passed and allocates a valid block with zero user bytes.
117 Such a block can later be expanded with realloc(). We
118 disallow this based on the belief that it's better to make
119 a special case and allocate one byte in the rare case this
120 is desired than to miss all the erroneous occurrences where
121 buffer length calculation code results in a zero. */
125 nbytes += HEAD_SIZE + 1;
126 if ((buf = (char *)malloc(nbytes)) != NULL) {
127 struct abufhead *head = (struct abufhead *)buf;
129 /* Enqueue buffer on allocated list */
130 qinsert(&abqueue, (struct b_queue *) buf);
131 head->ablen = nbytes;
132 head->abfname = bufimode ? NULL : fname;
133 head->ablineno = (sm_ushort)lineno;
134 head->abin_use = true;
135 /* Emplace end-clobber detector at end of buffer */
136 buf[nbytes - 1] = (uint8_t)((((intptr_t) buf) & 0xFF) ^ 0xC5);
137 buf += HEAD_SIZE; /* Increment to user data start */
138 if (++sm_buffers > sm_max_buffers) {
139 sm_max_buffers = sm_buffers;
142 if (sm_bytes > sm_max_bytes) {
143 sm_max_bytes = sm_bytes;
147 Emsg0(M_ABORT, 0, _("Out of memory\n"));
149 Dmsg4(1150, "smalloc %d at %p from %s:%d\n", nbytes, buf, fname, lineno);
150 #if SMALLOC_SANITY_CHECK > 0
151 if (sm_bytes > SMALLOC_SANITY_CHECK) {
152 Emsg0(M_ABORT, 0, _("Too much memory used."));
158 /* SM_NEW_OWNER -- Update the File and line number for a buffer
159 This is to accomodate mem_pool. */
161 void sm_new_owner(const char *fname, int lineno, char *buf)
163 buf -= HEAD_SIZE; /* Decrement to header */
164 ((struct abufhead *)buf)->abfname = bufimode ? NULL : fname;
165 ((struct abufhead *)buf)->ablineno = (sm_ushort) lineno;
166 ((struct abufhead *)buf)->abin_use = true;
170 /* SM_FREE -- Update free pool availability. FREE is never called
171 except through this interface or by actuallyfree().
172 free(x) is defined to generate a call to this
175 void sm_free(const char *file, int line, void *fp)
177 char *cp = (char *) fp;
181 Emsg2(M_ABORT, 0, _("Attempt to free NULL called from %s:%d\n"), file, line);
185 qp = (struct b_queue *)cp;
186 struct abufhead *head = (struct abufhead *)cp;
189 Dmsg4(1150, "sm_free %d at %p from %s:%d\n",
191 head->abfname, head->ablineno);
193 if (!head->abin_use) {
195 Emsg2(M_ABORT, 0, _("double free from %s:%d\n"), file, line);
197 head->abin_use = false;
199 /* The following assertions will catch virtually every release
200 of an address which isn't an allocated buffer. */
201 if (qp->qnext->qprev != qp) {
203 Emsg2(M_ABORT, 0, _("qp->qnext->qprev != qp called from %s:%d\n"), file, line);
205 if (qp->qprev->qnext != qp) {
207 Emsg2(M_ABORT, 0, _("qp->qprev->qnext != qp called from %s:%d\n"), file, line);
210 /* The following assertion detects storing off the end of the
211 allocated space in the buffer by comparing the end of buffer
212 checksum with the address of the buffer. */
214 if (((unsigned char *)cp)[head->ablen - 1] != ((((intptr_t) cp) & 0xFF) ^ 0xC5)) {
216 Emsg2(M_ABORT, 0, _("Buffer overrun called from %s:%d\n"), file, line);
218 if (sm_buffers > 0) {
220 sm_bytes -= head->ablen;
226 /* Now we wipe the contents of the just-released buffer with
227 "designer garbage" (Duff Kurland's phrase) of alternating
228 bits. This is intended to ruin the day for any miscreant who
229 attempts to access data through a pointer into storage that's
230 been previously released.
232 Modified, kes May, 2007 to not zap the header. This allows us
233 to check the in_use bit and detect doubly freed buffers.
236 memset(cp+HEAD_SIZE, 0xAA, (int)(head->ablen - HEAD_SIZE));
241 /* SM_MALLOC -- Allocate buffer. NULL is returned if no memory
244 void *sm_malloc(const char *fname, int lineno, unsigned int nbytes)
248 if ((buf = smalloc(fname, lineno, nbytes)) != NULL) {
250 /* To catch sloppy code that assumes buffers obtained from
251 malloc() are zeroed, we preset the buffer contents to
252 "designer garbage" consisting of alternating bits. */
254 memset(buf, 0x55, (int) nbytes);
256 Emsg0(M_ABORT, 0, _("Out of memory\n"));
261 /* SM_CALLOC -- Allocate an array and clear it to zero. */
263 void *sm_calloc(const char *fname, int lineno,
264 unsigned int nelem, unsigned int elsize)
268 if ((buf = smalloc(fname, lineno, nelem * elsize)) != NULL) {
269 memset(buf, 0, (int) (nelem * elsize));
271 Emsg0(M_ABORT, 0, _("Out of memory\n"));
276 /* SM_REALLOC -- Adjust the size of a previously allocated buffer.
277 Note that the trick of "resurrecting" a previously
278 freed buffer with realloc() is NOT supported by this
279 function. Further, because of the need to maintain
280 our control storage, SM_REALLOC must always allocate
281 a new block and copy the data in the old block.
282 This may result in programs which make heavy use of
283 realloc() running much slower than normally. */
285 void *sm_realloc(const char *fname, int lineno, void *ptr, unsigned int size)
289 char *cp = (char *) ptr;
291 Dmsg4(1400, "sm_realloc %s:%d %p %d\n", fname, lineno, ptr, size);
293 e_msg(fname, lineno, M_ABORT, 0, _("sm_realloc size: %d\n"), size);
296 /* If the old block pointer is NULL, treat realloc() as a
297 malloc(). SVID is silent on this, but many C libraries
300 return sm_malloc(fname, lineno, size);
303 /* If the old and new sizes are the same, be a nice guy and just
304 return the buffer passed in. */
306 struct abufhead *head = (struct abufhead *)cp;
307 osize = head->ablen - (HEAD_SIZE + 1);
312 /* Sizes differ. Allocate a new buffer of the requested size.
313 If we can't obtain such a buffer, act as defined in SVID:
314 return NULL from realloc() and leave the buffer in PTR
318 // sm_bytes -= head->ablen;
320 if ((buf = smalloc(fname, lineno, size)) != NULL) {
321 memcpy(buf, ptr, (int)sm_min(size, osize));
322 /* If the new buffer is larger than the old, fill the balance
323 of it with "designer garbage". */
325 memset(((char *) buf) + osize, 0x55, (int) (size - osize));
328 /* All done. Free and dechain the original buffer. */
329 sm_free(fname, lineno, ptr);
331 Dmsg4(4150, _("sm_realloc %d at %p from %s:%d\n"), size, buf, fname, lineno);
335 /* ACTUALLYMALLOC -- Call the system malloc() function to obtain
336 storage which will eventually be released
337 by system or library routines not compiled
340 void *actuallymalloc(unsigned int size)
345 /* ACTUALLYCALLOC -- Call the system calloc() function to obtain
346 storage which will eventually be released
347 by system or library routines not compiled
350 void *actuallycalloc(unsigned int nelem, unsigned int elsize)
352 return calloc(nelem, elsize);
355 /* ACTUALLYREALLOC -- Call the system realloc() function to obtain
356 storage which will eventually be released
357 by system or library routines not compiled
360 void *actuallyrealloc(void *ptr, unsigned int size)
362 Dmsg2(1400, "Actuallyrealloc %p %d\n", ptr, size);
363 return realloc(ptr, size);
366 /* ACTUALLYFREE -- Interface to system free() function to release
367 buffers allocated by low-level routines. */
369 void actuallyfree(void *cp)
374 /* SM_DUMP -- Print orphaned buffers (and dump them if BUFDUMP is
377 void sm_dump(bool bufdump, bool in_use)
383 ap = (struct abufhead *)abqueue.qnext;
385 while (ap != (struct abufhead *) &abqueue) {
388 (ap->abq.qnext->qprev != (struct b_queue *) ap) ||
389 (ap->abq.qprev->qnext != (struct b_queue *) ap)) {
391 "\nOrphaned buffers exist. Dump terminated following\n"
392 " discovery of bad links in chain of orphaned buffers.\n"
393 " Buffer address with bad links: %p\n"), ap);
397 if (ap->abfname != NULL) {
398 unsigned memsize = ap->ablen - (HEAD_SIZE + 1);
400 char *cp = ((char *)ap) + HEAD_SIZE;
402 bsnprintf(errmsg, sizeof(errmsg),
403 _("%s buffer: %s %6u bytes buf=%p allocated at %s:%d\n"),
404 in_use?"In use":"Orphaned",
405 my_name, memsize, cp, ap->abfname, ap->ablineno
407 Pmsg1(0, "%s", errmsg);
415 bstrncat(errmsg, "\n", sizeof(errmsg));
417 Pmsg1(0, "%s", errmsg);
420 bsnprintf(buf, sizeof(buf), " %02X",
422 bstrncat(errmsg, buf, sizeof(errmsg));
426 Pmsg1(0, "%s\n", errmsg);
429 ap = (struct abufhead *) ap->abq.qnext;
435 /* SM_CHECK -- Check the buffers and dump if any damage exists. */
436 void sm_check(const char *fname, int lineno, bool bufdump)
438 if (!sm_check_rtn(fname, lineno, bufdump)) {
439 Emsg2(M_ABORT, 0, _("Damaged buffer found. Called from %s:%d\n"),
445 /* SM_CHECK_RTN -- Check the buffers and return 1 if OK otherwise 0 */
446 int sm_check_rtn(const char *fname, int lineno, bool bufdump)
452 ap = (struct abufhead *) abqueue.qnext;
453 while (ap != (struct abufhead *)&abqueue) {
456 if (ap->abq.qnext->qprev != (struct b_queue *)ap) {
459 if (ap->abq.qprev->qnext != (struct b_queue *)ap) {
462 if (((unsigned char *) ap)[((struct abufhead *)ap)->ablen - 1] !=
463 ((((intptr_t) ap) & 0xFF) ^ 0xC5)) {
472 _("\nDamaged buffers found at %s:%d\n"), fname, lineno);
475 Pmsg0(0, _(" discovery of bad prev link.\n"));
478 Pmsg0(0, _(" discovery of bad next link.\n"));
481 Pmsg0(0, _(" discovery of data overrun.\n"));
484 Pmsg0(0, _(" NULL pointer.\n"));
490 Pmsg1(0, _(" Buffer address: %p\n"), ap);
492 if (ap->abfname != NULL) {
493 unsigned memsize = ap->ablen - (HEAD_SIZE + 1);
497 _("Damaged buffer: %6u bytes allocated at line %d of %s %s\n"),
498 memsize, ap->ablineno, my_name, ap->abfname
502 char *cp = ((char *) ap) + HEAD_SIZE;
507 strcat(errmsg, "\n");
509 Pmsg1(0, "%s", errmsg);
513 sprintf(errmsg + strlen(errmsg), " %02X",
516 sprintf(errmsg + strlen(errmsg), " %c ",
522 Pmsg1(0, "%s\n", errmsg);
526 ap = (struct abufhead *)ap->abq.qnext;
530 return badbuf ? 0 : 1;
534 /* SM_STATIC -- Orphaned buffer detection can be disabled (for such
535 items as buffers allocated during initialisation) by
536 calling sm_static(1). Normal orphaned buffer
537 detection can be re-enabled with sm_static(0). Note
538 that all the other safeguards still apply to buffers
539 allocated when sm_static(1) mode is in effect. */
541 void sm_static(bool mode)
547 * Here we overload C++'s global new and delete operators
548 * so that the memory is allocated through smartalloc.
552 void * operator new(size_t size)
554 // Dmsg1(000, "new called %d\n", size);
555 return sm_malloc(__FILE__, __LINE__, size);
558 void operator delete(void *buf)
560 // Dmsg1(000, "free called %p\n", buf);
561 sm_free(__FILE__, __LINE__, buf);