Bash-4.4 distribution sources and documentation
This commit is contained in:
@@ -16,7 +16,7 @@
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
srcdir = @srcdir@
|
||||
VPATH = .:@srcdir@
|
||||
VPATH = @srcdir@
|
||||
topdir = @top_srcdir@
|
||||
BUILD_DIR = @BUILD_DIR@
|
||||
|
||||
|
||||
@@ -866,8 +866,8 @@ internal_free (mem, file, line, flags)
|
||||
p = (union mhead *) ap - 1;
|
||||
}
|
||||
|
||||
#if defined (MALLOC_TRACE) || defined (MALLOC_REGISTER)
|
||||
if (malloc_trace || malloc_register)
|
||||
#if defined (MALLOC_TRACE) || defined (MALLOC_REGISTER) || defined (MALLOC_WATCH)
|
||||
if (malloc_trace || malloc_register || _malloc_nwatch > 0)
|
||||
ubytes = p->mh_nbytes;
|
||||
#endif
|
||||
|
||||
|
||||
@@ -110,7 +110,7 @@ _print_malloc_stats (s, fp)
|
||||
}
|
||||
fprintf (fp, "\nTotal bytes in use: %lu, total bytes free: %lu\n",
|
||||
totused, totfree);
|
||||
fprintf (fp, "\nTotal bytes requested by application: %lu\n", _mstats.bytesreq);
|
||||
fprintf (fp, "\nTotal bytes requested by application: %lu\n", (unsigned long)_mstats.bytesreq);
|
||||
fprintf (fp, "Total mallocs: %d, total frees: %d, total reallocs: %d (%d copies)\n",
|
||||
_mstats.nmal, _mstats.nfre, _mstats.nrealloc, _mstats.nrcopy);
|
||||
fprintf (fp, "Total sbrks: %d, total bytes via sbrk: %d\n",
|
||||
|
||||
@@ -37,14 +37,25 @@ extern int malloc_register;
|
||||
|
||||
#ifdef MALLOC_REGISTER
|
||||
|
||||
#define FIND_ALLOC 0x01 /* allocate new entry or find existing */
|
||||
#define FIND_EXIST 0x02 /* find existing entry */
|
||||
extern FILE *_imalloc_fopen __P((char *, char *, char *, char *, size_t));
|
||||
|
||||
#define FIND_ALLOC 0x01 /* find slot for new allocation */
|
||||
#define FIND_EXIST 0x02 /* find slot for existing entry for free() or search */
|
||||
|
||||
static int table_count = 0;
|
||||
static int table_allocated = 0;
|
||||
static int table_bucket_index = REG_TABLE_SIZE-1;
|
||||
static mr_table_t mem_table[REG_TABLE_SIZE];
|
||||
static mr_table_t mem_overflow;
|
||||
|
||||
#ifndef STREQ
|
||||
#define STREQ(a, b) ((a)[0] == (b)[0] && strcmp(a, b) == 0)
|
||||
#endif
|
||||
|
||||
static int location_table_index = 0;
|
||||
static int location_table_count = 0;
|
||||
static ma_table_t mlocation_table[REG_TABLE_SIZE];
|
||||
|
||||
/*
|
||||
* NOTE: taken from dmalloc (http://dmalloc.com) and modified.
|
||||
*/
|
||||
@@ -72,8 +83,15 @@ which_bucket (mem)
|
||||
{
|
||||
return (mt_hash ((unsigned char *)mem) & (REG_TABLE_SIZE-1));
|
||||
}
|
||||
|
||||
#else
|
||||
#define which_bucket(mem) (mt_hash ((unsigned char *)(mem)) & (REG_TABLE_SIZE-1));
|
||||
|
||||
#define next_bucket() ((table_bucket_index + 1) & (REG_TABLE_SIZE-1))
|
||||
#define next_entry(mem) ((mem == mem_table + REG_TABLE_SIZE - 1) ? mem_table : ++mem)
|
||||
|
||||
#define prev_bucket() (table_bucket_index == 0 ? REG_TABLE_SIZE-1 : table_bucket_index-1)
|
||||
#define prev_entry(mem) ((mem == mem_table) ? mem_table + REG_TABLE_SIZE - 1 : mem - 1)
|
||||
#endif
|
||||
|
||||
static mr_table_t *
|
||||
@@ -83,60 +101,37 @@ find_entry (mem, flags)
|
||||
{
|
||||
unsigned int bucket;
|
||||
register mr_table_t *tp;
|
||||
mr_table_t *endp, *lastp;
|
||||
mr_table_t *endp;
|
||||
|
||||
if (mem_overflow.mem == mem)
|
||||
return (&mem_overflow);
|
||||
|
||||
bucket = which_bucket (mem); /* get initial hash */
|
||||
tp = endp = mem_table + bucket;
|
||||
lastp = mem_table + REG_TABLE_SIZE;
|
||||
/* If we want to insert an allocation entry just use the next slot */
|
||||
if (flags & FIND_ALLOC)
|
||||
{
|
||||
table_bucket_index = next_bucket();
|
||||
table_count++;
|
||||
tp = mem_table + table_bucket_index;
|
||||
memset(tp, 0, sizeof (mr_table_t)); /* overwrite next existing entry */
|
||||
return tp;
|
||||
}
|
||||
|
||||
tp = endp = mem_table + table_bucket_index;
|
||||
|
||||
/* search for last allocation corresponding to MEM, return entry pointer */
|
||||
while (1)
|
||||
{
|
||||
if (tp->mem == mem)
|
||||
return (tp);
|
||||
if (tp->mem == 0 && (flags & FIND_ALLOC))
|
||||
{
|
||||
table_count++;
|
||||
return (tp);
|
||||
}
|
||||
|
||||
tp++;
|
||||
tp = prev_entry (tp);
|
||||
|
||||
if (tp == lastp) /* wrap around */
|
||||
tp = mem_table;
|
||||
|
||||
if (tp == endp && (flags & FIND_EXIST))
|
||||
/* if we went all the way around and didn't find it, return NULL */
|
||||
if (tp == endp)
|
||||
return ((mr_table_t *)NULL);
|
||||
|
||||
if (tp == endp && (flags & FIND_ALLOC))
|
||||
break;
|
||||
}
|
||||
|
||||
/* oops. table is full. replace an existing free entry. */
|
||||
do
|
||||
{
|
||||
/* If there are no free entries, punt right away without searching. */
|
||||
if (table_allocated == REG_TABLE_SIZE)
|
||||
break;
|
||||
|
||||
if (tp->flags & MT_FREE)
|
||||
{
|
||||
memset(tp, 0, sizeof (mr_table_t));
|
||||
return (tp);
|
||||
}
|
||||
tp++;
|
||||
|
||||
if (tp == lastp)
|
||||
tp = mem_table;
|
||||
}
|
||||
while (tp != endp);
|
||||
|
||||
/* wow. entirely full. return mem_overflow dummy entry. */
|
||||
tp = &mem_overflow;
|
||||
memset (tp, 0, sizeof (mr_table_t));
|
||||
return tp;
|
||||
return (mr_table_t *)NULL;
|
||||
}
|
||||
|
||||
mr_table_t *
|
||||
@@ -186,6 +181,8 @@ mregister_alloc (tag, mem, size, file, line)
|
||||
blocked_sigs = 1;
|
||||
}
|
||||
|
||||
mlocation_register_alloc (file, line);
|
||||
|
||||
tentry = find_entry (mem, FIND_ALLOC);
|
||||
|
||||
if (tentry == 0)
|
||||
@@ -293,7 +290,9 @@ _register_dump_table(fp)
|
||||
{
|
||||
entry = mem_table[i];
|
||||
if (entry.mem)
|
||||
fprintf (fp, "[%d] %p:%d:%s:%s:%s:%d:%d:%d\n", i,
|
||||
fprintf (fp, "%s[%d] %p:%zu:%s:%s:%s:%d:%d:%d\n",
|
||||
(i == table_bucket_index) ? "*" : "",
|
||||
i,
|
||||
entry.mem, entry.size,
|
||||
_entry_flags(entry.flags),
|
||||
entry.func ? entry.func : "unknown",
|
||||
@@ -317,6 +316,105 @@ mregister_table_init ()
|
||||
table_count = 0;
|
||||
}
|
||||
|
||||
/* Simple for now */
|
||||
|
||||
static ma_table_t *
|
||||
find_location_entry (file, line)
|
||||
const char *file;
|
||||
int line;
|
||||
{
|
||||
register ma_table_t *tp, *endp;
|
||||
|
||||
endp = mlocation_table + location_table_count;
|
||||
for (tp = mlocation_table; tp <= endp; tp++)
|
||||
{
|
||||
if (tp->line == line && STREQ (file, tp->file))
|
||||
return tp;
|
||||
}
|
||||
return (ma_table_t *)NULL;
|
||||
}
|
||||
|
||||
void
|
||||
mlocation_register_alloc (file, line)
|
||||
const char *file;
|
||||
int line;
|
||||
{
|
||||
ma_table_t *lentry;
|
||||
const char *nfile;
|
||||
|
||||
if (file == 0)
|
||||
{
|
||||
mlocation_table[0].nalloc++;
|
||||
return;
|
||||
}
|
||||
|
||||
nfile = strrchr (file, '/');
|
||||
if (nfile)
|
||||
nfile++;
|
||||
else
|
||||
nfile = file;
|
||||
|
||||
lentry = find_location_entry (nfile, line);
|
||||
if (lentry == 0)
|
||||
{
|
||||
location_table_index++;
|
||||
if (location_table_index == REG_TABLE_SIZE)
|
||||
location_table_index = 1; /* slot 0 reserved */
|
||||
lentry = mlocation_table + location_table_index;
|
||||
lentry->file = nfile;
|
||||
lentry->line = line;
|
||||
lentry->nalloc = 1;
|
||||
if (location_table_count < REG_TABLE_SIZE)
|
||||
location_table_count++; /* clamp at REG_TABLE_SIZE for now */
|
||||
}
|
||||
else
|
||||
lentry->nalloc++;
|
||||
}
|
||||
|
||||
static void
|
||||
_location_dump_table (fp)
|
||||
FILE *fp;
|
||||
{
|
||||
register ma_table_t *tp, *endp;
|
||||
|
||||
endp = mlocation_table + location_table_count;
|
||||
for (tp = mlocation_table; tp < endp; tp++)
|
||||
fprintf (fp, "%s:%d\t%d\n", tp->file ? tp->file : "unknown",
|
||||
tp->line ? tp->line : 0,
|
||||
tp->nalloc);
|
||||
}
|
||||
|
||||
void
|
||||
mlocation_dump_table ()
|
||||
{
|
||||
_location_dump_table (stderr);
|
||||
}
|
||||
|
||||
#define LOCROOT "/var/tmp/maltrace/locations."
|
||||
|
||||
void
|
||||
mlocation_write_table ()
|
||||
{
|
||||
FILE *fp;
|
||||
char defname[sizeof (LOCROOT) + 64];
|
||||
|
||||
fp = _imalloc_fopen ((char *)NULL, (char *)NULL, LOCROOT, defname, sizeof (defname));
|
||||
if (fp == 0)
|
||||
return; /* XXX - no error message yet */
|
||||
_location_dump_table (fp);
|
||||
fclose (fp);
|
||||
}
|
||||
|
||||
void
|
||||
mlocation_table_init ()
|
||||
{
|
||||
memset (mlocation_table, 0, sizeof (ma_table_t) * REG_TABLE_SIZE);
|
||||
mlocation_table[0].file = ""; /* reserve slot 0 for unknown locations */
|
||||
mlocation_table[0].line = 0;
|
||||
mlocation_table[0].nalloc = 0;
|
||||
location_table_count = 1;
|
||||
}
|
||||
|
||||
#endif /* MALLOC_REGISTER */
|
||||
|
||||
int
|
||||
|
||||
@@ -64,6 +64,17 @@ extern void mregister_describe_mem ();
|
||||
extern void mregister_dump_table __P((void));
|
||||
extern void mregister_table_init __P((void));
|
||||
|
||||
typedef struct ma_table {
|
||||
const char *file;
|
||||
int line;
|
||||
int nalloc;
|
||||
} ma_table_t;
|
||||
|
||||
extern void mlocation_register_alloc __P((const char *, int));
|
||||
extern void mlocation_table_init __P((void));
|
||||
extern void mlocation_dump_table __P((void));
|
||||
extern void mlocation_write_table __P((void));
|
||||
|
||||
/* NOTE: HASH_MIX taken from dmalloc (http://dmalloc.com) */
|
||||
|
||||
/*
|
||||
|
||||
@@ -52,10 +52,10 @@ mtrace_alloc (tag, mem, size, file, line)
|
||||
_mtrace_fp = stderr;
|
||||
|
||||
if (_mtrace_verbose)
|
||||
fprintf (_mtrace_fp, "alloc: %s: %p (%d bytes) from '%s:%d'\n",
|
||||
fprintf (_mtrace_fp, "alloc: %s: %p (%zu bytes) from '%s:%d'\n",
|
||||
tag, mem, size, file ? file : "unknown", line);
|
||||
else
|
||||
fprintf (_mtrace_fp, "alloc:%p:%d:%s:%d\n",
|
||||
fprintf (_mtrace_fp, "alloc:%p:%zu:%s:%d\n",
|
||||
mem, size, file ? file : "unknown", line);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user