6 Evolved over several years, starting with the initial
7 SMARTALLOC code for AutoSketch in 1986, guided by the Blind
8 Watchbreaker, John Walker. Isolated in this general-purpose
9 form in September of 1989. Updated with be more POSIX
10 compliant and to include Web-friendly HTML documentation in
11 October of 1998 by the same culprit. For additional
12 information and the current version visit the Web page:
14 http://www.fourmilab.ch/smartall/
21 Bacula® - The Network Backup Solution
23 Copyright (C) 2000-2006 Free Software Foundation Europe e.V.
25 The main author of Bacula is Kern Sibbald, with contributions from
26 many others, a complete list can be found in the file AUTHORS.
27 This program is Free Software; you can redistribute it and/or
28 modify it under the terms of version two of the GNU General Public
29 License as published by the Free Software Foundation plus additions
30 that are listed in the file LICENSE.
32 This program is distributed in the hope that it will be useful, but
33 WITHOUT ANY WARRANTY; without even the implied warranty of
34 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
35 General Public License for more details.
37 You should have received a copy of the GNU General Public License
38 along with this program; if not, write to the Free Software
39 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
42 Bacula® is a registered trademark of John Walker.
43 The licensor of Bacula is the Free Software Foundation Europe
44 (FSFE), Fiduciary Program, Sumatrastrasse 25, 8006 Zürich,
45 Switzerland, email:ftf@fsfeurope.org.
49 /* Use the real routines here */
55 /* We normally turn off debugging here.
56 * 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)
69 uint64_t sm_max_bytes = 0;
70 uint64_t sm_bytes = 0;
71 uint32_t sm_max_buffers = 0;
72 uint32_t sm_buffers = 0;
76 static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
78 extern char my_name[]; /* daemon name */
80 typedef unsigned short sm_ushort;
82 #define EOS '\0' /* End of string sentinel */
83 #define sm_min(a, b) ((a) < (b) ? (a) : (b))
85 /* Queue data structures */
87 /* Memory allocation control structures and storage. */
90 struct b_queue abq; /* Links on allocated queue */
91 unsigned ablen; /* Buffer length in bytes */
92 const char *abfname; /* File name pointer */
93 sm_ushort ablineno; /* Line number of allocation */
96 static struct b_queue abqueue = { /* Allocated buffer queue */
101 static bool bufimode = false; /* Buffers not tracked when True */
103 #define HEAD_SIZE BALIGN(sizeof(struct abufhead))
106 /* SMALLOC -- Allocate buffer, enqueing on the orphaned buffer
109 static void *smalloc(const char *fname, int lineno, unsigned int nbytes)
113 /* Note: Unix MALLOC actually permits a zero length to be
114 passed and allocates a valid block with zero user bytes.
115 Such a block can later be expanded with realloc(). We
116 disallow this based on the belief that it's better to make
117 a special case and allocate one byte in the rare case this
118 is desired than to miss all the erroneous occurrences where
119 buffer length calculation code results in a zero. */
123 nbytes += HEAD_SIZE + 1;
124 if ((buf = (char *)malloc(nbytes)) != NULL) {
125 struct abufhead *head = (struct abufhead *)buf;
127 /* Enqueue buffer on allocated list */
128 qinsert(&abqueue, (struct b_queue *) buf);
129 head->ablen = nbytes;
130 head->abfname = bufimode ? NULL : fname;
131 head->ablineno = (sm_ushort) lineno;
132 /* Emplace end-clobber detector at end of buffer */
133 buf[nbytes - 1] = (uint8_t)((((long) buf) & 0xFF) ^ 0xC5);
134 buf += HEAD_SIZE; /* Increment to user data start */
135 if (++sm_buffers > sm_max_buffers) {
136 sm_max_buffers = sm_buffers;
139 if (sm_bytes > sm_max_bytes) {
140 sm_max_bytes = sm_bytes;
144 Emsg0(M_ABORT, 0, _("Out of memory\n"));
146 Dmsg4(1150, "smalloc %d at %x from %s:%d\n", nbytes, buf, fname, lineno);
147 #if SMALLOC_SANITY_CHECK > 0
148 if (sm_bytes > SMALLOC_SANITY_CHECK) {
149 Emsg0(M_ABORT, 0, _("Too much memory used."));
155 /* SM_NEW_OWNER -- Update the File and line number for a buffer
156 This is to accomodate mem_pool. */
158 void sm_new_owner(const char *fname, int lineno, char *buf)
160 buf -= HEAD_SIZE; /* Decrement to header */
161 ((struct abufhead *)buf)->abfname = bufimode ? NULL : fname;
162 ((struct abufhead *)buf)->ablineno = (sm_ushort) lineno;
166 /* SM_FREE -- Update free pool availability. FREE is never called
167 except through this interface or by actuallyfree().
168 free(x) is defined to generate a call to this
171 void sm_free(const char *file, int line, void *fp)
173 char *cp = (char *) fp;
177 Emsg2(M_ABORT, 0, _("Attempt to free NULL called from %s:%d\n"), file, line);
181 qp = (struct b_queue *) cp;
182 struct abufhead *head = (struct abufhead *)cp;
185 Dmsg4(1150, "sm_free %d at %x from %s:%d\n",
187 head->abfname, head->ablineno);
189 /* The following assertions will catch virtually every release
190 of an address which isn't an allocated buffer. */
191 if (qp->qnext->qprev != qp) {
193 Emsg2(M_ABORT, 0, _("qp->qnext->qprev != qp called from %s:%d\n"), file, line);
195 if (qp->qprev->qnext != qp) {
197 Emsg2(M_ABORT, 0, _("qp->qprev->qnext != qp called from %s:%d\n"), file, line);
200 /* The following assertion detects storing off the end of the
201 allocated space in the buffer by comparing the end of buffer
202 checksum with the address of the buffer. */
204 if (((unsigned char *)cp)[head->ablen - 1] != ((((long) cp) & 0xFF) ^ 0xC5)) {
206 Emsg2(M_ABORT, 0, _("Buffer overrun called from %s:%d\n"), file, line);
208 if (sm_buffers > 0) {
210 sm_bytes -= head->ablen;
216 /* Now we wipe the contents of the just-released buffer with
217 "designer garbage" (Duff Kurland's phrase) of alternating
218 bits. This is intended to ruin the day for any miscreant who
219 attempts to access data through a pointer into storage that's
220 been previously released. */
222 memset(cp, 0xAA, (int) head->ablen);
227 /* SM_MALLOC -- Allocate buffer. NULL is returned if no memory
230 void *sm_malloc(const char *fname, int lineno, unsigned int nbytes)
234 if ((buf = smalloc(fname, lineno, nbytes)) != NULL) {
236 /* To catch sloppy code that assumes buffers obtained from
237 malloc() are zeroed, we preset the buffer contents to
238 "designer garbage" consisting of alternating bits. */
240 memset(buf, 0x55, (int) nbytes);
242 Emsg0(M_ABORT, 0, _("Out of memory\n"));
247 /* SM_CALLOC -- Allocate an array and clear it to zero. */
249 void *sm_calloc(const char *fname, int lineno,
250 unsigned int nelem, unsigned int elsize)
254 if ((buf = smalloc(fname, lineno, nelem * elsize)) != NULL) {
255 memset(buf, 0, (int) (nelem * elsize));
257 Emsg0(M_ABORT, 0, _("Out of memory\n"));
262 /* SM_REALLOC -- Adjust the size of a previously allocated buffer.
263 Note that the trick of "resurrecting" a previously
264 freed buffer with realloc() is NOT supported by this
265 function. Further, because of the need to maintain
266 our control storage, SM_REALLOC must always allocate
267 a new block and copy the data in the old block.
268 This may result in programs which make heavy use of
269 realloc() running much slower than normally. */
271 void *sm_realloc(const char *fname, int lineno, void *ptr, unsigned int size)
275 char *cp = (char *) ptr;
277 Dmsg4(400, "sm_realloc %s:%d 0x%x %d\n", fname, lineno, ptr, size);
279 e_msg(fname, lineno, M_ABORT, 0, _("sm_realloc size: %d\n"), size);
282 /* If the old block pointer is NULL, treat realloc() as a
283 malloc(). SVID is silent on this, but many C libraries
287 return sm_malloc(fname, lineno, size);
290 /* If the old and new sizes are the same, be a nice guy and just
291 return the buffer passed in. */
294 struct abufhead *head = (struct abufhead *)cp;
295 osize = head->ablen - (HEAD_SIZE + 1);
300 /* Sizes differ. Allocate a new buffer of the requested size.
301 If we can't obtain such a buffer, act as defined in SVID:
302 return NULL from realloc() and leave the buffer in PTR
306 // sm_bytes -= head->ablen;
308 if ((buf = smalloc(fname, lineno, size)) != NULL) {
309 memcpy(buf, ptr, (int) sm_min(size, osize));
310 /* If the new buffer is larger than the old, fill the balance
311 of it with "designer garbage". */
313 memset(((char *) buf) + osize, 0x55, (int) (size - osize));
316 /* All done. Free and dechain the original buffer. */
318 sm_free(__FILE__, __LINE__, ptr);
320 Dmsg4(150, _("sm_realloc %d at %x from %s:%d\n"), size, buf, fname, lineno);
324 /* ACTUALLYMALLOC -- Call the system malloc() function to obtain
325 storage which will eventually be released
326 by system or library routines not compiled
329 void *actuallymalloc(unsigned int size)
334 /* ACTUALLYCALLOC -- Call the system calloc() function to obtain
335 storage which will eventually be released
336 by system or library routines not compiled
339 void *actuallycalloc(unsigned int nelem, unsigned int elsize)
341 return calloc(nelem, elsize);
344 /* ACTUALLYREALLOC -- Call the system realloc() function to obtain
345 storage which will eventually be released
346 by system or library routines not compiled
349 void *actuallyrealloc(void *ptr, unsigned int size)
351 Dmsg2(400, "Actuallyrealloc 0x%x %d\n", ptr, size);
352 return realloc(ptr, size);
355 /* ACTUALLYFREE -- Interface to system free() function to release
356 buffers allocated by low-level routines. */
358 void actuallyfree(void *cp)
363 /* SM_DUMP -- Print orphaned buffers (and dump them if BUFDUMP is
365 * N.B. DO NOT USE any Bacula print routines (Dmsg, Jmsg, Emsg, ...)
366 * as they have all been shut down at this point.
368 void sm_dump(bool bufdump)
374 ap = (struct abufhead *)abqueue.qnext;
376 while (ap != (struct abufhead *) &abqueue) {
379 (ap->abq.qnext->qprev != (struct b_queue *) ap) ||
380 (ap->abq.qprev->qnext != (struct b_queue *) ap)) {
382 "\nOrphaned buffers exist. Dump terminated following\n"
383 " discovery of bad links in chain of orphaned buffers.\n"
384 " Buffer address with bad links: %lx\n"), (long) ap);
388 if (ap->abfname != NULL) {
389 unsigned memsize = ap->ablen - (HEAD_SIZE + 1);
392 bsnprintf(errmsg, sizeof(errmsg),
393 _("Orphaned buffer: %6u bytes allocated at line %d of %s %s\n"),
394 memsize, ap->ablineno, my_name, ap->abfname
396 fprintf(stderr, "%s", errmsg);
400 char *cp = ((char *) ap) + HEAD_SIZE;
405 bstrncat(errmsg, "\n", sizeof(errmsg));
407 fprintf(stderr, "%s", errmsg);
410 bsnprintf(buf, sizeof(buf), " %02X",
412 bstrncat(errmsg, buf, sizeof(errmsg));
416 fprintf(stderr, "%s\n", errmsg);
419 ap = (struct abufhead *) ap->abq.qnext;
425 /* SM_CHECK -- Check the buffers and dump if any damage exists. */
426 void sm_check(const char *fname, int lineno, bool bufdump)
428 if (!sm_check_rtn(fname, lineno, bufdump)) {
429 Emsg2(M_ABORT, 0, _("Damaged buffer found. Called from %s:%d\n"),
435 /* SM_CHECK_RTN -- Check the buffers and return 1 if OK otherwise 0 */
436 int sm_check_rtn(const char *fname, int lineno, bool bufdump)
442 ap = (struct abufhead *) abqueue.qnext;
443 while (ap != (struct abufhead *) &abqueue) {
446 (ap->abq.qnext->qprev != (struct b_queue *) ap)) {
449 if (ap->abq.qprev->qnext != (struct b_queue *) ap) {
452 if (((unsigned char *) ap)[((struct abufhead *) ap)->ablen - 1] !=
453 ((((long) ap) & 0xFF) ^ 0xC5)) {
459 _("\nDamaged buffers found at %s:%d\n"), fname, lineno);
462 fprintf(stderr, _(" discovery of bad prev link.\n"));
465 fprintf(stderr, _(" discovery of bad next link.\n"));
468 fprintf(stderr, _(" discovery of data overrun.\n"));
471 fprintf(stderr, _(" Buffer address: %lx\n"), (long) ap);
473 if (ap->abfname != NULL) {
474 unsigned memsize = ap->ablen - (HEAD_SIZE + 1);
478 _("Damaged buffer: %6u bytes allocated at line %d of %s %s\n"),
479 memsize, ap->ablineno, my_name, ap->abfname
483 char *cp = ((char *) ap) + HEAD_SIZE;
488 strcat(errmsg, "\n");
490 fprintf(stderr, "%s", errmsg);
494 sprintf(errmsg + strlen(errmsg), " %02X",
497 sprintf(errmsg + strlen(errmsg), " %c ",
503 fprintf(stderr, "%s\n", errmsg);
507 ap = (struct abufhead *) ap->abq.qnext;
510 return badbuf ? 0 : 1;
514 /* SM_STATIC -- Orphaned buffer detection can be disabled (for such
515 items as buffers allocated during initialisation) by
516 calling sm_static(1). Normal orphaned buffer
517 detection can be re-enabled with sm_static(0). Note
518 that all the other safeguards still apply to buffers
519 allocated when sm_static(1) mode is in effect. */
521 void sm_static(int mode)
523 bufimode = (bool) (mode != 0);
527 * Here we overload C++'s global new and delete operators
528 * so that the memory is allocated through smartalloc.
532 void * operator new(size_t size)
534 // Dmsg1(000, "new called %d\n", size);
535 return sm_malloc(__FILE__, __LINE__, size);
538 void operator delete(void *buf)
540 // Dmsg1(000, "free called 0x%x\n", buf);
541 sm_free(__FILE__, __LINE__, buf);