/*
Bacula® - The Network Backup Solution
- Copyright (C) 2000-2008 Free Software Foundation Europe e.V.
+ Copyright (C) 2000-2011 Free Software Foundation Europe e.V.
The main author of Bacula is Kern Sibbald, with contributions from
many others, a complete list can be found in the file AUTHORS.
This program is Free Software; you can redistribute it and/or
- modify it under the terms of version two of the GNU General Public
+ modify it under the terms of version three of the GNU Affero General Public
License as published by the Free Software Foundation and included
in the file LICENSE.
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
- You should have received a copy of the GNU General Public License
+ You should have received a copy of the GNU Affero General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
02110-1301, USA.
- Bacula® is a registered trademark of John Walker.
+ Bacula® is a registered trademark of Kern Sibbald.
The licensor of Bacula is the Free Software Foundation Europe
(FSFE), Fiduciary Program, Sumatrastrasse 25, 8006 Zürich,
Switzerland, email:ftf@fsfeurope.org.
http://www.fourmilab.ch/smartall/
-
- Version $Id$
-
*/
+#define _LOCKMGR_COMPLIANT
+
#include "bacula.h"
/* Use the real routines here */
#undef realloc
* If you want it, simply #ifdef all the
* following off.
*/
+#ifdef no_debug_xxxxx
#undef Dmsg1
#undef Dmsg2
#undef Dmsg3
#define Dmsg2(l,f,a1,a2)
#define Dmsg3(l,f,a1,a2,a3)
#define Dmsg4(l,f,a1,a2,a3,a4)
+#endif
uint64_t sm_max_bytes = 0;
extern char my_name[]; /* daemon name */
-typedef unsigned short sm_ushort;
-
#define EOS '\0' /* End of string sentinel */
#define sm_min(a, b) ((a) < (b) ? (a) : (b))
struct abufhead {
struct b_queue abq; /* Links on allocated queue */
- unsigned ablen; /* Buffer length in bytes */
+ uint32_t ablen; /* Buffer length in bytes */
const char *abfname; /* File name pointer */
- sm_ushort ablineno; /* Line number of allocation */
+ uint32_t ablineno; /* Line number of allocation */
bool abin_use; /* set when malloced and cleared when free */
};
qinsert(&abqueue, (struct b_queue *) buf);
head->ablen = nbytes;
head->abfname = bufimode ? NULL : fname;
- head->ablineno = (sm_ushort)lineno;
+ head->ablineno = (uint32_t)lineno;
head->abin_use = true;
/* Emplace end-clobber detector at end of buffer */
- buf[nbytes - 1] = (uint8_t)((((long) buf) & 0xFF) ^ 0xC5);
+ buf[nbytes - 1] = (uint8_t)((((intptr_t) buf) & 0xFF) ^ 0xC5);
buf += HEAD_SIZE; /* Increment to user data start */
if (++sm_buffers > sm_max_buffers) {
sm_max_buffers = sm_buffers;
} else {
Emsg0(M_ABORT, 0, _("Out of memory\n"));
}
- Dmsg4(1150, "smalloc %d at %x from %s:%d\n", nbytes, buf, fname, lineno);
+ Dmsg4(1150, "smalloc %d at %p from %s:%d\n", nbytes, buf, fname, lineno);
#if SMALLOC_SANITY_CHECK > 0
if (sm_bytes > SMALLOC_SANITY_CHECK) {
Emsg0(M_ABORT, 0, _("Too much memory used."));
{
buf -= HEAD_SIZE; /* Decrement to header */
((struct abufhead *)buf)->abfname = bufimode ? NULL : fname;
- ((struct abufhead *)buf)->ablineno = (sm_ushort) lineno;
+ ((struct abufhead *)buf)->ablineno = (uint32_t) lineno;
((struct abufhead *)buf)->abin_use = true;
return;
}
{
char *cp = (char *) fp;
struct b_queue *qp;
+ uint32_t lineno = line;
if (cp == NULL) {
- Emsg2(M_ABORT, 0, _("Attempt to free NULL called from %s:%d\n"), file, line);
+ Emsg2(M_ABORT, 0, _("Attempt to free NULL called from %s:%d\n"), file, lineno);
}
cp -= HEAD_SIZE;
struct abufhead *head = (struct abufhead *)cp;
P(mutex);
- Dmsg4(1150, "sm_free %d at %x from %s:%d\n",
+ Dmsg4(1150, "sm_free %d at %p from %s:%d\n",
head->ablen, fp,
- head->abfname, head->ablineno);
+ get_basename(head->abfname), head->ablineno);
if (!head->abin_use) {
V(mutex);
- Emsg2(M_ABORT, 0, _("double free from %s:%d\n"), file, line);
+ Emsg2(M_ABORT, 0, _("double free from %s:%d\n"), file, lineno);
}
head->abin_use = false;
of an address which isn't an allocated buffer. */
if (qp->qnext->qprev != qp) {
V(mutex);
- Emsg2(M_ABORT, 0, _("qp->qnext->qprev != qp called from %s:%d\n"), file, line);
+ Emsg2(M_ABORT, 0, _("qp->qnext->qprev != qp called from %s:%d\n"), file, lineno);
}
if (qp->qprev->qnext != qp) {
V(mutex);
- Emsg2(M_ABORT, 0, _("qp->qprev->qnext != qp called from %s:%d\n"), file, line);
+ Emsg2(M_ABORT, 0, _("qp->qprev->qnext != qp called from %s:%d\n"), file, lineno);
}
/* The following assertion detects storing off the end of the
allocated space in the buffer by comparing the end of buffer
checksum with the address of the buffer. */
- if (((unsigned char *)cp)[head->ablen - 1] != ((((long) cp) & 0xFF) ^ 0xC5)) {
+ if (((unsigned char *)cp)[head->ablen - 1] != ((((intptr_t) cp) & 0xFF) ^ 0xC5)) {
V(mutex);
- Emsg2(M_ABORT, 0, _("Buffer overrun called from %s:%d\n"), file, line);
+ Emsg6(M_ABORT, 0, _("Overrun buffer: len=%d addr=%p allocated: %s:%d called from %s:%d\n"),
+ head->ablen, fp, get_basename(head->abfname), head->ablineno, file, line);
}
if (sm_buffers > 0) {
sm_buffers--;
void *buf;
char *cp = (char *) ptr;
- Dmsg4(400, "sm_realloc %s:%d 0x%x %d\n", fname, lineno, ptr, size);
+ Dmsg4(1400, "sm_realloc %s:%d %p %d\n", get_basename(fname), (uint32_t)lineno, ptr, size);
if (size <= 0) {
e_msg(fname, lineno, M_ABORT, 0, _("sm_realloc size: %d\n"), size);
}
}
/* All done. Free and dechain the original buffer. */
- sm_free(__FILE__, __LINE__, ptr);
+ sm_free(fname, lineno, ptr);
}
- Dmsg4(150, _("sm_realloc %d at %x from %s:%d\n"), size, buf, fname, lineno);
+ Dmsg4(4150, _("sm_realloc %d at %p from %s:%d\n"), size, buf, get_basename(fname), (uint32_t)lineno);
return buf;
}
void *actuallyrealloc(void *ptr, unsigned int size)
{
- Dmsg2(400, "Actuallyrealloc 0x%x %d\n", ptr, size);
+ Dmsg2(1400, "Actuallyrealloc %p %d\n", ptr, size);
return realloc(ptr, size);
}
/* SM_DUMP -- Print orphaned buffers (and dump them if BUFDUMP is
* True).
- * N.B. DO NOT USE any Bacula print routines (Dmsg, Jmsg, Emsg, ...)
- * as they have all been shut down at this point.
*/
void sm_dump(bool bufdump, bool in_use)
{
if ((ap == NULL) ||
(ap->abq.qnext->qprev != (struct b_queue *) ap) ||
(ap->abq.qprev->qnext != (struct b_queue *) ap)) {
- fprintf(stderr, _(
+ Pmsg1(0, _(
"\nOrphaned buffers exist. Dump terminated following\n"
" discovery of bad links in chain of orphaned buffers.\n"
" Buffer address with bad links: %p\n"), ap);
}
if (ap->abfname != NULL) {
- unsigned memsize = ap->ablen - (HEAD_SIZE + 1);
char errmsg[500];
+ uint32_t memsize = ap->ablen - (HEAD_SIZE + 1);
char *cp = ((char *)ap) + HEAD_SIZE;
- bsnprintf(errmsg, sizeof(errmsg),
- _("%s buffer: %s %6u bytes buf=%p allocated at %s:%d\n"),
+ Pmsg6(0, "%s buffer: %s %d bytes at %p from %s:%d\n",
in_use?"In use":"Orphaned",
- my_name, memsize, cp, ap->abfname, ap->ablineno
- );
- fprintf(stderr, "%s", errmsg);
+ my_name, memsize, cp, get_basename(ap->abfname), ap->ablineno);
if (bufdump) {
char buf[20];
unsigned llen = 0;
if (llen >= 16) {
bstrncat(errmsg, "\n", sizeof(errmsg));
llen = 0;
- fprintf(stderr, "%s", errmsg);
+ Pmsg1(0, "%s", errmsg);
errmsg[0] = EOS;
}
bsnprintf(buf, sizeof(buf), " %02X",
llen++;
memsize--;
}
- fprintf(stderr, "%s\n", errmsg);
+ Pmsg1(0, "%s\n", errmsg);
}
}
ap = (struct abufhead *) ap->abq.qnext;
{
if (!sm_check_rtn(fname, lineno, bufdump)) {
Emsg2(M_ABORT, 0, _("Damaged buffer found. Called from %s:%d\n"),
- fname, lineno);
+ get_basename(fname), (uint32_t)lineno);
}
}
P(mutex);
ap = (struct abufhead *) abqueue.qnext;
- while (ap != (struct abufhead *) &abqueue) {
+ while (ap != (struct abufhead *)&abqueue) {
bad = 0;
- if ((ap == NULL) ||
- (ap->abq.qnext->qprev != (struct b_queue *) ap)) {
- bad = 0x1;
- }
- if (ap->abq.qprev->qnext != (struct b_queue *) ap) {
- bad |= 0x2;
- }
- if (((unsigned char *) ap)[((struct abufhead *) ap)->ablen - 1] !=
- ((((long) ap) & 0xFF) ^ 0xC5)) {
- bad |= 0x4;
+ if (ap != NULL) {
+ if (ap->abq.qnext->qprev != (struct b_queue *)ap) {
+ bad = 0x1;
+ }
+ if (ap->abq.qprev->qnext != (struct b_queue *)ap) {
+ bad |= 0x2;
+ }
+ if (((unsigned char *) ap)[((struct abufhead *)ap)->ablen - 1] !=
+ ((((intptr_t) ap) & 0xFF) ^ 0xC5)) {
+ bad |= 0x4;
+ }
+ } else {
+ bad = 0x8;
}
badbuf |= bad;
if (bad) {
- fprintf(stderr,
- _("\nDamaged buffers found at %s:%d\n"), fname, lineno);
+ Pmsg2(0,
+ _("\nDamaged buffers found at %s:%d\n"), get_basename(fname), (uint32_t)lineno);
if (bad & 0x1) {
- fprintf(stderr, _(" discovery of bad prev link.\n"));
+ Pmsg0(0, _(" discovery of bad prev link.\n"));
}
if (bad & 0x2) {
- fprintf(stderr, _(" discovery of bad next link.\n"));
+ Pmsg0(0, _(" discovery of bad next link.\n"));
}
if (bad & 0x4) {
- fprintf(stderr, _(" discovery of data overrun.\n"));
+ Pmsg0(0, _(" discovery of data overrun.\n"));
+ }
+ if (bad & 0x8) {
+ Pmsg0(0, _(" NULL pointer.\n"));
}
- fprintf(stderr, _(" Buffer address: %p\n"), ap);
+ if (!ap) {
+ goto get_out;
+ }
+ Pmsg1(0, _(" Buffer address: %p\n"), ap);
if (ap->abfname != NULL) {
- unsigned memsize = ap->ablen - (HEAD_SIZE + 1);
+ uint32_t memsize = ap->ablen - (HEAD_SIZE + 1);
char errmsg[80];
- fprintf(stderr,
+ Pmsg4(0,
_("Damaged buffer: %6u bytes allocated at line %d of %s %s\n"),
- memsize, ap->ablineno, my_name, ap->abfname
+ memsize, ap->ablineno, my_name, get_basename(ap->abfname)
);
if (bufdump) {
unsigned llen = 0;
if (llen >= 16) {
strcat(errmsg, "\n");
llen = 0;
- fprintf(stderr, "%s", errmsg);
+ Pmsg1(0, "%s", errmsg);
errmsg[0] = EOS;
}
if (*cp < 0x20) {
llen++;
memsize--;
}
- fprintf(stderr, "%s\n", errmsg);
+ Pmsg1(0, "%s\n", errmsg);
}
}
}
- ap = (struct abufhead *) ap->abq.qnext;
+ ap = (struct abufhead *)ap->abq.qnext;
}
+get_out:
V(mutex);
return badbuf ? 0 : 1;
}
void operator delete(void *buf)
{
-// Dmsg1(000, "free called 0x%x\n", buf);
+// Dmsg1(000, "free called %p\n", buf);
sm_free(__FILE__, __LINE__, buf);
}
#endif