bsdgrep(1): Rip out "xmalloc" bits

xmalloc was a debug malloc implementation, but the x{malloc,calloc,free}
functions default to calling the malloc(3) equivalents.

Instead of relying on this malloc shim, we can devise better ways to debug
malloc issues that aren't misleading upon initial inspection.  (I.e., using
jemalloc's various built-in debugging capabilities.)

Submitted by:	Kyle Evans <kevans91 at ksu.edu>
Reviewed by:	emaste, cem
Differential Revision:	https://reviews.freebsd.org/D10269
This commit is contained in:
Conrad Meyer 2017-04-04 16:08:51 +00:00
parent a5ed868511
commit 5dc41cb0f2
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=316492
6 changed files with 31 additions and 463 deletions

View File

@ -17,7 +17,7 @@ SRCS= file.c grep.c queue.c util.c
# Extra files ported backported form some regex improvements
.PATH: ${.CURDIR}/regex
SRCS+= fastmatch.c hashtable.c tre-compile.c tre-fastmatch.c xmalloc.c
SRCS+= fastmatch.c hashtable.c tre-compile.c tre-fastmatch.c
CFLAGS+=-I${.CURDIR}/regex
CFLAGS.gcc+= --param max-inline-insns-single=500

View File

@ -34,7 +34,6 @@
#include <string.h>
#include "tre-fastmatch.h"
#include "xmalloc.h"
int
tre_fixncomp(fastmatch_t *preg, const char *regex, size_t n, int cflags)

View File

@ -9,8 +9,6 @@
#include <string.h>
#include <wchar.h>
#include "xmalloc.h"
int
tre_convert_pattern(const char *regex, size_t n, tre_char_t **w,
size_t *wn)
@ -19,7 +17,7 @@ tre_convert_pattern(const char *regex, size_t n, tre_char_t **w,
tre_char_t *wregex;
size_t wlen;
wregex = xmalloc(sizeof(tre_char_t) * (n + 1));
wregex = malloc(sizeof(tre_char_t) * (n + 1));
if (wregex == NULL)
return REG_ESPACE;
@ -60,13 +58,13 @@ tre_convert_pattern(const char *regex, size_t n, tre_char_t **w,
consumed = 1;
else
{
xfree(wregex);
free(wregex);
return REG_BADPAT;
}
break;
case -1:
DPRINT(("mbrtowc: error %d: %s.\n", errno, strerror(errno)));
xfree(wregex);
free(wregex);
return REG_BADPAT;
case -2:
/* The last character wasn't complete. Let's not call it a
@ -98,6 +96,6 @@ void
tre_free_pattern(tre_char_t *wregex)
{
#if TRE_WCHAR
xfree(wregex);
free(wregex);
#endif
}

View File

@ -42,7 +42,6 @@
#include "hashtable.h"
#include "tre-fastmatch.h"
#include "xmalloc.h"
static int fastcmp(const fastmatch_t *fg, const void *data,
tre_str_type_t type);
@ -53,9 +52,9 @@ static int fastcmp(const fastmatch_t *fg, const void *data,
#define FAIL_COMP(errcode) \
{ \
if (fg->pattern) \
xfree(fg->pattern); \
free(fg->pattern); \
if (fg->wpattern) \
xfree(fg->wpattern); \
free(fg->wpattern); \
if (fg->qsBc_table) \
hashtable_free(fg->qsBc_table); \
fg = NULL; \
@ -92,7 +91,7 @@ static int fastcmp(const fastmatch_t *fg, const void *data,
if (siz == (size_t)-1) \
return REG_BADPAT; \
fg->len = siz; \
fg->pattern = xmalloc(siz + 1); \
fg->pattern = malloc(siz + 1); \
if (fg->pattern == NULL) \
return REG_ESPACE; \
wcstombs(fg->pattern, fg->wpattern, siz); \
@ -340,7 +339,7 @@ static int fastcmp(const fastmatch_t *fg, const void *data,
#define FILL_BMGS \
if (!fg->hasdot) \
{ \
fg->sbmGs = xmalloc(fg->len * sizeof(int)); \
fg->sbmGs = malloc(fg->len * sizeof(int)); \
if (!fg->sbmGs) \
return REG_ESPACE; \
if (fg->len == 1) \
@ -356,7 +355,7 @@ static int fastcmp(const fastmatch_t *fg, const void *data,
#define FILL_BMGS_WIDE \
if (!fg->hasdot) \
{ \
fg->bmGs = xmalloc(fg->wlen * sizeof(int)); \
fg->bmGs = malloc(fg->wlen * sizeof(int)); \
if (!fg->bmGs) \
return REG_ESPACE; \
if (fg->wlen == 1) \
@ -376,13 +375,13 @@ static int fastcmp(const fastmatch_t *fg, const void *data,
{ \
if (fg->icase) \
{ \
wp = xmalloc(plen * sizeof(tre_char_t)); \
wp = malloc(plen * sizeof(tre_char_t)); \
if (wp == NULL) \
return REG_ESPACE; \
for (unsigned int i = 0; i < plen; i++) \
wp[i] = towlower(pat[i]); \
_CALC_BMGS(arr, wp, plen); \
xfree(wp); \
free(wp); \
} \
else \
_CALC_BMGS(arr, pat, plen); \
@ -391,13 +390,13 @@ static int fastcmp(const fastmatch_t *fg, const void *data,
{ \
if (fg->icase) \
{ \
p = xmalloc(plen); \
p = malloc(plen); \
if (p == NULL) \
return REG_ESPACE; \
for (unsigned int i = 0; i < plen; i++) \
p[i] = tolower((unsigned char)pat[i]); \
_CALC_BMGS(arr, p, plen); \
xfree(p); \
free(p); \
} \
else \
_CALC_BMGS(arr, pat, plen); \
@ -408,7 +407,7 @@ static int fastcmp(const fastmatch_t *fg, const void *data,
{ \
int f = 0, g; \
\
int *suff = xmalloc(plen * sizeof(int)); \
int *suff = malloc(plen * sizeof(int)); \
if (suff == NULL) \
return REG_ESPACE; \
\
@ -440,7 +439,7 @@ static int fastcmp(const fastmatch_t *fg, const void *data,
for (unsigned int i = 0; i <= plen - 2; i++) \
arr[plen - 1 - suff[i]] = plen - 1 - i; \
\
xfree(suff); \
free(suff); \
}
/*
@ -449,7 +448,7 @@ static int fastcmp(const fastmatch_t *fg, const void *data,
*/
#define SAVE_PATTERN(src, srclen, dst, dstlen) \
dstlen = srclen; \
dst = xmalloc((dstlen + 1) * sizeof(tre_char_t)); \
dst = malloc((dstlen + 1) * sizeof(tre_char_t)); \
if (dst == NULL) \
return REG_ESPACE; \
if (dstlen > 0) \
@ -489,11 +488,11 @@ static int fastcmp(const fastmatch_t *fg, const void *data,
if (n == 0) \
{ \
fg->matchall = true; \
fg->pattern = xmalloc(sizeof(char)); \
fg->pattern = malloc(sizeof(char)); \
if (!fg->pattern) \
FAIL_COMP(REG_ESPACE); \
fg->pattern[0] = '\0'; \
fg->wpattern = xmalloc(sizeof(tre_char_t)); \
fg->wpattern = malloc(sizeof(tre_char_t)); \
if (!fg->wpattern) \
FAIL_COMP(REG_ESPACE); \
fg->wpattern[0] = TRE_CHAR('\0'); \
@ -580,7 +579,7 @@ tre_compile_fast(fastmatch_t *fg, const tre_char_t *pat, size_t n,
if (fg->word && (TRE_MB_CUR_MAX > 1))
return REG_BADPAT;
tmp = xmalloc((n + 1) * sizeof(tre_char_t));
tmp = malloc((n + 1) * sizeof(tre_char_t));
if (tmp == NULL)
return REG_ESPACE;
@ -631,10 +630,10 @@ tre_compile_fast(fastmatch_t *fg, const tre_char_t *pat, size_t n,
if (escaped)
{
if (!_escmap)
_escmap = xmalloc(n * sizeof(bool));
_escmap = malloc(n * sizeof(bool));
if (!_escmap)
{
xfree(tmp);
free(tmp);
return REG_ESPACE;
}
_escmap[i] = true;
@ -688,7 +687,7 @@ tre_compile_fast(fastmatch_t *fg, const tre_char_t *pat, size_t n,
}
continue;
badpat:
xfree(tmp);
free(tmp);
DPRINT(("tre_compile_fast: compilation of pattern failed, falling"
"back to NFA\n"));
return REG_BADPAT;
@ -715,7 +714,7 @@ tre_compile_fast(fastmatch_t *fg, const tre_char_t *pat, size_t n,
{
if (fg->wescmap != NULL)
{
fg->escmap = xmalloc(fg->len * sizeof(bool));
fg->escmap = malloc(fg->len * sizeof(bool));
if (!fg->escmap)
{
tre_free_fast(fg);
@ -746,7 +745,7 @@ tre_compile_fast(fastmatch_t *fg, const tre_char_t *pat, size_t n,
fg->escmap = _escmap;
#endif
xfree(tmp);
free(tmp);
DPRINT(("tre_compile_fast: pattern: %s, len %zu, bol %c, eol %c, "
"icase: %c, word: %c, newline %c\n", fg->pattern, fg->len,
@ -977,16 +976,16 @@ tre_free_fast(fastmatch_t *fg)
#ifdef TRE_WCHAR
hashtable_free(fg->qsBc_table);
if (!fg->hasdot)
xfree(fg->bmGs);
free(fg->bmGs);
if (fg->wescmap)
xfree(fg->wescmap);
xfree(fg->wpattern);
free(fg->wescmap);
free(fg->wpattern);
#endif
if (!fg->hasdot)
xfree(fg->sbmGs);
free(fg->sbmGs);
if (fg->escmap)
xfree(fg->escmap);
xfree(fg->pattern);
free(fg->escmap);
free(fg->pattern);
}
/*

View File

@ -1,349 +0,0 @@
/* $FreeBSD$ */
/*
xmalloc.c - Simple malloc debugging library implementation
This software is released under a BSD-style license.
See the file LICENSE for details and copyright.
*/
/*
TODO:
- red zones
- group dumps by source location
*/
#include <stdlib.h>
#include <assert.h>
#include <stdio.h>
#define XMALLOC_INTERNAL 1
#include "xmalloc.h"
/*
Internal stuff.
*/
typedef struct hashTableItemRec {
void *ptr;
int bytes;
const char *file;
int line;
const char *func;
struct hashTableItemRec *next;
} hashTableItem;
typedef struct {
hashTableItem **table;
} hashTable;
static int xmalloc_peak;
static int xmalloc_current;
static int xmalloc_peak_blocks;
static int xmalloc_current_blocks;
static int xmalloc_fail_after;
#define TABLE_BITS 8
#define TABLE_MASK ((1 << TABLE_BITS) - 1)
#define TABLE_SIZE (1 << TABLE_BITS)
static hashTable *
hash_table_new(void)
{
hashTable *tbl;
tbl = malloc(sizeof(*tbl));
if (tbl != NULL)
{
tbl->table = calloc(TABLE_SIZE, sizeof(*tbl->table));
if (tbl->table == NULL)
{
free(tbl);
return NULL;
}
}
return tbl;
}
static int
hash_void_ptr(void *ptr)
{
int hash;
int i;
/* I took this hash function just off the top of my head, I have
no idea whether it is bad or very bad. */
hash = 0;
for (i = 0; i < (int)sizeof(ptr)*8 / TABLE_BITS; i++)
{
hash ^= (unsigned long)ptr >> i*8;
hash += i * 17;
hash &= TABLE_MASK;
}
return hash;
}
static void
hash_table_add(hashTable *tbl, void *ptr, int bytes,
const char *file, int line, const char *func)
{
int i;
hashTableItem *item, *new;
i = hash_void_ptr(ptr);
item = tbl->table[i];
if (item != NULL)
while (item->next != NULL)
item = item->next;
new = malloc(sizeof(*new));
assert(new != NULL);
new->ptr = ptr;
new->bytes = bytes;
new->file = file;
new->line = line;
new->func = func;
new->next = NULL;
if (item != NULL)
item->next = new;
else
tbl->table[i] = new;
xmalloc_current += bytes;
if (xmalloc_current > xmalloc_peak)
xmalloc_peak = xmalloc_current;
xmalloc_current_blocks++;
if (xmalloc_current_blocks > xmalloc_peak_blocks)
xmalloc_peak_blocks = xmalloc_current_blocks;
}
static void
hash_table_del(hashTable *tbl, void *ptr)
{
int i;
hashTableItem *item, *prev;
i = hash_void_ptr(ptr);
item = tbl->table[i];
if (item == NULL)
{
printf("xfree: invalid ptr %p\n", ptr);
abort();
}
prev = NULL;
while (item->ptr != ptr)
{
prev = item;
item = item->next;
}
if (item->ptr != ptr)
{
printf("xfree: invalid ptr %p\n", ptr);
abort();
}
xmalloc_current -= item->bytes;
xmalloc_current_blocks--;
if (prev != NULL)
{
prev->next = item->next;
free(item);
}
else
{
tbl->table[i] = item->next;
free(item);
}
}
static hashTable *xmalloc_table = NULL;
static void
xmalloc_init(void)
{
if (xmalloc_table == NULL)
{
xmalloc_table = hash_table_new();
xmalloc_peak = 0;
xmalloc_peak_blocks = 0;
xmalloc_current = 0;
xmalloc_current_blocks = 0;
xmalloc_fail_after = -1;
}
assert(xmalloc_table != NULL);
assert(xmalloc_table->table != NULL);
}
/*
Public API.
*/
void
xmalloc_configure(int fail_after)
{
xmalloc_init();
xmalloc_fail_after = fail_after;
}
int
xmalloc_dump_leaks(void)
{
int i;
int num_leaks = 0;
int leaked_bytes = 0;
hashTableItem *item;
xmalloc_init();
for (i = 0; i < TABLE_SIZE; i++)
{
item = xmalloc_table->table[i];
while (item != NULL)
{
printf("%s:%d: %s: %d bytes at %p not freed\n",
item->file, item->line, item->func, item->bytes, item->ptr);
num_leaks++;
leaked_bytes += item->bytes;
item = item->next;
}
}
if (num_leaks == 0)
printf("No memory leaks.\n");
else
printf("%d unfreed memory chuncks, total %d unfreed bytes.\n",
num_leaks, leaked_bytes);
printf("Peak memory consumption %d bytes (%.1f kB, %.1f MB) in %d blocks ",
xmalloc_peak, (double)xmalloc_peak / 1024,
(double)xmalloc_peak / (1024*1024), xmalloc_peak_blocks);
printf("(average ");
if (xmalloc_peak_blocks)
printf("%d", ((xmalloc_peak + xmalloc_peak_blocks / 2)
/ xmalloc_peak_blocks));
else
printf("N/A");
printf(" bytes per block).\n");
return num_leaks;
}
void *
xmalloc_impl(size_t size, const char *file, int line, const char *func)
{
void *ptr;
xmalloc_init();
assert(size > 0);
if (xmalloc_fail_after == 0)
{
xmalloc_fail_after = -2;
#if 0
printf("xmalloc: forced failure %s:%d: %s\n", file, line, func);
#endif
return NULL;
}
else if (xmalloc_fail_after == -2)
{
printf("xmalloc: called after failure from %s:%d: %s\n",
file, line, func);
assert(0);
}
else if (xmalloc_fail_after > 0)
xmalloc_fail_after--;
ptr = malloc(size);
if (ptr != NULL)
hash_table_add(xmalloc_table, ptr, (int)size, file, line, func);
return ptr;
}
void *
xcalloc_impl(size_t nmemb, size_t size, const char *file, int line,
const char *func)
{
void *ptr;
xmalloc_init();
assert(size > 0);
if (xmalloc_fail_after == 0)
{
xmalloc_fail_after = -2;
#if 0
printf("xcalloc: forced failure %s:%d: %s\n", file, line, func);
#endif
return NULL;
}
else if (xmalloc_fail_after == -2)
{
printf("xcalloc: called after failure from %s:%d: %s\n",
file, line, func);
assert(0);
}
else if (xmalloc_fail_after > 0)
xmalloc_fail_after--;
ptr = calloc(nmemb, size);
if (ptr != NULL)
hash_table_add(xmalloc_table, ptr, (int)(nmemb * size), file, line, func);
return ptr;
}
void
xfree_impl(void *ptr, const char *file, int line, const char *func)
{
/*LINTED*/(void)&file;
/*LINTED*/(void)&line;
/*LINTED*/(void)&func;
xmalloc_init();
if (ptr != NULL)
hash_table_del(xmalloc_table, ptr);
free(ptr);
}
void *
xrealloc_impl(void *ptr, size_t new_size, const char *file, int line,
const char *func)
{
void *new_ptr;
xmalloc_init();
assert(ptr != NULL);
assert(new_size > 0);
if (xmalloc_fail_after == 0)
{
xmalloc_fail_after = -2;
return NULL;
}
else if (xmalloc_fail_after == -2)
{
printf("xrealloc: called after failure from %s:%d: %s\n",
file, line, func);
assert(0);
}
else if (xmalloc_fail_after > 0)
xmalloc_fail_after--;
new_ptr = realloc(ptr, new_size);
if (new_ptr != NULL)
{
hash_table_del(xmalloc_table, ptr);
hash_table_add(xmalloc_table, new_ptr, (int)new_size, file, line, func);
}
return new_ptr;
}
/* EOF */

View File

@ -1,79 +0,0 @@
/* $FreeBSD$ */
/*
xmalloc.h - Simple malloc debugging library API
This software is released under a BSD-style license.
See the file LICENSE for details and copyright.
*/
#ifndef _XMALLOC_H
#define _XMALLOC_H 1
void *xmalloc_impl(size_t size, const char *file, int line, const char *func);
void *xcalloc_impl(size_t nmemb, size_t size, const char *file, int line,
const char *func);
void xfree_impl(void *ptr, const char *file, int line, const char *func);
void *xrealloc_impl(void *ptr, size_t new_size, const char *file, int line,
const char *func);
int xmalloc_dump_leaks(void);
void xmalloc_configure(int fail_after);
#ifndef XMALLOC_INTERNAL
#ifdef MALLOC_DEBUGGING
/* Version 2.4 and later of GCC define a magical variable `__PRETTY_FUNCTION__'
which contains the name of the function currently being defined.
# define __XMALLOC_FUNCTION __PRETTY_FUNCTION__
This is broken in G++ before version 2.6.
C9x has a similar variable called __func__, but prefer the GCC one since
it demangles C++ function names. */
# ifdef __GNUC__
# if __GNUC__ > 2 || (__GNUC__ == 2 \
&& __GNUC_MINOR__ >= (defined __cplusplus ? 6 : 4))
# define __XMALLOC_FUNCTION __PRETTY_FUNCTION__
# else
# define __XMALLOC_FUNCTION ((const char *) 0)
# endif
# else
# if defined __STDC_VERSION__ && __STDC_VERSION__ >= 199901L
# define __XMALLOC_FUNCTION __func__
# else
# define __XMALLOC_FUNCTION ((const char *) 0)
# endif
# endif
#define xmalloc(size) xmalloc_impl(size, __FILE__, __LINE__, \
__XMALLOC_FUNCTION)
#define xcalloc(nmemb, size) xcalloc_impl(nmemb, size, __FILE__, __LINE__, \
__XMALLOC_FUNCTION)
#define xfree(ptr) xfree_impl(ptr, __FILE__, __LINE__, __XMALLOC_FUNCTION)
#define xrealloc(ptr, new_size) xrealloc_impl(ptr, new_size, __FILE__, \
__LINE__, __XMALLOC_FUNCTION)
#undef malloc
#undef calloc
#undef free
#undef realloc
#define malloc USE_XMALLOC_INSTEAD_OF_MALLOC
#define calloc USE_XCALLOC_INSTEAD_OF_CALLOC
#define free USE_XFREE_INSTEAD_OF_FREE
#define realloc USE_XREALLOC_INSTEAD_OF_REALLOC
#else /* !MALLOC_DEBUGGING */
#include <stdlib.h>
#define xmalloc(size) malloc(size)
#define xcalloc(nmemb, size) calloc(nmemb, size)
#define xfree(ptr) free(ptr)
#define xrealloc(ptr, new_size) realloc(ptr, new_size)
#endif /* !MALLOC_DEBUGGING */
#endif /* !XMALLOC_INTERNAL */
#endif /* _XMALLOC_H */
/* EOF */