Skip to content

Commit 3e9d71f

Browse files
committed
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.
1 parent 8c20d89 commit 3e9d71f

File tree

13 files changed

+105
-96
lines changed

13 files changed

+105
-96
lines changed

Makefile.am

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -123,7 +123,8 @@ strace_SOURCES = \
123123
v4l2.c \
124124
vsprintf.c \
125125
wait.c \
126-
xattr.c
126+
xattr.c \
127+
xmalloc.c
127128

128129
if USE_LIBUNWIND
129130
strace_SOURCES += unwind.c

count.c

Lines changed: 3 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -58,11 +58,8 @@ count_syscall(struct tcb *tcp, const struct timeval *syscall_exiting_tv)
5858
if (!SCNO_IN_RANGE(scno))
5959
return;
6060

61-
if (!counts) {
62-
counts = calloc(nsyscalls, sizeof(*counts));
63-
if (!counts)
64-
die_out_of_memory();
65-
}
61+
if (!counts)
62+
counts = xcalloc(nsyscalls, sizeof(*counts));
6663
cc = &counts[scno];
6764

6865
cc->calls++;
@@ -171,9 +168,7 @@ call_summary_pers(FILE *outf)
171168
fprintf(outf, "%6.6s %11.11s %11.11s %9.9s %9.9s %s\n",
172169
dashes, dashes, dashes, dashes, dashes, dashes);
173170

174-
sorted_count = calloc(sizeof(int), nsyscalls);
175-
if (!sorted_count)
176-
die_out_of_memory();
171+
sorted_count = xcalloc(sizeof(int), nsyscalls);
177172
call_cum = error_cum = tv_cum.tv_sec = tv_cum.tv_usec = 0;
178173
if (overhead.tv_sec == -1) {
179174
tv_mul(&overhead, &shortest, 8);

defs.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -434,6 +434,13 @@ void perror_msg_and_die(const char *fmt, ...)
434434
ATTRIBUTE_FORMAT((printf, 1, 2)) ATTRIBUTE_NORETURN;
435435
void die_out_of_memory(void) ATTRIBUTE_NORETURN;
436436

437+
void *xmalloc(size_t size) ATTRIBUTE_MALLOC ATTRIBUTE_ALLOC_SIZE((1));
438+
void *xcalloc(size_t nmemb, size_t size)
439+
ATTRIBUTE_MALLOC ATTRIBUTE_ALLOC_SIZE((1, 2));
440+
void *xreallocarray(void *ptr, size_t nmemb, size_t size)
441+
ATTRIBUTE_ALLOC_SIZE((2, 3));
442+
char *xstrdup(const char *str) ATTRIBUTE_MALLOC;
443+
437444
#if USE_CUSTOM_PRINTF
438445
/*
439446
* See comment in vsprintf.c for allowed formats.

desc.c

Lines changed: 3 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -331,11 +331,8 @@ decode_select(struct tcb *tcp, long *args, enum bitness_t bitness)
331331
if (entering(tcp)) {
332332
tprintf("%d", (int) args[0]);
333333

334-
if (verbose(tcp) && fdsize > 0) {
335-
fds = malloc(fdsize);
336-
if (!fds)
337-
die_out_of_memory();
338-
}
334+
if (verbose(tcp) && fdsize > 0)
335+
fds = xmalloc(fdsize);
339336
for (i = 0; i < 3; i++) {
340337
arg = args[i+1];
341338
if (arg == 0) {
@@ -380,9 +377,7 @@ decode_select(struct tcb *tcp, long *args, enum bitness_t bitness)
380377
return RVAL_STR;
381378
}
382379

383-
fds = malloc(fdsize);
384-
if (!fds)
385-
die_out_of_memory();
380+
fds = xmalloc(fdsize);
386381

387382
outptr = outstr;
388383
sep = "";

dirent.c

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -81,9 +81,7 @@ SYS_FUNC(getdents)
8181
len = tcp->u_rval;
8282

8383
if (len) {
84-
buf = malloc(len);
85-
if (!buf)
86-
die_out_of_memory();
84+
buf = xmalloc(len);
8785
if (umoven(tcp, tcp->u_arg[1], len, buf) < 0) {
8886
tprintf("%#lx, %lu", tcp->u_arg[1], tcp->u_arg[2]);
8987
free(buf);
@@ -164,9 +162,7 @@ SYS_FUNC(getdents64)
164162
len = tcp->u_rval;
165163

166164
if (len) {
167-
buf = malloc(len);
168-
if (!buf)
169-
die_out_of_memory();
165+
buf = xmalloc(len);
170166
if (umoven(tcp, tcp->u_arg[1], len, buf) < 0) {
171167
tprintf("%#lx, %lu", tcp->u_arg[1], tcp->u_arg[2]);
172168
free(buf);

net.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -995,7 +995,7 @@ SYS_FUNC(recvmmsg)
995995
/* Abusing tcp->auxstr as temp storage.
996996
* Will be used and freed on syscall exit.
997997
*/
998-
tcp->auxstr = strdup(str);
998+
tcp->auxstr = xstrdup(str);
999999
} else {
10001000
tprintf("%#lx, %ld, ", tcp->u_arg[1], tcp->u_arg[2]);
10011001
printflags(msg_flags, tcp->u_arg[3], "MSG_???");

pathtrace.c

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -91,9 +91,8 @@ storepath(const char *path)
9191
return; /* already in table */
9292

9393
i = num_selected++;
94-
paths_selected = realloc(paths_selected, num_selected * sizeof(paths_selected[0]));
95-
if (!paths_selected)
96-
die_out_of_memory();
94+
paths_selected = xreallocarray(paths_selected, num_selected,
95+
sizeof(paths_selected[0]));
9796
paths_selected[i] = path;
9897
}
9998

@@ -287,9 +286,7 @@ pathtrace_match(struct tcb *tcp)
287286
if (nfds > 1024*1024)
288287
nfds = 1024*1024;
289288
fdsize = (((nfds + 7) / 8) + current_wordsize-1) & -current_wordsize;
290-
fds = malloc(fdsize);
291-
if (!fds)
292-
die_out_of_memory();
289+
fds = xmalloc(fdsize);
293290

294291
for (i = 1; i <= 3; ++i) {
295292
if (args[i] == 0)

strace.c

Lines changed: 10 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -324,15 +324,6 @@ void perror_msg_and_die(const char *fmt, ...)
324324
die();
325325
}
326326

327-
void die_out_of_memory(void)
328-
{
329-
static bool recursed = 0;
330-
if (recursed)
331-
exit(1);
332-
recursed = 1;
333-
error_msg_and_die("Out of memory");
334-
}
335-
336327
static void
337328
error_opt_arg(int opt, const char *arg)
338329
{
@@ -676,10 +667,9 @@ expand_tcbtab(void)
676667
So tcbtab is a table of pointers. Since we never
677668
free the TCBs, we allocate a single chunk of many. */
678669
unsigned int i = tcbtabsize;
679-
struct tcb *newtcbs = calloc(tcbtabsize, sizeof(newtcbs[0]));
680-
struct tcb **newtab = realloc(tcbtab, tcbtabsize * 2 * sizeof(tcbtab[0]));
681-
if (!newtab || !newtcbs)
682-
die_out_of_memory();
670+
struct tcb *newtcbs = xcalloc(tcbtabsize, sizeof(newtcbs[0]));
671+
struct tcb **newtab = xreallocarray(tcbtab, tcbtabsize * 2,
672+
sizeof(tcbtab[0]));
683673
tcbtabsize *= 2;
684674
tcbtab = newtab;
685675
while (i < tcbtabsize)
@@ -1233,7 +1223,7 @@ startup_child(char **argv)
12331223
* On NOMMU, can be safely freed only after execve in tracee.
12341224
* It's hard to know when that happens, so we just leak it.
12351225
*/
1236-
params_for_tracee.pathname = NOMMU_SYSTEM ? strdup(pathname) : pathname;
1226+
params_for_tracee.pathname = NOMMU_SYSTEM ? xstrdup(pathname) : pathname;
12371227

12381228
#if defined HAVE_PRCTL && defined PR_SET_PTRACER && defined PR_SET_PTRACER_ANY
12391229
if (daemonized_tracer)
@@ -1445,12 +1435,8 @@ init(int argc, char *argv[])
14451435

14461436
/* Allocate the initial tcbtab. */
14471437
tcbtabsize = argc; /* Surely enough for all -p args. */
1448-
tcbtab = calloc(tcbtabsize, sizeof(tcbtab[0]));
1449-
if (!tcbtab)
1450-
die_out_of_memory();
1451-
tcp = calloc(tcbtabsize, sizeof(*tcp));
1452-
if (!tcp)
1453-
die_out_of_memory();
1438+
tcbtab = xcalloc(tcbtabsize, sizeof(tcbtab[0]));
1439+
tcp = xcalloc(tcbtabsize, sizeof(*tcp));
14541440
for (tcbi = 0; tcbi < tcbtabsize; tcbi++)
14551441
tcbtab[tcbi] = tcp++;
14561442

@@ -1548,7 +1534,7 @@ init(int argc, char *argv[])
15481534
qualify(optarg);
15491535
break;
15501536
case 'o':
1551-
outfname = strdup(optarg);
1537+
outfname = xstrdup(optarg);
15521538
break;
15531539
case 'O':
15541540
i = string_to_uint(optarg);
@@ -1572,7 +1558,7 @@ init(int argc, char *argv[])
15721558
set_sortby(optarg);
15731559
break;
15741560
case 'u':
1575-
username = strdup(optarg);
1561+
username = xstrdup(optarg);
15761562
break;
15771563
#ifdef USE_LIBUNWIND
15781564
case 'k':
@@ -1596,9 +1582,7 @@ init(int argc, char *argv[])
15961582
argv += optind;
15971583
/* argc -= optind; - no need, argc is not used below */
15981584

1599-
acolumn_spaces = malloc(acolumn + 1);
1600-
if (!acolumn_spaces)
1601-
die_out_of_memory();
1585+
acolumn_spaces = xmalloc(acolumn + 1);
16021586
memset(acolumn_spaces, ' ', acolumn);
16031587
acolumn_spaces[acolumn] = '\0';
16041588

@@ -1691,9 +1675,7 @@ init(int argc, char *argv[])
16911675
}
16921676

16931677
if (!outfname || outfname[0] == '|' || outfname[0] == '!') {
1694-
char *buf = malloc(BUFSIZ);
1695-
if (!buf)
1696-
die_out_of_memory();
1678+
char *buf = xmalloc(BUFSIZ);
16971679
setvbuf(shared_log, buf, _IOLBF, BUFSIZ);
16981680
}
16991681
if (outfname && argv[0]) {

syscall.c

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -381,9 +381,8 @@ reallocate_qual(const unsigned int n)
381381
unsigned p;
382382
qualbits_t *qp;
383383
for (p = 0; p < SUPPORTED_PERSONALITIES; p++) {
384-
qp = qual_vec[p] = realloc(qual_vec[p], n * sizeof(qualbits_t));
385-
if (!qp)
386-
die_out_of_memory();
384+
qp = qual_vec[p] = xreallocarray(qual_vec[p], n,
385+
sizeof(qualbits_t));
387386
memset(&qp[num_quals], 0, (n - num_quals) * sizeof(qualbits_t));
388387
}
389388
num_quals = n;
@@ -531,9 +530,7 @@ qualify(const char *s)
531530
for (i = 0; i < num_quals; i++) {
532531
qualify_one(i, opt->bitflag, !not, -1);
533532
}
534-
copy = strdup(s);
535-
if (!copy)
536-
die_out_of_memory();
533+
copy = xstrdup(s);
537534
for (p = strtok(copy, ","); p; p = strtok(NULL, ",")) {
538535
int n;
539536
if (opt->bitflag == QUAL_TRACE && (n = lookup_class(p)) > 0) {

unwind.c

Lines changed: 8 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -107,9 +107,7 @@ unwind_tcb_init(struct tcb *tcp)
107107
if (!tcp->libunwind_ui)
108108
die_out_of_memory();
109109

110-
tcp->queue = malloc(sizeof(*tcp->queue));
111-
if (!tcp->queue)
112-
die_out_of_memory();
110+
tcp->queue = xmalloc(sizeof(*tcp->queue));
113111
tcp->queue->head = NULL;
114112
tcp->queue->tail = NULL;
115113
}
@@ -152,9 +150,7 @@ build_mmap_cache(struct tcb* tcp)
152150
return;
153151
}
154152

155-
cache_head = calloc(cur_array_size, sizeof(*cache_head));
156-
if (!cache_head)
157-
die_out_of_memory();
153+
cache_head = xcalloc(cur_array_size, sizeof(*cache_head));
158154

159155
while (fgets(buffer, sizeof(buffer), fp) != NULL) {
160156
struct mmap_cache_t *entry;
@@ -197,19 +193,15 @@ build_mmap_cache(struct tcb* tcp)
197193

198194
if (tcp->mmap_cache_size >= cur_array_size) {
199195
cur_array_size *= 2;
200-
cache_head = realloc(cache_head,
201-
cur_array_size * sizeof(*cache_head));
202-
if (!cache_head)
203-
die_out_of_memory();
196+
cache_head = xreallocarray(cache_head, cur_array_size,
197+
sizeof(*cache_head));
204198
}
205199

206200
entry = &cache_head[tcp->mmap_cache_size];
207201
entry->start_addr = start_addr;
208202
entry->end_addr = end_addr;
209203
entry->mmap_offset = mmap_offset;
210-
entry->binary_filename = strdup(binary_path);
211-
if (!entry->binary_filename)
212-
die_out_of_memory();
204+
entry->binary_filename = xstrdup(binary_path);
213205
tcp->mmap_cache_size++;
214206
}
215207
fclose(fp);
@@ -290,10 +282,8 @@ get_symbol_name(unw_cursor_t *cursor, char **name,
290282
*offset = 0;
291283
break;
292284
}
285+
*name = xreallocarray(*name, 2, *size);
293286
*size *= 2;
294-
*name = realloc(*name, *size);
295-
if (!*name)
296-
die_out_of_memory();
297287
}
298288
}
299289

@@ -372,9 +362,7 @@ stacktrace_walk(struct tcb *tcp,
372362
if (tcp->mmap_cache_size == 0)
373363
error_msg_and_die("bug: mmap_cache is empty");
374364

375-
symbol_name = malloc(symbol_name_size);
376-
if (!symbol_name)
377-
die_out_of_memory();
365+
symbol_name = xmalloc(symbol_name_size);
378366

379367
if (unw_init_remote(&cursor, libunwind_as, tcp->libunwind_ui) < 0)
380368
perror_msg_and_die("Can't initiate libunwind");
@@ -490,10 +478,7 @@ queue_put(struct queue_t *queue,
490478
{
491479
struct call_t *call;
492480

493-
call = malloc(sizeof(*call));
494-
if (!call)
495-
die_out_of_memory();
496-
481+
call = xmalloc(sizeof(*call));
497482
call->output_line = sprint_call_or_error(binary_filename,
498483
symbol_name,
499484
function_offset,

0 commit comments

Comments
 (0)