summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Makefile.am3
-rw-r--r--count.c11
-rw-r--r--defs.h7
-rw-r--r--desc.c11
-rw-r--r--dirent.c8
-rw-r--r--net.c2
-rw-r--r--pathtrace.c9
-rw-r--r--strace.c38
-rw-r--r--syscall.c9
-rw-r--r--unwind.c31
-rw-r--r--util.c8
-rw-r--r--vsprintf.c4
-rw-r--r--xmalloc.c60
13 files changed, 105 insertions, 96 deletions
diff --git a/Makefile.am b/Makefile.am
index d4be76f6d..e2a0f747f 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -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
diff --git a/count.c b/count.c
index 25921b257..1232d3dbf 100644
--- a/count.c
+++ b/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);
diff --git a/defs.h b/defs.h
index 77c819c62..c02f81039 100644
--- a/defs.h
+++ b/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.
diff --git a/desc.c b/desc.c
index 1b9dd1a5f..e1d01dc4e 100644
--- a/desc.c
+++ b/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 = "";
diff --git a/dirent.c b/dirent.c
index 32f04b9e9..988d535c0 100644
--- a/dirent.c
+++ b/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);
diff --git a/net.c b/net.c
index 2ed950de3..0a3c601fb 100644
--- a/net.c
+++ b/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_???");
diff --git a/pathtrace.c b/pathtrace.c
index 0db7fe31d..894dd5c96 100644
--- a/pathtrace.c
+++ b/pathtrace.c
@@ -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)
diff --git a/strace.c b/strace.c
index 5eab36031..0bffd5e18 100644
--- a/strace.c
+++ b/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]) {
diff --git a/syscall.c b/syscall.c
index b63a5280f..1a9c5fc29 100644
--- a/syscall.c
+++ b/syscall.c
@@ -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) {
diff --git a/unwind.c b/unwind.c
index 6f422a1cf..7c091f1b9 100644
--- a/unwind.c
+++ b/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,
diff --git a/util.c b/util.c
index 6afafbbf6..9dad3f1a6 100644
--- a/util.c
+++ b/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;
diff --git a/vsprintf.c b/vsprintf.c
index 0125e7205..aae40db30 100644
--- a/vsprintf.c
+++ b/vsprintf.c
@@ -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);
}
diff --git a/xmalloc.c b/xmalloc.c
new file mode 100644
index 000000000..c852f5530
--- /dev/null
+++ b/xmalloc.c
@@ -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;
+}