]> git.sur5r.net Git - bacula/bacula/blob - bacula/src/lib/smartall.c
Use Pmsg in smartall.c rather than printf for tracing Windows
[bacula/bacula] / bacula / src / lib / smartall.c
1 /*
2    Bacula® - The Network Backup Solution
3
4    Copyright (C) 2000-2010 Free Software Foundation Europe e.V.
5
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
11    in the file LICENSE.
12
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.
17
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
21    02110-1301, USA.
22
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.
27 */
28 /*
29
30                          S M A R T A L L O C
31                         Smart Memory Allocator
32
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:
40
41                   http://www.fourmilab.ch/smartall/
42
43 */
44
45 #define _LOCKMGR_COMPLIANT
46
47 #include "bacula.h"
48 /* Use the real routines here */
49 #undef realloc
50 #undef calloc
51 #undef malloc
52 #undef free
53
54 /* We normally turn off debugging here.
55  *  If you want it, simply #ifdef all the
56  *  following off.
57  */
58 #ifdef no_debug_xxxxx
59 #undef Dmsg1
60 #undef Dmsg2
61 #undef Dmsg3
62 #undef Dmsg4
63 #define Dmsg1(l,f,a1)
64 #define Dmsg2(l,f,a1,a2)
65 #define Dmsg3(l,f,a1,a2,a3)
66 #define Dmsg4(l,f,a1,a2,a3,a4)
67 #endif
68
69
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;
74
75 #ifdef SMARTALLOC
76
77 static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
78
79 extern char my_name[];                /* daemon name */
80
81 typedef unsigned short sm_ushort;
82
83 #define EOS      '\0'              /* End of string sentinel */
84 #define sm_min(a, b) ((a) < (b) ? (a) : (b))
85
86 /*  Queue data structures  */
87
88 /*  Memory allocation control structures and storage.  */
89
90 struct abufhead {
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 */
96 };
97
98 static struct b_queue abqueue = {    /* Allocated buffer queue */
99    &abqueue, &abqueue
100 };
101
102
103 static bool bufimode = false;   /* Buffers not tracked when True */
104
105 #define HEAD_SIZE BALIGN(sizeof(struct abufhead))
106
107
108 /*  SMALLOC  --  Allocate buffer, enqueing on the orphaned buffer
109                  tracking list.  */
110
111 static void *smalloc(const char *fname, int lineno, unsigned int nbytes)
112 {
113    char *buf;
114
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.  */
122
123    ASSERT(nbytes > 0);
124
125    nbytes += HEAD_SIZE + 1;
126    if ((buf = (char *)malloc(nbytes)) != NULL) {
127       struct abufhead *head = (struct abufhead *)buf;
128       P(mutex);
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;
140       }
141       sm_bytes += nbytes;
142       if (sm_bytes > sm_max_bytes) {
143          sm_max_bytes = sm_bytes;
144       }
145       V(mutex);
146    } else {
147       Emsg0(M_ABORT, 0, _("Out of memory\n"));
148    }
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."));
153    }
154 #endif
155    return (void *)buf;
156 }
157
158 /*  SM_NEW_OWNER -- Update the File and line number for a buffer
159                     This is to accomodate mem_pool. */
160
161 void sm_new_owner(const char *fname, int lineno, char *buf)
162 {
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;
167    return;
168 }
169
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
173                  routine.  */
174
175 void sm_free(const char *file, int line, void *fp)
176 {
177    char *cp = (char *) fp;
178    struct b_queue *qp;
179
180    if (cp == NULL) {
181       Emsg2(M_ABORT, 0, _("Attempt to free NULL called from %s:%d\n"), file, line);
182    }
183
184    cp -= HEAD_SIZE;
185    qp = (struct b_queue *)cp;
186    struct abufhead *head = (struct abufhead *)cp;
187
188    P(mutex);
189    Dmsg4(1150, "sm_free %d at %p from %s:%d\n",
190          head->ablen, fp,
191          head->abfname, head->ablineno);
192
193    if (!head->abin_use) {
194       V(mutex);
195       Emsg2(M_ABORT, 0, _("double free from %s:%d\n"), file, line);
196    }
197    head->abin_use = false;
198
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) {
202       V(mutex);
203       Emsg2(M_ABORT, 0, _("qp->qnext->qprev != qp called from %s:%d\n"), file, line);
204    }
205    if (qp->qprev->qnext != qp) {
206       V(mutex);
207       Emsg2(M_ABORT, 0, _("qp->qprev->qnext != qp called from %s:%d\n"), file, line);
208    }
209
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.  */
213
214    if (((unsigned char *)cp)[head->ablen - 1] != ((((intptr_t) cp) & 0xFF) ^ 0xC5)) {
215       V(mutex);
216       Emsg2(M_ABORT, 0, _("Buffer overrun called from %s:%d\n"), file, line);
217    }
218    if (sm_buffers > 0) {
219       sm_buffers--;
220       sm_bytes -= head->ablen;
221    }
222
223    qdchain(qp);
224    V(mutex);
225
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.
231
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.
234    */
235
236    memset(cp+HEAD_SIZE, 0xAA, (int)(head->ablen - HEAD_SIZE));
237
238    free(cp);
239 }
240
241 /*  SM_MALLOC  --  Allocate buffer.  NULL is returned if no memory
242                    was available.  */
243
244 void *sm_malloc(const char *fname, int lineno, unsigned int nbytes)
245 {
246    void *buf;
247
248    if ((buf = smalloc(fname, lineno, nbytes)) != NULL) {
249
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.  */
253
254       memset(buf, 0x55, (int) nbytes);
255    } else {
256       Emsg0(M_ABORT, 0, _("Out of memory\n"));
257    }
258    return buf;
259 }
260
261 /*  SM_CALLOC  --  Allocate an array and clear it to zero.  */
262
263 void *sm_calloc(const char *fname, int lineno,
264                 unsigned int nelem, unsigned int elsize)
265 {
266    void *buf;
267
268    if ((buf = smalloc(fname, lineno, nelem * elsize)) != NULL) {
269       memset(buf, 0, (int) (nelem * elsize));
270    } else {
271       Emsg0(M_ABORT, 0, _("Out of memory\n"));
272    }
273    return buf;
274 }
275
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.  */
284
285 void *sm_realloc(const char *fname, int lineno, void *ptr, unsigned int size)
286 {
287    unsigned osize;
288    void *buf;
289    char *cp = (char *) ptr;
290
291    Dmsg4(1400, "sm_realloc %s:%d %p %d\n", fname, lineno, ptr, size);
292    if (size <= 0) {
293       e_msg(fname, lineno, M_ABORT, 0, _("sm_realloc size: %d\n"), size);
294    }
295
296    /*  If  the  old  block  pointer  is  NULL, treat realloc() as a
297       malloc().  SVID is silent  on  this,  but  many  C  libraries
298       permit this.  */
299    if (ptr == NULL) {
300       return sm_malloc(fname, lineno, size);
301    }
302
303    /* If the old and new sizes are the same, be a nice guy and just
304       return the buffer passed in.  */
305    cp -= HEAD_SIZE;
306    struct abufhead *head = (struct abufhead *)cp;
307    osize = head->ablen - (HEAD_SIZE + 1);
308    if (size == osize) {
309       return ptr;
310    }
311
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
315       intact.  */
316
317 // sm_buffers--;
318 // sm_bytes -= head->ablen;
319
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". */
324       if (size > osize) {
325          memset(((char *) buf) + osize, 0x55, (int) (size - osize));
326       }
327
328       /* All done.  Free and dechain the original buffer. */
329       sm_free(fname, lineno, ptr);
330    }
331    Dmsg4(4150, _("sm_realloc %d at %p from %s:%d\n"), size, buf, fname, lineno);
332    return buf;
333 }
334
335 /*  ACTUALLYMALLOC  --  Call the system malloc() function to obtain
336                         storage which will eventually be released
337                         by system or library routines not compiled
338                         using SMARTALLOC.  */
339
340 void *actuallymalloc(unsigned int size)
341 {
342    return malloc(size);
343 }
344
345 /*  ACTUALLYCALLOC  --  Call the system calloc() function to obtain
346                         storage which will eventually be released
347                         by system or library routines not compiled
348                         using SMARTALLOC.  */
349
350 void *actuallycalloc(unsigned int nelem, unsigned int elsize)
351 {
352    return calloc(nelem, elsize);
353 }
354
355 /*  ACTUALLYREALLOC  --  Call the system realloc() function to obtain
356                          storage which will eventually be released
357                          by system or library routines not compiled
358                          using SMARTALLOC.  */
359
360 void *actuallyrealloc(void *ptr, unsigned int size)
361 {
362    Dmsg2(1400, "Actuallyrealloc %p %d\n", ptr, size);
363    return realloc(ptr, size);
364 }
365
366 /*  ACTUALLYFREE  --  Interface to system free() function to release
367                       buffers allocated by low-level routines. */
368
369 void actuallyfree(void *cp)
370 {
371    free(cp);
372 }
373
374 /*  SM_DUMP  --  Print orphaned buffers (and dump them if BUFDUMP is
375  *               True).
376  */
377 void sm_dump(bool bufdump, bool in_use) 
378 {
379    struct abufhead *ap;
380
381    P(mutex);
382
383    ap = (struct abufhead *)abqueue.qnext;
384
385    while (ap != (struct abufhead *) &abqueue) {
386
387       if ((ap == NULL) ||
388           (ap->abq.qnext->qprev != (struct b_queue *) ap) ||
389           (ap->abq.qprev->qnext != (struct b_queue *) ap)) {
390          Pmsg1(0, _(
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);
394          break;
395       }
396
397       if (ap->abfname != NULL) {
398          unsigned memsize = ap->ablen - (HEAD_SIZE + 1);
399          char errmsg[500];
400          char *cp = ((char *)ap) + HEAD_SIZE;
401
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
406          );
407          Pmsg1(0, "%s", errmsg);
408          if (bufdump) {
409             char buf[20];
410             unsigned llen = 0;
411
412             errmsg[0] = EOS;
413             while (memsize) {
414                if (llen >= 16) {
415                   bstrncat(errmsg, "\n", sizeof(errmsg));
416                   llen = 0;
417                   Pmsg1(0, "%s", errmsg);
418                   errmsg[0] = EOS;
419                }
420                bsnprintf(buf, sizeof(buf), " %02X",
421                   (*cp++) & 0xFF);
422                bstrncat(errmsg, buf, sizeof(errmsg));
423                llen++;
424                memsize--;
425             }
426             Pmsg1(0, "%s\n", errmsg);
427          }
428       }
429       ap = (struct abufhead *) ap->abq.qnext;
430    }
431    V(mutex);
432 }
433
434 #undef sm_check
435 /*  SM_CHECK --  Check the buffers and dump if any damage exists. */
436 void sm_check(const char *fname, int lineno, bool bufdump)
437 {
438    if (!sm_check_rtn(fname, lineno, bufdump)) {
439       Emsg2(M_ABORT, 0, _("Damaged buffer found. Called from %s:%d\n"),
440             fname, lineno);
441    }
442 }
443
444 #undef sm_check_rtn
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)
447 {
448    struct abufhead *ap;
449    int bad, badbuf = 0;
450
451    P(mutex);
452    ap = (struct abufhead *) abqueue.qnext;
453    while (ap != (struct abufhead *)&abqueue) {
454       bad = 0;
455       if (ap != NULL) {
456          if (ap->abq.qnext->qprev != (struct b_queue *)ap) {
457             bad = 0x1;
458          }
459          if (ap->abq.qprev->qnext != (struct b_queue *)ap) {
460             bad |= 0x2;
461          }
462          if (((unsigned char *) ap)[((struct abufhead *)ap)->ablen - 1] !=
463               ((((intptr_t) ap) & 0xFF) ^ 0xC5)) {
464             bad |= 0x4;
465          }
466       } else {
467          bad = 0x8;
468       }
469       badbuf |= bad;
470       if (bad) {
471          Pmsg2(0, 
472             _("\nDamaged buffers found at %s:%d\n"), fname, lineno);
473
474          if (bad & 0x1) {
475             Pmsg0(0,  _("  discovery of bad prev link.\n"));
476          }
477          if (bad & 0x2) {
478             Pmsg0(0, _("  discovery of bad next link.\n"));
479          }
480          if (bad & 0x4) {
481             Pmsg0(0, _("  discovery of data overrun.\n"));
482          }
483          if (bad & 0x8) {
484             Pmsg0(0, _("  NULL pointer.\n"));
485          }
486
487          if (!ap) {
488             goto get_out;
489          }
490          Pmsg1(0, _("  Buffer address: %p\n"), ap);
491
492          if (ap->abfname != NULL) {
493             unsigned memsize = ap->ablen - (HEAD_SIZE + 1);
494             char errmsg[80];
495
496             Pmsg4(0, 
497               _("Damaged buffer:  %6u bytes allocated at line %d of %s %s\n"),
498                memsize, ap->ablineno, my_name, ap->abfname
499             );
500             if (bufdump) {
501                unsigned llen = 0;
502                char *cp = ((char *) ap) + HEAD_SIZE;
503
504                errmsg[0] = EOS;
505                while (memsize) {
506                   if (llen >= 16) {
507                      strcat(errmsg, "\n");
508                      llen = 0;
509                      Pmsg1(0, "%s", errmsg);
510                      errmsg[0] = EOS;
511                   }
512                   if (*cp < 0x20) {
513                      sprintf(errmsg + strlen(errmsg), " %02X",
514                         (*cp++) & 0xFF);
515                   } else {
516                      sprintf(errmsg + strlen(errmsg), " %c ",
517                         (*cp++) & 0xFF);
518                   }
519                   llen++;
520                   memsize--;
521                }
522                Pmsg1(0, "%s\n", errmsg);
523             }
524          }
525       }
526       ap = (struct abufhead *)ap->abq.qnext;
527    }
528 get_out:
529    V(mutex);
530    return badbuf ? 0 : 1;
531 }
532
533
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.  */
540
541 void sm_static(bool mode)
542 {
543    bufimode = mode;
544 }
545
546 /*
547  * Here we overload C++'s global new and delete operators
548  *  so that the memory is allocated through smartalloc.
549  */
550
551 #ifdef xxx
552 void * operator new(size_t size)
553 {
554 // Dmsg1(000, "new called %d\n", size);
555    return sm_malloc(__FILE__, __LINE__, size);
556 }
557
558 void operator delete(void *buf)
559 {
560 // Dmsg1(000, "free called %p\n", buf);
561    sm_free(__FILE__, __LINE__, buf);
562 }
563 #endif
564
565 #endif