Introduce memory allocation wrappers
Introduce wrappers to the following functions that do memory allocation: malloc, calloc, realloc, strdup. This commit is a follow-up to the related discussions in strace-devel ML: http://sourceforge.net/p/strace/mailman/message/33618180/ http://sourceforge.net/p/strace/mailman/message/33733470/ * defs.h (xmalloc, xcalloc, xreallocarray, xstrdup): New prototypes. * xmalloc.c: New file. * Makefile.am (strace_SOURCES): Add it. * count.c (count_syscall, call_summary_pers): Use xcalloc. * desc.c (decode_select): Use xmalloc. * dirent.c (sys_getdents, sys_getdents64): Likewise. * net.c (sys_recvmmsg): Use xstrdup. * pathtrace.c (storepath): Use xreallocarray. (pathtrace_match): Use xmalloc. * strace.c (die_out_of_memory): Move to xmalloc.c. (expand_tcbtab): Use xcalloc and xreallocarray. (startup_child): Use xstrdup. (init): Use xmalloc, xcalloc, and xstrdup. * syscall.c (reallocate_qual): Use xreallocarray. (qualify): Use xstrdup. * unwind.c (unwind_tcb_init): Use xmalloc. (build_mmap_cache): Use xcalloc, xreallocarray, and xstrdup. (get_symbol_name): Use xreallocarray. (stacktrace_walk, queue_put): Use xmalloc. * util.c (printstr): Use xmalloc. * vsprintf.c (strace_vfprintf): Likewise.
This commit is contained in:
parent
8c20d8926c
commit
3e9d71feaa
@ -123,7 +123,8 @@ strace_SOURCES = \
|
||||
v4l2.c \
|
||||
vsprintf.c \
|
||||
wait.c \
|
||||
xattr.c
|
||||
xattr.c \
|
||||
xmalloc.c
|
||||
|
||||
if USE_LIBUNWIND
|
||||
strace_SOURCES += unwind.c
|
||||
|
11
count.c
11
count.c
@ -58,11 +58,8 @@ count_syscall(struct tcb *tcp, const struct timeval *syscall_exiting_tv)
|
||||
if (!SCNO_IN_RANGE(scno))
|
||||
return;
|
||||
|
||||
if (!counts) {
|
||||
counts = calloc(nsyscalls, sizeof(*counts));
|
||||
if (!counts)
|
||||
die_out_of_memory();
|
||||
}
|
||||
if (!counts)
|
||||
counts = xcalloc(nsyscalls, sizeof(*counts));
|
||||
cc = &counts[scno];
|
||||
|
||||
cc->calls++;
|
||||
@ -171,9 +168,7 @@ call_summary_pers(FILE *outf)
|
||||
fprintf(outf, "%6.6s %11.11s %11.11s %9.9s %9.9s %s\n",
|
||||
dashes, dashes, dashes, dashes, dashes, dashes);
|
||||
|
||||
sorted_count = calloc(sizeof(int), nsyscalls);
|
||||
if (!sorted_count)
|
||||
die_out_of_memory();
|
||||
sorted_count = xcalloc(sizeof(int), nsyscalls);
|
||||
call_cum = error_cum = tv_cum.tv_sec = tv_cum.tv_usec = 0;
|
||||
if (overhead.tv_sec == -1) {
|
||||
tv_mul(&overhead, &shortest, 8);
|
||||
|
7
defs.h
7
defs.h
@ -434,6 +434,13 @@ void perror_msg_and_die(const char *fmt, ...)
|
||||
ATTRIBUTE_FORMAT((printf, 1, 2)) ATTRIBUTE_NORETURN;
|
||||
void die_out_of_memory(void) ATTRIBUTE_NORETURN;
|
||||
|
||||
void *xmalloc(size_t size) ATTRIBUTE_MALLOC ATTRIBUTE_ALLOC_SIZE((1));
|
||||
void *xcalloc(size_t nmemb, size_t size)
|
||||
ATTRIBUTE_MALLOC ATTRIBUTE_ALLOC_SIZE((1, 2));
|
||||
void *xreallocarray(void *ptr, size_t nmemb, size_t size)
|
||||
ATTRIBUTE_ALLOC_SIZE((2, 3));
|
||||
char *xstrdup(const char *str) ATTRIBUTE_MALLOC;
|
||||
|
||||
#if USE_CUSTOM_PRINTF
|
||||
/*
|
||||
* See comment in vsprintf.c for allowed formats.
|
||||
|
11
desc.c
11
desc.c
@ -331,11 +331,8 @@ decode_select(struct tcb *tcp, long *args, enum bitness_t bitness)
|
||||
if (entering(tcp)) {
|
||||
tprintf("%d", (int) args[0]);
|
||||
|
||||
if (verbose(tcp) && fdsize > 0) {
|
||||
fds = malloc(fdsize);
|
||||
if (!fds)
|
||||
die_out_of_memory();
|
||||
}
|
||||
if (verbose(tcp) && fdsize > 0)
|
||||
fds = xmalloc(fdsize);
|
||||
for (i = 0; i < 3; i++) {
|
||||
arg = args[i+1];
|
||||
if (arg == 0) {
|
||||
@ -380,9 +377,7 @@ decode_select(struct tcb *tcp, long *args, enum bitness_t bitness)
|
||||
return RVAL_STR;
|
||||
}
|
||||
|
||||
fds = malloc(fdsize);
|
||||
if (!fds)
|
||||
die_out_of_memory();
|
||||
fds = xmalloc(fdsize);
|
||||
|
||||
outptr = outstr;
|
||||
sep = "";
|
||||
|
8
dirent.c
8
dirent.c
@ -81,9 +81,7 @@ SYS_FUNC(getdents)
|
||||
len = tcp->u_rval;
|
||||
|
||||
if (len) {
|
||||
buf = malloc(len);
|
||||
if (!buf)
|
||||
die_out_of_memory();
|
||||
buf = xmalloc(len);
|
||||
if (umoven(tcp, tcp->u_arg[1], len, buf) < 0) {
|
||||
tprintf("%#lx, %lu", tcp->u_arg[1], tcp->u_arg[2]);
|
||||
free(buf);
|
||||
@ -164,9 +162,7 @@ SYS_FUNC(getdents64)
|
||||
len = tcp->u_rval;
|
||||
|
||||
if (len) {
|
||||
buf = malloc(len);
|
||||
if (!buf)
|
||||
die_out_of_memory();
|
||||
buf = xmalloc(len);
|
||||
if (umoven(tcp, tcp->u_arg[1], len, buf) < 0) {
|
||||
tprintf("%#lx, %lu", tcp->u_arg[1], tcp->u_arg[2]);
|
||||
free(buf);
|
||||
|
2
net.c
2
net.c
@ -995,7 +995,7 @@ SYS_FUNC(recvmmsg)
|
||||
/* Abusing tcp->auxstr as temp storage.
|
||||
* Will be used and freed on syscall exit.
|
||||
*/
|
||||
tcp->auxstr = strdup(str);
|
||||
tcp->auxstr = xstrdup(str);
|
||||
} else {
|
||||
tprintf("%#lx, %ld, ", tcp->u_arg[1], tcp->u_arg[2]);
|
||||
printflags(msg_flags, tcp->u_arg[3], "MSG_???");
|
||||
|
@ -91,9 +91,8 @@ storepath(const char *path)
|
||||
return; /* already in table */
|
||||
|
||||
i = num_selected++;
|
||||
paths_selected = realloc(paths_selected, num_selected * sizeof(paths_selected[0]));
|
||||
if (!paths_selected)
|
||||
die_out_of_memory();
|
||||
paths_selected = xreallocarray(paths_selected, num_selected,
|
||||
sizeof(paths_selected[0]));
|
||||
paths_selected[i] = path;
|
||||
}
|
||||
|
||||
@ -287,9 +286,7 @@ pathtrace_match(struct tcb *tcp)
|
||||
if (nfds > 1024*1024)
|
||||
nfds = 1024*1024;
|
||||
fdsize = (((nfds + 7) / 8) + current_wordsize-1) & -current_wordsize;
|
||||
fds = malloc(fdsize);
|
||||
if (!fds)
|
||||
die_out_of_memory();
|
||||
fds = xmalloc(fdsize);
|
||||
|
||||
for (i = 1; i <= 3; ++i) {
|
||||
if (args[i] == 0)
|
||||
|
38
strace.c
38
strace.c
@ -324,15 +324,6 @@ void perror_msg_and_die(const char *fmt, ...)
|
||||
die();
|
||||
}
|
||||
|
||||
void die_out_of_memory(void)
|
||||
{
|
||||
static bool recursed = 0;
|
||||
if (recursed)
|
||||
exit(1);
|
||||
recursed = 1;
|
||||
error_msg_and_die("Out of memory");
|
||||
}
|
||||
|
||||
static void
|
||||
error_opt_arg(int opt, const char *arg)
|
||||
{
|
||||
@ -676,10 +667,9 @@ expand_tcbtab(void)
|
||||
So tcbtab is a table of pointers. Since we never
|
||||
free the TCBs, we allocate a single chunk of many. */
|
||||
unsigned int i = tcbtabsize;
|
||||
struct tcb *newtcbs = calloc(tcbtabsize, sizeof(newtcbs[0]));
|
||||
struct tcb **newtab = realloc(tcbtab, tcbtabsize * 2 * sizeof(tcbtab[0]));
|
||||
if (!newtab || !newtcbs)
|
||||
die_out_of_memory();
|
||||
struct tcb *newtcbs = xcalloc(tcbtabsize, sizeof(newtcbs[0]));
|
||||
struct tcb **newtab = xreallocarray(tcbtab, tcbtabsize * 2,
|
||||
sizeof(tcbtab[0]));
|
||||
tcbtabsize *= 2;
|
||||
tcbtab = newtab;
|
||||
while (i < tcbtabsize)
|
||||
@ -1233,7 +1223,7 @@ startup_child(char **argv)
|
||||
* On NOMMU, can be safely freed only after execve in tracee.
|
||||
* It's hard to know when that happens, so we just leak it.
|
||||
*/
|
||||
params_for_tracee.pathname = NOMMU_SYSTEM ? strdup(pathname) : pathname;
|
||||
params_for_tracee.pathname = NOMMU_SYSTEM ? xstrdup(pathname) : pathname;
|
||||
|
||||
#if defined HAVE_PRCTL && defined PR_SET_PTRACER && defined PR_SET_PTRACER_ANY
|
||||
if (daemonized_tracer)
|
||||
@ -1445,12 +1435,8 @@ init(int argc, char *argv[])
|
||||
|
||||
/* Allocate the initial tcbtab. */
|
||||
tcbtabsize = argc; /* Surely enough for all -p args. */
|
||||
tcbtab = calloc(tcbtabsize, sizeof(tcbtab[0]));
|
||||
if (!tcbtab)
|
||||
die_out_of_memory();
|
||||
tcp = calloc(tcbtabsize, sizeof(*tcp));
|
||||
if (!tcp)
|
||||
die_out_of_memory();
|
||||
tcbtab = xcalloc(tcbtabsize, sizeof(tcbtab[0]));
|
||||
tcp = xcalloc(tcbtabsize, sizeof(*tcp));
|
||||
for (tcbi = 0; tcbi < tcbtabsize; tcbi++)
|
||||
tcbtab[tcbi] = tcp++;
|
||||
|
||||
@ -1548,7 +1534,7 @@ init(int argc, char *argv[])
|
||||
qualify(optarg);
|
||||
break;
|
||||
case 'o':
|
||||
outfname = strdup(optarg);
|
||||
outfname = xstrdup(optarg);
|
||||
break;
|
||||
case 'O':
|
||||
i = string_to_uint(optarg);
|
||||
@ -1572,7 +1558,7 @@ init(int argc, char *argv[])
|
||||
set_sortby(optarg);
|
||||
break;
|
||||
case 'u':
|
||||
username = strdup(optarg);
|
||||
username = xstrdup(optarg);
|
||||
break;
|
||||
#ifdef USE_LIBUNWIND
|
||||
case 'k':
|
||||
@ -1596,9 +1582,7 @@ init(int argc, char *argv[])
|
||||
argv += optind;
|
||||
/* argc -= optind; - no need, argc is not used below */
|
||||
|
||||
acolumn_spaces = malloc(acolumn + 1);
|
||||
if (!acolumn_spaces)
|
||||
die_out_of_memory();
|
||||
acolumn_spaces = xmalloc(acolumn + 1);
|
||||
memset(acolumn_spaces, ' ', acolumn);
|
||||
acolumn_spaces[acolumn] = '\0';
|
||||
|
||||
@ -1691,9 +1675,7 @@ init(int argc, char *argv[])
|
||||
}
|
||||
|
||||
if (!outfname || outfname[0] == '|' || outfname[0] == '!') {
|
||||
char *buf = malloc(BUFSIZ);
|
||||
if (!buf)
|
||||
die_out_of_memory();
|
||||
char *buf = xmalloc(BUFSIZ);
|
||||
setvbuf(shared_log, buf, _IOLBF, BUFSIZ);
|
||||
}
|
||||
if (outfname && argv[0]) {
|
||||
|
@ -381,9 +381,8 @@ reallocate_qual(const unsigned int n)
|
||||
unsigned p;
|
||||
qualbits_t *qp;
|
||||
for (p = 0; p < SUPPORTED_PERSONALITIES; p++) {
|
||||
qp = qual_vec[p] = realloc(qual_vec[p], n * sizeof(qualbits_t));
|
||||
if (!qp)
|
||||
die_out_of_memory();
|
||||
qp = qual_vec[p] = xreallocarray(qual_vec[p], n,
|
||||
sizeof(qualbits_t));
|
||||
memset(&qp[num_quals], 0, (n - num_quals) * sizeof(qualbits_t));
|
||||
}
|
||||
num_quals = n;
|
||||
@ -531,9 +530,7 @@ qualify(const char *s)
|
||||
for (i = 0; i < num_quals; i++) {
|
||||
qualify_one(i, opt->bitflag, !not, -1);
|
||||
}
|
||||
copy = strdup(s);
|
||||
if (!copy)
|
||||
die_out_of_memory();
|
||||
copy = xstrdup(s);
|
||||
for (p = strtok(copy, ","); p; p = strtok(NULL, ",")) {
|
||||
int n;
|
||||
if (opt->bitflag == QUAL_TRACE && (n = lookup_class(p)) > 0) {
|
||||
|
31
unwind.c
31
unwind.c
@ -107,9 +107,7 @@ unwind_tcb_init(struct tcb *tcp)
|
||||
if (!tcp->libunwind_ui)
|
||||
die_out_of_memory();
|
||||
|
||||
tcp->queue = malloc(sizeof(*tcp->queue));
|
||||
if (!tcp->queue)
|
||||
die_out_of_memory();
|
||||
tcp->queue = xmalloc(sizeof(*tcp->queue));
|
||||
tcp->queue->head = NULL;
|
||||
tcp->queue->tail = NULL;
|
||||
}
|
||||
@ -152,9 +150,7 @@ build_mmap_cache(struct tcb* tcp)
|
||||
return;
|
||||
}
|
||||
|
||||
cache_head = calloc(cur_array_size, sizeof(*cache_head));
|
||||
if (!cache_head)
|
||||
die_out_of_memory();
|
||||
cache_head = xcalloc(cur_array_size, sizeof(*cache_head));
|
||||
|
||||
while (fgets(buffer, sizeof(buffer), fp) != NULL) {
|
||||
struct mmap_cache_t *entry;
|
||||
@ -197,19 +193,15 @@ build_mmap_cache(struct tcb* tcp)
|
||||
|
||||
if (tcp->mmap_cache_size >= cur_array_size) {
|
||||
cur_array_size *= 2;
|
||||
cache_head = realloc(cache_head,
|
||||
cur_array_size * sizeof(*cache_head));
|
||||
if (!cache_head)
|
||||
die_out_of_memory();
|
||||
cache_head = xreallocarray(cache_head, cur_array_size,
|
||||
sizeof(*cache_head));
|
||||
}
|
||||
|
||||
entry = &cache_head[tcp->mmap_cache_size];
|
||||
entry->start_addr = start_addr;
|
||||
entry->end_addr = end_addr;
|
||||
entry->mmap_offset = mmap_offset;
|
||||
entry->binary_filename = strdup(binary_path);
|
||||
if (!entry->binary_filename)
|
||||
die_out_of_memory();
|
||||
entry->binary_filename = xstrdup(binary_path);
|
||||
tcp->mmap_cache_size++;
|
||||
}
|
||||
fclose(fp);
|
||||
@ -290,10 +282,8 @@ get_symbol_name(unw_cursor_t *cursor, char **name,
|
||||
*offset = 0;
|
||||
break;
|
||||
}
|
||||
*name = xreallocarray(*name, 2, *size);
|
||||
*size *= 2;
|
||||
*name = realloc(*name, *size);
|
||||
if (!*name)
|
||||
die_out_of_memory();
|
||||
}
|
||||
}
|
||||
|
||||
@ -372,9 +362,7 @@ stacktrace_walk(struct tcb *tcp,
|
||||
if (tcp->mmap_cache_size == 0)
|
||||
error_msg_and_die("bug: mmap_cache is empty");
|
||||
|
||||
symbol_name = malloc(symbol_name_size);
|
||||
if (!symbol_name)
|
||||
die_out_of_memory();
|
||||
symbol_name = xmalloc(symbol_name_size);
|
||||
|
||||
if (unw_init_remote(&cursor, libunwind_as, tcp->libunwind_ui) < 0)
|
||||
perror_msg_and_die("Can't initiate libunwind");
|
||||
@ -490,10 +478,7 @@ queue_put(struct queue_t *queue,
|
||||
{
|
||||
struct call_t *call;
|
||||
|
||||
call = malloc(sizeof(*call));
|
||||
if (!call)
|
||||
die_out_of_memory();
|
||||
|
||||
call = xmalloc(sizeof(*call));
|
||||
call->output_line = sprint_call_or_error(binary_filename,
|
||||
symbol_name,
|
||||
function_offset,
|
||||
|
8
util.c
8
util.c
@ -763,12 +763,8 @@ printstr(struct tcb *tcp, long addr, long len)
|
||||
|
||||
if (outstr_size / 4 != max_strlen)
|
||||
die_out_of_memory();
|
||||
str = malloc(max_strlen + 1);
|
||||
if (!str)
|
||||
die_out_of_memory();
|
||||
outstr = malloc(outstr_size);
|
||||
if (!outstr)
|
||||
die_out_of_memory();
|
||||
str = xmalloc(max_strlen + 1);
|
||||
outstr = xmalloc(outstr_size);
|
||||
}
|
||||
|
||||
size = max_strlen;
|
||||
|
@ -776,9 +776,7 @@ int strace_vfprintf(FILE *fp, const char *fmt, va_list args)
|
||||
if (len >= buflen) {
|
||||
buflen = len + 256;
|
||||
free(buf);
|
||||
buf = malloc(buflen);
|
||||
if (!buf)
|
||||
die_out_of_memory();
|
||||
buf = xmalloc(buflen);
|
||||
/*len =*/ kernel_vsnprintf(buf, buflen, fmt, args);
|
||||
}
|
||||
|
||||
|
60
xmalloc.c
Normal file
60
xmalloc.c
Normal file
@ -0,0 +1,60 @@
|
||||
#include "defs.h"
|
||||
|
||||
void die_out_of_memory(void)
|
||||
{
|
||||
static bool recursed = false;
|
||||
|
||||
if (recursed)
|
||||
exit(1);
|
||||
recursed = 1;
|
||||
|
||||
error_msg_and_die("Out of memory");
|
||||
}
|
||||
|
||||
void *xmalloc(size_t size)
|
||||
{
|
||||
void *p = malloc(size);
|
||||
|
||||
if (!p)
|
||||
die_out_of_memory();
|
||||
|
||||
return p;
|
||||
}
|
||||
|
||||
void *xcalloc(size_t nmemb, size_t size)
|
||||
{
|
||||
void *p = calloc(nmemb, size);
|
||||
|
||||
if (!p)
|
||||
die_out_of_memory();
|
||||
|
||||
return p;
|
||||
}
|
||||
|
||||
#define HALF_SIZE_T (((size_t) 1) << (sizeof(size_t) * 4))
|
||||
|
||||
void *xreallocarray(void *ptr, size_t nmemb, size_t size)
|
||||
{
|
||||
size_t bytes = nmemb * size;
|
||||
|
||||
if ((nmemb | size) >= HALF_SIZE_T &&
|
||||
size && bytes / size != nmemb)
|
||||
die_out_of_memory();
|
||||
|
||||
void *p = realloc(ptr, bytes);
|
||||
|
||||
if (!p)
|
||||
die_out_of_memory();
|
||||
|
||||
return p;
|
||||
}
|
||||
|
||||
char *xstrdup(const char *str)
|
||||
{
|
||||
char *p = strdup(str);
|
||||
|
||||
if (!p)
|
||||
die_out_of_memory();
|
||||
|
||||
return p;
|
||||
}
|
Loading…
Reference in New Issue
Block a user