]> git.sur5r.net Git - bacula/bacula/blob - bacula/src/lib/smartall.c
Backport from BEE
[bacula/bacula] / bacula / src / lib / smartall.c
1 /*
2    Bacula® - The Network Backup Solution
3
4    Copyright (C) 2000-2014 Free Software Foundation Europe e.V.
5
6    The main author of Bacula is Kern Sibbald, with contributions from many
7    others, a complete list can be found in the file AUTHORS.
8
9    You may use this file and others of this release according to the
10    license defined in the LICENSE file, which includes the Affero General
11    Public License, v3.0 ("AGPLv3") and some additional permissions and
12    terms pursuant to its AGPLv3 Section 7.
13
14    Bacula® is a registered trademark of Kern Sibbald.
15 */
16 /*
17
18                          S M A R T A L L O C
19                         Smart Memory Allocator
20
21         Evolved   over   several  years,  starting  with  the  initial
22         SMARTALLOC code for AutoSketch in 1986, guided  by  the  Blind
23         Watchbreaker,  John  Walker.  Isolated in this general-purpose
24         form in  September  of  1989.   Updated  with  be  more  POSIX
25         compliant  and  to  include Web-friendly HTML documentation in
26         October  of  1998  by  the  same  culprit.    For   additional
27         information and the current version visit the Web page:
28
29                   http://www.fourmilab.ch/smartall/
30
31 */
32
33 #define _LOCKMGR_COMPLIANT
34
35 #include "bacula.h"
36 /* Use the real routines here */
37 #undef realloc
38 #undef calloc
39 #undef malloc
40 #undef free
41
42 /* We normally turn off debugging here.
43  *  If you want it, simply #ifdef all the
44  *  following off.
45  */
46 #ifdef no_debug_xxxxx
47 #undef Dmsg1
48 #undef Dmsg2
49 #undef Dmsg3
50 #undef Dmsg4
51 #define Dmsg1(l,f,a1)
52 #define Dmsg2(l,f,a1,a2)
53 #define Dmsg3(l,f,a1,a2,a3)
54 #define Dmsg4(l,f,a1,a2,a3,a4)
55 #endif
56
57
58 uint64_t sm_max_bytes = 0;
59 uint64_t sm_bytes = 0;
60 uint32_t sm_max_buffers = 0;
61 uint32_t sm_buffers = 0;
62
63 #ifdef SMARTALLOC
64
65 static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
66
67 extern char my_name[];                /* daemon name */
68
69 #define EOS      '\0'              /* End of string sentinel */
70 #define sm_min(a, b) ((a) < (b) ? (a) : (b))
71
72 /*  Queue data structures  */
73
74 /*  Memory allocation control structures and storage.  */
75
76 struct abufhead {
77    struct b_queue abq;         /* Links on allocated queue */
78    uint32_t ablen;             /* Buffer length in bytes */
79    const char *abfname;        /* File name pointer */
80    uint32_t ablineno;          /* Line number of allocation */
81    bool abin_use;              /* set when malloced and cleared when free */
82 };
83
84 static struct b_queue abqueue = {    /* Allocated buffer queue */
85    &abqueue, &abqueue
86 };
87
88
89 static bool bufimode = false;   /* Buffers not tracked when True */
90
91 #define HEAD_SIZE BALIGN(sizeof(struct abufhead))
92
93
94 /*  SMALLOC  --  Allocate buffer, enqueing on the orphaned buffer
95                  tracking list.  */
96
97 static void *smalloc(const char *fname, int lineno, unsigned int nbytes)
98 {
99    char *buf;
100
101    /* Note:  Unix  MALLOC  actually  permits  a zero length to be
102       passed and allocates a valid block with  zero  user  bytes.
103       Such  a  block  can  later  be expanded with realloc().  We
104       disallow this based on the belief that it's better to  make
105       a  special case and allocate one byte in the rare case this
106       is desired than to miss all the erroneous occurrences where
107       buffer length calculation code results in a zero.  */
108
109    ASSERT(nbytes > 0);
110
111    nbytes += HEAD_SIZE + 1;
112    if ((buf = (char *)malloc(nbytes)) != NULL) {
113       struct abufhead *head = (struct abufhead *)buf;
114       P(mutex);
115       /* Enqueue buffer on allocated list */
116       qinsert(&abqueue, (struct b_queue *) buf);
117       head->ablen = nbytes;
118       head->abfname = bufimode ? NULL : fname;
119       head->ablineno = (uint32_t)lineno;
120       head->abin_use = true;
121       /* Emplace end-clobber detector at end of buffer */
122       buf[nbytes - 1] = (uint8_t)((((intptr_t) buf) & 0xFF) ^ 0xC5);
123       buf += HEAD_SIZE;  /* Increment to user data start */
124       if (++sm_buffers > sm_max_buffers) {
125          sm_max_buffers = sm_buffers;
126       }
127       sm_bytes += nbytes;
128       if (sm_bytes > sm_max_bytes) {
129          sm_max_bytes = sm_bytes;
130       }
131       V(mutex);
132    } else {
133       Emsg0(M_ABORT, 0, _("Out of memory\n"));
134    }
135    Dmsg4(DT_MEMORY|50, "smalloc %d at %p from %s:%d\n", nbytes, buf, fname, lineno);
136 #if    SMALLOC_SANITY_CHECK > 0
137    if (sm_bytes > SMALLOC_SANITY_CHECK) {
138       Emsg0(M_ABORT, 0, _("Too much memory used."));
139    }
140 #endif
141    return (void *)buf;
142 }
143
144 /*  SM_NEW_OWNER -- Update the File and line number for a buffer
145                     This is to accomodate mem_pool. */
146
147 void sm_new_owner(const char *fname, int lineno, char *buf)
148 {
149    buf -= HEAD_SIZE;  /* Decrement to header */
150    ((struct abufhead *)buf)->abfname = bufimode ? NULL : fname;
151    ((struct abufhead *)buf)->ablineno = (uint32_t) lineno;
152    ((struct abufhead *)buf)->abin_use = true;
153    return;
154 }
155
156 /*  SM_FREE  --  Update free pool availability.  FREE is never called
157                  except  through  this interface or by actuallyfree().
158                  free(x)  is  defined  to  generate  a  call  to  this
159                  routine.  */
160
161 void sm_free(const char *file, int line, void *fp)
162 {
163    char *cp = (char *) fp;
164    struct b_queue *qp;
165    uint32_t lineno = line;
166
167    if (cp == NULL) {
168       Emsg2(M_ABORT, 0, _("Attempt to free NULL called from %s:%d\n"), file, lineno);
169    }
170
171    cp -= HEAD_SIZE;
172    qp = (struct b_queue *)cp;
173    struct abufhead *head = (struct abufhead *)cp;
174
175    P(mutex);
176    Dmsg4(DT_MEMORY|50, "sm_free %d at %p from %s:%d\n",
177          head->ablen, fp,
178          get_basename(head->abfname), head->ablineno);
179
180    if (!head->abin_use) {
181       V(mutex);
182       Emsg2(M_ABORT, 0, _("double free from %s:%d\n"), file, lineno);
183    }
184    head->abin_use = false;
185
186    /* The following assertions will catch virtually every release
187       of an address which isn't an allocated buffer. */
188    if (qp->qnext->qprev != qp) {
189       V(mutex);
190       Emsg2(M_ABORT, 0, _("qp->qnext->qprev != qp called from %s:%d\n"), file, lineno);
191    }
192    if (qp->qprev->qnext != qp) {
193       V(mutex);
194       Emsg2(M_ABORT, 0, _("qp->qprev->qnext != qp called from %s:%d\n"), file, lineno);
195    }
196
197    /* The following assertion detects storing off the  end  of  the
198       allocated  space in the buffer by comparing the end of buffer
199       checksum with the address of the buffer.  */
200
201    if (((unsigned char *)cp)[head->ablen - 1] != ((((intptr_t) cp) & 0xFF) ^ 0xC5)) {
202       V(mutex);
203       Emsg6(M_ABORT, 0, _("Overrun buffer: len=%d addr=%p allocated: %s:%d called from %s:%d\n"),
204          head->ablen, fp, get_basename(head->abfname), head->ablineno, file, line);
205    }
206    if (sm_buffers > 0) {
207       sm_buffers--;
208       sm_bytes -= head->ablen;
209    }
210
211    qdchain(qp);
212    V(mutex);
213
214    /* Now we wipe the contents of  the  just-released  buffer  with
215       "designer  garbage"  (Duff  Kurland's  phrase) of alternating
216       bits.  This is intended to ruin the day for any miscreant who
217       attempts to access data through a pointer into storage that's
218       been previously released.
219
220       Modified, kes May, 2007 to not zap the header. This allows us
221       to check the in_use bit and detect doubly freed buffers.
222    */
223
224    memset(cp+HEAD_SIZE, 0xAA, (int)(head->ablen - HEAD_SIZE));
225
226    free(cp);
227 }
228
229 /*  SM_MALLOC  --  Allocate buffer.  NULL is returned if no memory
230                    was available.  */
231
232 void *sm_malloc(const char *fname, int lineno, unsigned int nbytes)
233 {
234    void *buf;
235
236    if ((buf = smalloc(fname, lineno, nbytes)) != NULL) {
237
238       /* To catch sloppy code that assumes  buffers  obtained  from
239          malloc()  are  zeroed,  we  preset  the buffer contents to
240          "designer garbage" consisting of alternating bits.  */
241
242       memset(buf, 0x55, (int) nbytes);
243    } else {
244       Emsg0(M_ABORT, 0, _("Out of memory\n"));
245    }
246    return buf;
247 }
248
249 /*  SM_CALLOC  --  Allocate an array and clear it to zero.  */
250
251 void *sm_calloc(const char *fname, int lineno,
252                 unsigned int nelem, unsigned int elsize)
253 {
254    void *buf;
255
256    if ((buf = smalloc(fname, lineno, nelem * elsize)) != NULL) {
257       memset(buf, 0, (int) (nelem * elsize));
258    } else {
259       Emsg0(M_ABORT, 0, _("Out of memory\n"));
260    }
261    return buf;
262 }
263
264 /*  SM_REALLOC  --  Adjust the size of a  previously  allocated  buffer.
265                     Note  that  the trick of "resurrecting" a previously
266                     freed buffer with realloc() is NOT supported by this
267                     function.   Further, because of the need to maintain
268                     our control storage, SM_REALLOC must always allocate
269                     a  new  block  and  copy  the data in the old block.
270                     This may result in programs which make heavy use  of
271                     realloc() running much slower than normally.  */
272
273 void *sm_realloc(const char *fname, int lineno, void *ptr, unsigned int size)
274 {
275    unsigned osize;
276    void *buf;
277    char *cp = (char *) ptr;
278
279    Dmsg4(DT_MEMORY|50, "sm_realloc %s:%d %p %d\n", get_basename(fname), (uint32_t)lineno, ptr, size);
280    if (size <= 0) {
281       e_msg(fname, lineno, M_ABORT, 0, _("sm_realloc size: %d\n"), size);
282    }
283
284    /*  If  the  old  block  pointer  is  NULL, treat realloc() as a
285       malloc().  SVID is silent  on  this,  but  many  C  libraries
286       permit this.  */
287    if (ptr == NULL) {
288       return sm_malloc(fname, lineno, size);
289    }
290
291    /* If the old and new sizes are the same, be a nice guy and just
292       return the buffer passed in.  */
293    cp -= HEAD_SIZE;
294    struct abufhead *head = (struct abufhead *)cp;
295    osize = head->ablen - (HEAD_SIZE + 1);
296    if (size == osize) {
297       return ptr;
298    }
299
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
303       intact.  */
304
305 // sm_buffers--;
306 // sm_bytes -= head->ablen;
307
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". */
312       if (size > osize) {
313          memset(((char *) buf) + osize, 0x55, (int) (size - osize));
314       }
315
316       /* All done.  Free and dechain the original buffer. */
317       sm_free(fname, lineno, ptr);
318    }
319    Dmsg4(DT_MEMORY|60, _("sm_realloc %d at %p from %s:%d\n"), size, buf, get_basename(fname), (uint32_t)lineno);
320    return buf;
321 }
322
323 /*  ACTUALLYMALLOC  --  Call the system malloc() function to obtain
324                         storage which will eventually be released
325                         by system or library routines not compiled
326                         using SMARTALLOC.  */
327
328 void *actuallymalloc(unsigned int size)
329 {
330    return malloc(size);
331 }
332
333 /*  ACTUALLYCALLOC  --  Call the system calloc() function to obtain
334                         storage which will eventually be released
335                         by system or library routines not compiled
336                         using SMARTALLOC.  */
337
338 void *actuallycalloc(unsigned int nelem, unsigned int elsize)
339 {
340    return calloc(nelem, elsize);
341 }
342
343 /*  ACTUALLYREALLOC  --  Call the system realloc() function to obtain
344                          storage which will eventually be released
345                          by system or library routines not compiled
346                          using SMARTALLOC.  */
347
348 void *actuallyrealloc(void *ptr, unsigned int size)
349 {
350    Dmsg2(DT_MEMORY|40, "Actuallyrealloc %p %d\n", ptr, size);
351    return realloc(ptr, size);
352 }
353
354 /*  ACTUALLYFREE  --  Interface to system free() function to release
355                       buffers allocated by low-level routines. */
356
357 void actuallyfree(void *cp)
358 {
359    free(cp);
360 }
361
362 /*  SM_DUMP  --  Print orphaned buffers (and dump them if BUFDUMP is
363  *               True).
364  */
365 void sm_dump(bool bufdump, bool in_use)
366 {
367    struct abufhead *ap;
368
369    P(mutex);
370
371    ap = (struct abufhead *)abqueue.qnext;
372
373    while (ap != (struct abufhead *) &abqueue) {
374
375       if ((ap == NULL) ||
376           (ap->abq.qnext->qprev != (struct b_queue *) ap) ||
377           (ap->abq.qprev->qnext != (struct b_queue *) ap)) {
378          Pmsg1(0, _(
379             "\nOrphaned buffers exist.  Dump terminated following\n"
380             "  discovery of bad links in chain of orphaned buffers.\n"
381             "  Buffer address with bad links: %p\n"), ap);
382          break;
383       }
384
385       if (ap->abfname != NULL) {
386          char errmsg[500];
387          uint32_t memsize = ap->ablen - (HEAD_SIZE + 1);
388          char *cp = ((char *)ap) + HEAD_SIZE;
389
390          Pmsg6(0, "%s buffer: %s %d bytes at %p from %s:%d\n",
391             in_use?"In use":"Orphaned",
392             my_name, memsize, cp, get_basename(ap->abfname), ap->ablineno);
393          if (bufdump) {
394             char buf[20];
395             unsigned llen = 0;
396
397             errmsg[0] = EOS;
398             while (memsize) {
399                if (llen >= 16) {
400                   bstrncat(errmsg, "\n", sizeof(errmsg));
401                   llen = 0;
402                   Pmsg1(0, "%s", errmsg);
403                   errmsg[0] = EOS;
404                }
405                bsnprintf(buf, sizeof(buf), " %02X",
406                   (*cp++) & 0xFF);
407                bstrncat(errmsg, buf, sizeof(errmsg));
408                llen++;
409                memsize--;
410             }
411             Pmsg1(0, "%s\n", errmsg);
412          }
413       }
414       ap = (struct abufhead *) ap->abq.qnext;
415    }
416    V(mutex);
417 }
418
419 #undef sm_check
420 /*  SM_CHECK --  Check the buffers and dump if any damage exists. */
421 void sm_check(const char *fname, int lineno, bool bufdump)
422 {
423    if (!sm_check_rtn(fname, lineno, bufdump)) {
424       Emsg2(M_ABORT, 0, _("Damaged buffer found. Called from %s:%d\n"),
425             get_basename(fname), (uint32_t)lineno);
426    }
427 }
428
429 #undef sm_check_rtn
430 /*  SM_CHECK_RTN -- Check the buffers and return 1 if OK otherwise 0 */
431 int sm_check_rtn(const char *fname, int lineno, bool bufdump)
432 {
433    struct abufhead *ap;
434    int bad, badbuf = 0;
435
436    P(mutex);
437    ap = (struct abufhead *) abqueue.qnext;
438    while (ap != (struct abufhead *)&abqueue) {
439       bad = 0;
440       if (ap != NULL) {
441          if (ap->abq.qnext->qprev != (struct b_queue *)ap) {
442             bad = 0x1;
443          }
444          if (ap->abq.qprev->qnext != (struct b_queue *)ap) {
445             bad |= 0x2;
446          }
447          if (((unsigned char *) ap)[((struct abufhead *)ap)->ablen - 1] !=
448               ((((intptr_t) ap) & 0xFF) ^ 0xC5)) {
449             bad |= 0x4;
450          }
451       } else {
452          bad = 0x8;
453       }
454       badbuf |= bad;
455       if (bad) {
456          Pmsg2(0,
457             _("\nDamaged buffers found at %s:%d\n"), get_basename(fname), (uint32_t)lineno);
458
459          if (bad & 0x1) {
460             Pmsg0(0,  _("  discovery of bad prev link.\n"));
461          }
462          if (bad & 0x2) {
463             Pmsg0(0, _("  discovery of bad next link.\n"));
464          }
465          if (bad & 0x4) {
466             Pmsg0(0, _("  discovery of data overrun.\n"));
467          }
468          if (bad & 0x8) {
469             Pmsg0(0, _("  NULL pointer.\n"));
470          }
471
472          if (!ap) {
473             goto get_out;
474          }
475          Pmsg1(0, _("  Buffer address: %p\n"), ap);
476
477          if (ap->abfname != NULL) {
478             uint32_t memsize = ap->ablen - (HEAD_SIZE + 1);
479             char errmsg[80];
480
481             Pmsg4(0,
482               _("Damaged buffer:  %6u bytes allocated at line %d of %s %s\n"),
483                memsize, ap->ablineno, my_name, get_basename(ap->abfname)
484             );
485             if (bufdump) {
486                unsigned llen = 0;
487                char *cp = ((char *) ap) + HEAD_SIZE;
488
489                errmsg[0] = EOS;
490                while (memsize) {
491                   if (llen >= 16) {
492                      strcat(errmsg, "\n");
493                      llen = 0;
494                      Pmsg1(0, "%s", errmsg);
495                      errmsg[0] = EOS;
496                   }
497                   if (*cp < 0x20) {
498                      sprintf(errmsg + strlen(errmsg), " %02X",
499                         (*cp++) & 0xFF);
500                   } else {
501                      sprintf(errmsg + strlen(errmsg), " %c ",
502                         (*cp++) & 0xFF);
503                   }
504                   llen++;
505                   memsize--;
506                }
507                Pmsg1(0, "%s\n", errmsg);
508             }
509          }
510       }
511       ap = (struct abufhead *)ap->abq.qnext;
512    }
513 get_out:
514    V(mutex);
515    return badbuf ? 0 : 1;
516 }
517
518
519 /*  SM_STATIC  --  Orphaned buffer detection can be disabled  (for  such
520                    items  as buffers allocated during initialisation) by
521                    calling   sm_static(1).    Normal   orphaned   buffer
522                    detection  can be re-enabled with sm_static(0).  Note
523                    that all the other safeguards still apply to  buffers
524                    allocated  when  sm_static(1)  mode is in effect.  */
525
526 void sm_static(bool mode)
527 {
528    bufimode = mode;
529 }
530
531 /*
532  * Here we overload C++'s global new and delete operators
533  *  so that the memory is allocated through smartalloc.
534  */
535
536 #ifdef xxx
537 void * operator new(size_t size)
538 {
539 // Dmsg1(000, "new called %d\n", size);
540    return sm_malloc(__FILE__, __LINE__, size);
541 }
542
543 void operator delete(void *buf)
544 {
545 // Dmsg1(000, "free called %p\n", buf);
546    sm_free(__FILE__, __LINE__, buf);
547 }
548 #endif
549
550 #endif