]> git.kernelconcepts.de Git - karo-tx-linux.git/blobdiff - tools/lib/traceevent/event-parse.c
lib tools traceevent: Add back pevent assignment in __pevent_parse_format()
[karo-tx-linux.git] / tools / lib / traceevent / event-parse.c
index 5f34aa371b5660c503cfca05e9e0731aba013ea7..f2989c525e48a6865729cff8962fca28d39532fc 100644 (file)
  *  Frederic Weisbecker gave his permission to relicense the code to
  *  the Lesser General Public License.
  */
-#define _GNU_SOURCE
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
 #include <stdarg.h>
 #include <ctype.h>
 #include <errno.h>
+#include <stdint.h>
+#include <limits.h>
 
 #include "event-parse.h"
 #include "event-utils.h"
@@ -117,14 +118,7 @@ void breakpoint(void)
 
 struct print_arg *alloc_arg(void)
 {
-       struct print_arg *arg;
-
-       arg = malloc_or_die(sizeof(*arg));
-       if (!arg)
-               return NULL;
-       memset(arg, 0, sizeof(*arg));
-
-       return arg;
+       return calloc(1, sizeof(struct print_arg));
 }
 
 struct cmdline {
@@ -158,7 +152,9 @@ static int cmdline_init(struct pevent *pevent)
        struct cmdline *cmdlines;
        int i;
 
-       cmdlines = malloc_or_die(sizeof(*cmdlines) * pevent->cmdline_count);
+       cmdlines = malloc(sizeof(*cmdlines) * pevent->cmdline_count);
+       if (!cmdlines)
+               return -1;
 
        i = 0;
        while (cmdlist) {
@@ -186,8 +182,8 @@ static char *find_cmdline(struct pevent *pevent, int pid)
        if (!pid)
                return "<idle>";
 
-       if (!pevent->cmdlines)
-               cmdline_init(pevent);
+       if (!pevent->cmdlines && cmdline_init(pevent))
+               return "<not enough memory for cmdlines!>";
 
        key.pid = pid;
 
@@ -215,8 +211,8 @@ int pevent_pid_is_registered(struct pevent *pevent, int pid)
        if (!pid)
                return 1;
 
-       if (!pevent->cmdlines)
-               cmdline_init(pevent);
+       if (!pevent->cmdlines && cmdline_init(pevent))
+               return 0;
 
        key.pid = pid;
 
@@ -258,10 +254,14 @@ static int add_new_comm(struct pevent *pevent, const char *comm, int pid)
                return -1;
        }
 
-       cmdlines[pevent->cmdline_count].pid = pid;
        cmdlines[pevent->cmdline_count].comm = strdup(comm);
-       if (!cmdlines[pevent->cmdline_count].comm)
-               die("malloc comm");
+       if (!cmdlines[pevent->cmdline_count].comm) {
+               free(cmdlines);
+               errno = ENOMEM;
+               return -1;
+       }
+
+       cmdlines[pevent->cmdline_count].pid = pid;
                
        if (cmdlines[pevent->cmdline_count].comm)
                pevent->cmdline_count++;
@@ -288,10 +288,15 @@ int pevent_register_comm(struct pevent *pevent, const char *comm, int pid)
        if (pevent->cmdlines)
                return add_new_comm(pevent, comm, pid);
 
-       item = malloc_or_die(sizeof(*item));
+       item = malloc(sizeof(*item));
+       if (!item)
+               return -1;
+
        item->comm = strdup(comm);
-       if (!item->comm)
-               die("malloc comm");
+       if (!item->comm) {
+               free(item);
+               return -1;
+       }
        item->pid = pid;
        item->next = pevent->cmdlist;
 
@@ -355,7 +360,10 @@ static int func_map_init(struct pevent *pevent)
        struct func_map *func_map;
        int i;
 
-       func_map = malloc_or_die(sizeof(*func_map) * (pevent->func_count + 1));
+       func_map = malloc(sizeof(*func_map) * (pevent->func_count + 1));
+       if (!func_map)
+               return -1;
+
        funclist = pevent->funclist;
 
        i = 0;
@@ -455,25 +463,36 @@ pevent_find_function_address(struct pevent *pevent, unsigned long long addr)
 int pevent_register_function(struct pevent *pevent, char *func,
                             unsigned long long addr, char *mod)
 {
-       struct func_list *item;
+       struct func_list *item = malloc(sizeof(*item));
 
-       item = malloc_or_die(sizeof(*item));
+       if (!item)
+               return -1;
 
        item->next = pevent->funclist;
        item->func = strdup(func);
-       if (mod)
+       if (!item->func)
+               goto out_free;
+
+       if (mod) {
                item->mod = strdup(mod);
-       else
+               if (!item->mod)
+                       goto out_free_func;
+       } else
                item->mod = NULL;
        item->addr = addr;
 
-       if (!item->func || (mod && !item->mod))
-               die("malloc func");
-
        pevent->funclist = item;
        pevent->func_count++;
 
        return 0;
+
+out_free_func:
+       free(item->func);
+       item->func = NULL;
+out_free:
+       free(item);
+       errno = ENOMEM;
+       return -1;
 }
 
 /**
@@ -524,14 +543,16 @@ static int printk_cmp(const void *a, const void *b)
        return 0;
 }
 
-static void printk_map_init(struct pevent *pevent)
+static int printk_map_init(struct pevent *pevent)
 {
        struct printk_list *printklist;
        struct printk_list *item;
        struct printk_map *printk_map;
        int i;
 
-       printk_map = malloc_or_die(sizeof(*printk_map) * (pevent->printk_count + 1));
+       printk_map = malloc(sizeof(*printk_map) * (pevent->printk_count + 1));
+       if (!printk_map)
+               return -1;
 
        printklist = pevent->printklist;
 
@@ -549,6 +570,8 @@ static void printk_map_init(struct pevent *pevent)
 
        pevent->printk_map = printk_map;
        pevent->printklist = NULL;
+
+       return 0;
 }
 
 static struct printk_map *
@@ -557,8 +580,8 @@ find_printk(struct pevent *pevent, unsigned long long addr)
        struct printk_map *printk;
        struct printk_map key;
 
-       if (!pevent->printk_map)
-               printk_map_init(pevent);
+       if (!pevent->printk_map && printk_map_init(pevent))
+               return NULL;
 
        key.addr = addr;
 
@@ -580,21 +603,27 @@ find_printk(struct pevent *pevent, unsigned long long addr)
 int pevent_register_print_string(struct pevent *pevent, char *fmt,
                                 unsigned long long addr)
 {
-       struct printk_list *item;
+       struct printk_list *item = malloc(sizeof(*item));
 
-       item = malloc_or_die(sizeof(*item));
+       if (!item)
+               return -1;
 
        item->next = pevent->printklist;
-       item->printk = strdup(fmt);
        item->addr = addr;
 
+       item->printk = strdup(fmt);
        if (!item->printk)
-               die("malloc fmt");
+               goto out_free;
 
        pevent->printklist = item;
        pevent->printk_count++;
 
        return 0;
+
+out_free:
+       free(item);
+       errno = ENOMEM;
+       return -1;
 }
 
 /**
@@ -619,24 +648,18 @@ void pevent_print_printk(struct pevent *pevent)
 
 static struct event_format *alloc_event(void)
 {
-       struct event_format *event;
-
-       event = malloc(sizeof(*event));
-       if (!event)
-               return NULL;
-       memset(event, 0, sizeof(*event));
-
-       return event;
+       return calloc(1, sizeof(struct event_format));
 }
 
-static void add_event(struct pevent *pevent, struct event_format *event)
+static int add_event(struct pevent *pevent, struct event_format *event)
 {
        int i;
+       struct event_format **events = realloc(pevent->events, sizeof(event) *
+                                              (pevent->nr_events + 1));
+       if (!events)
+               return -1;
 
-       pevent->events = realloc(pevent->events, sizeof(event) *
-                                (pevent->nr_events + 1));
-       if (!pevent->events)
-               die("Can not allocate events");
+       pevent->events = events;
 
        for (i = 0; i < pevent->nr_events; i++) {
                if (pevent->events[i]->id > event->id)
@@ -651,6 +674,8 @@ static void add_event(struct pevent *pevent, struct event_format *event)
        pevent->nr_events++;
 
        event->pevent = pevent;
+
+       return 0;
 }
 
 static int event_item_type(enum event_type type)
@@ -827,9 +852,9 @@ static enum event_type __read_token(char **tok)
        switch (type) {
        case EVENT_NEWLINE:
        case EVENT_DELIM:
-               *tok = malloc_or_die(2);
-               (*tok)[0] = ch;
-               (*tok)[1] = 0;
+               if (asprintf(tok, "%c", ch) < 0)
+                       return EVENT_ERROR;
+
                return type;
 
        case EVENT_OP:
@@ -1240,8 +1265,10 @@ static int event_read_fields(struct event_format *event, struct format_field **f
 
                last_token = token;
 
-               field = malloc_or_die(sizeof(*field));
-               memset(field, 0, sizeof(*field));
+               field = calloc(1, sizeof(*field));
+               if (!field)
+                       goto fail;
+
                field->event = event;
 
                /* read the rest of the type */
@@ -1282,7 +1309,7 @@ static int event_read_fields(struct event_format *event, struct format_field **f
                }
 
                if (!field->type) {
-                       die("no type found");
+                       do_warning("%s: no type found", __func__);
                        goto fail;
                }
                field->name = last_token;
@@ -1329,7 +1356,7 @@ static int event_read_fields(struct event_format *event, struct format_field **f
                                free_token(token);
                                type = read_token(&token);
                                if (type == EVENT_NONE) {
-                                       die("failed to find token");
+                                       do_warning("failed to find token");
                                        goto fail;
                                }
                        }
@@ -1538,6 +1565,14 @@ process_cond(struct event_format *event, struct print_arg *top, char **tok)
        left = alloc_arg();
        right = alloc_arg();
 
+       if (!arg || !left || !right) {
+               do_warning("%s: not enough memory!", __func__);
+               /* arg will be freed at out_free */
+               free_arg(left);
+               free_arg(right);
+               goto out_free;
+       }
+
        arg->type = PRINT_OP;
        arg->op.left = left;
        arg->op.right = right;
@@ -1580,6 +1615,12 @@ process_array(struct event_format *event, struct print_arg *top, char **tok)
        char *token = NULL;
 
        arg = alloc_arg();
+       if (!arg) {
+               do_warning("%s: not enough memory!", __func__);
+               /* '*tok' is set to top->op.op.  No need to free. */
+               *tok = NULL;
+               return EVENT_ERROR;
+       }
 
        *tok = NULL;
        type = process_arg(event, arg, &token);
@@ -1595,8 +1636,7 @@ process_array(struct event_format *event, struct print_arg *top, char **tok)
        return type;
 
 out_free:
-       free_token(*tok);
-       *tok = NULL;
+       free_token(token);
        free_arg(arg);
        return EVENT_ERROR;
 }
@@ -1682,7 +1722,7 @@ process_op(struct event_format *event, struct print_arg *arg, char **tok)
        if (arg->type == PRINT_OP && !arg->op.left) {
                /* handle single op */
                if (token[1]) {
-                       die("bad op token %s", token);
+                       do_warning("bad op token %s", token);
                        goto out_free;
                }
                switch (token[0]) {
@@ -1699,10 +1739,16 @@ process_op(struct event_format *event, struct print_arg *arg, char **tok)
 
                /* make an empty left */
                left = alloc_arg();
+               if (!left)
+                       goto out_warn_free;
+
                left->type = PRINT_NULL;
                arg->op.left = left;
 
                right = alloc_arg();
+               if (!right)
+                       goto out_warn_free;
+
                arg->op.right = right;
 
                /* do not free the token, it belongs to an op */
@@ -1712,6 +1758,9 @@ process_op(struct event_format *event, struct print_arg *arg, char **tok)
        } else if (strcmp(token, "?") == 0) {
 
                left = alloc_arg();
+               if (!left)
+                       goto out_warn_free;
+
                /* copy the top arg to the left */
                *left = *arg;
 
@@ -1720,6 +1769,7 @@ process_op(struct event_format *event, struct print_arg *arg, char **tok)
                arg->op.left = left;
                arg->op.prio = 0;
 
+               /* it will set arg->op.right */
                type = process_cond(event, arg, tok);
 
        } else if (strcmp(token, ">>") == 0 ||
@@ -1739,6 +1789,8 @@ process_op(struct event_format *event, struct print_arg *arg, char **tok)
                   strcmp(token, "!=") == 0) {
 
                left = alloc_arg();
+               if (!left)
+                       goto out_warn_free;
 
                /* copy the top arg to the left */
                *left = *arg;
@@ -1746,6 +1798,7 @@ process_op(struct event_format *event, struct print_arg *arg, char **tok)
                arg->type = PRINT_OP;
                arg->op.op = token;
                arg->op.left = left;
+               arg->op.right = NULL;
 
                if (set_op_prio(arg) == -1) {
                        event->flags |= EVENT_FL_FAILED;
@@ -1762,12 +1815,14 @@ process_op(struct event_format *event, struct print_arg *arg, char **tok)
                    type == EVENT_DELIM && (strcmp(token, ")") == 0)) {
                        char *new_atom;
 
-                       if (left->type != PRINT_ATOM)
-                               die("bad pointer type");
+                       if (left->type != PRINT_ATOM) {
+                               do_warning("bad pointer type");
+                               goto out_free;
+                       }
                        new_atom = realloc(left->atom.atom,
                                            strlen(left->atom.atom) + 3);
                        if (!new_atom)
-                               goto out_free;
+                               goto out_warn_free;
 
                        left->atom.atom = new_atom;
                        strcat(left->atom.atom, " *");
@@ -1779,12 +1834,18 @@ process_op(struct event_format *event, struct print_arg *arg, char **tok)
                }
 
                right = alloc_arg();
+               if (!right)
+                       goto out_warn_free;
+
                type = process_arg_token(event, right, tok, type);
                arg->op.right = right;
 
        } else if (strcmp(token, "[") == 0) {
 
                left = alloc_arg();
+               if (!left)
+                       goto out_warn_free;
+
                *left = *arg;
 
                arg->type = PRINT_OP;
@@ -1793,6 +1854,7 @@ process_op(struct event_format *event, struct print_arg *arg, char **tok)
 
                arg->op.prio = 0;
 
+               /* it will set arg->op.right */
                type = process_array(event, arg, tok);
 
        } else {
@@ -1816,14 +1878,16 @@ process_op(struct event_format *event, struct print_arg *arg, char **tok)
 
        return type;
 
- out_free:
+out_warn_free:
+       do_warning("%s: not enough memory!", __func__);
+out_free:
        free_token(token);
        *tok = NULL;
        return EVENT_ERROR;
 }
 
 static enum event_type
-process_entry(struct event_format *event __unused, struct print_arg *arg,
+process_entry(struct event_format *event __maybe_unused, struct print_arg *arg,
              char **tok)
 {
        enum event_type type;
@@ -1880,7 +1944,11 @@ eval_type_str(unsigned long long val, const char *type, int pointer)
                        return val;
                }
 
-               ref = malloc_or_die(len);
+               ref = malloc(len);
+               if (!ref) {
+                       do_warning("%s: not enough memory!", __func__);
+                       return val;
+               }
                memcpy(ref, type, len);
 
                /* chop off the " *" */
@@ -1957,8 +2025,10 @@ eval_type_str(unsigned long long val, const char *type, int pointer)
 static unsigned long long
 eval_type(unsigned long long val, struct print_arg *arg, int pointer)
 {
-       if (arg->type != PRINT_TYPE)
-               die("expected type argument");
+       if (arg->type != PRINT_TYPE) {
+               do_warning("expected type argument");
+               return 0;
+       }
 
        return eval_type_str(val, arg->typecast.type, pointer);
 }
@@ -2143,7 +2213,7 @@ static char *arg_eval (struct print_arg *arg)
        case PRINT_STRING:
        case PRINT_BSTRING:
        default:
-               die("invalid eval type %d", arg->type);
+               do_warning("invalid eval type %d", arg->type);
                break;
        }
 
@@ -2166,6 +2236,8 @@ process_fields(struct event_format *event, struct print_flag_sym **list, char **
                        break;
 
                arg = alloc_arg();
+               if (!arg)
+                       goto out_free;
 
                free_token(token);
                type = process_arg(event, arg, &token);
@@ -2179,30 +2251,33 @@ process_fields(struct event_format *event, struct print_flag_sym **list, char **
                if (test_type_token(type, token, EVENT_DELIM, ","))
                        goto out_free;
 
-               field = malloc_or_die(sizeof(*field));
-               memset(field, 0, sizeof(*field));
+               field = calloc(1, sizeof(*field));
+               if (!field)
+                       goto out_free;
 
                value = arg_eval(arg);
                if (value == NULL)
-                       goto out_free;
+                       goto out_free_field;
                field->value = strdup(value);
                if (field->value == NULL)
-                       goto out_free;
+                       goto out_free_field;
 
                free_arg(arg);
                arg = alloc_arg();
+               if (!arg)
+                       goto out_free;
 
                free_token(token);
                type = process_arg(event, arg, &token);
                if (test_type_token(type, token, EVENT_OP, "}"))
-                       goto out_free;
+                       goto out_free_field;
 
                value = arg_eval(arg);
                if (value == NULL)
-                       goto out_free;
+                       goto out_free_field;
                field->str = strdup(value);
                if (field->str == NULL)
-                       goto out_free;
+                       goto out_free_field;
                free_arg(arg);
                arg = NULL;
 
@@ -2216,6 +2291,8 @@ process_fields(struct event_format *event, struct print_flag_sym **list, char **
        *tok = token;
        return type;
 
+out_free_field:
+       free_flag_sym(field);
 out_free:
        free_arg(arg);
        free_token(token);
@@ -2235,6 +2312,10 @@ process_flags(struct event_format *event, struct print_arg *arg, char **tok)
        arg->type = PRINT_FLAGS;
 
        field = alloc_arg();
+       if (!field) {
+               do_warning("%s: not enough memory!", __func__);
+               goto out_free;
+       }
 
        type = process_arg(event, field, &token);
 
@@ -2243,7 +2324,7 @@ process_flags(struct event_format *event, struct print_arg *arg, char **tok)
                type = process_op(event, field, &token);
 
        if (test_type_token(type, token, EVENT_DELIM, ","))
-               goto out_free;
+               goto out_free_field;
        free_token(token);
 
        arg->flags.field = field;
@@ -2265,7 +2346,9 @@ process_flags(struct event_format *event, struct print_arg *arg, char **tok)
        type = read_token_item(tok);
        return type;
 
- out_free:
+out_free_field:
+       free_arg(field);
+out_free:
        free_token(token);
        *tok = NULL;
        return EVENT_ERROR;
@@ -2282,10 +2365,14 @@ process_symbols(struct event_format *event, struct print_arg *arg, char **tok)
        arg->type = PRINT_SYMBOL;
 
        field = alloc_arg();
+       if (!field) {
+               do_warning("%s: not enough memory!", __func__);
+               goto out_free;
+       }
 
        type = process_arg(event, field, &token);
        if (test_type_token(type, token, EVENT_DELIM, ","))
-               goto out_free;
+               goto out_free_field;
 
        arg->symbol.field = field;
 
@@ -2297,7 +2384,9 @@ process_symbols(struct event_format *event, struct print_arg *arg, char **tok)
        type = read_token_item(tok);
        return type;
 
- out_free:
+out_free_field:
+       free_arg(field);
+out_free:
        free_token(token);
        *tok = NULL;
        return EVENT_ERROR;
@@ -2314,6 +2403,11 @@ process_hex(struct event_format *event, struct print_arg *arg, char **tok)
        arg->type = PRINT_HEX;
 
        field = alloc_arg();
+       if (!field) {
+               do_warning("%s: not enough memory!", __func__);
+               goto out_free;
+       }
+
        type = process_arg(event, field, &token);
 
        if (test_type_token(type, token, EVENT_DELIM, ","))
@@ -2324,6 +2418,12 @@ process_hex(struct event_format *event, struct print_arg *arg, char **tok)
        free_token(token);
 
        field = alloc_arg();
+       if (!field) {
+               do_warning("%s: not enough memory!", __func__);
+               *tok = NULL;
+               return EVENT_ERROR;
+       }
+
        type = process_arg(event, field, &token);
 
        if (test_type_token(type, token, EVENT_DELIM, ")"))
@@ -2381,6 +2481,12 @@ process_dynamic_array(struct event_format *event, struct print_arg *arg, char **
 
        free_token(token);
        arg = alloc_arg();
+       if (!field) {
+               do_warning("%s: not enough memory!", __func__);
+               *tok = NULL;
+               return EVENT_ERROR;
+       }
+
        type = process_arg(event, arg, &token);
        if (type == EVENT_ERROR)
                goto out_free_arg;
@@ -2434,10 +2540,16 @@ process_paren(struct event_format *event, struct print_arg *arg, char **tok)
                /* make this a typecast and contine */
 
                /* prevous must be an atom */
-               if (arg->type != PRINT_ATOM)
-                       die("previous needed to be PRINT_ATOM");
+               if (arg->type != PRINT_ATOM) {
+                       do_warning("previous needed to be PRINT_ATOM");
+                       goto out_free;
+               }
 
                item_arg = alloc_arg();
+               if (!item_arg) {
+                       do_warning("%s: not enough memory!", __func__);
+                       goto out_free;
+               }
 
                arg->type = PRINT_TYPE;
                arg->typecast.type = arg->atom.atom;
@@ -2457,7 +2569,8 @@ process_paren(struct event_format *event, struct print_arg *arg, char **tok)
 
 
 static enum event_type
-process_str(struct event_format *event __unused, struct print_arg *arg, char **tok)
+process_str(struct event_format *event __maybe_unused, struct print_arg *arg,
+           char **tok)
 {
        enum event_type type;
        char *token;
@@ -2489,6 +2602,9 @@ find_func_handler(struct pevent *pevent, char *func_name)
 {
        struct pevent_function_handler *func;
 
+       if (!pevent)
+               return NULL;
+
        for (func = pevent->func_handlers; func; func = func->next) {
                if (strcmp(func->name, func_name) == 0)
                        break;
@@ -2532,6 +2648,11 @@ process_func_handler(struct event_format *event, struct pevent_function_handler
        next_arg = &(arg->func.args);
        for (i = 0; i < func->nr_args; i++) {
                farg = alloc_arg();
+               if (!farg) {
+                       do_warning("%s: not enough memory!", __func__);
+                       return EVENT_ERROR;
+               }
+
                type = process_arg(event, farg, &token);
                if (i < (func->nr_args - 1))
                        test = ",";
@@ -2676,7 +2797,8 @@ process_arg_token(struct event_format *event, struct print_arg *arg,
 
        case EVENT_ERROR ... EVENT_NEWLINE:
        default:
-               die("unexpected type %d", type);
+               do_warning("unexpected type %d", type);
+               return EVENT_ERROR;
        }
        *tok = token;
 
@@ -2697,6 +2819,10 @@ static int event_read_print_args(struct event_format *event, struct print_arg **
                }
 
                arg = alloc_arg();
+               if (!arg) {
+                       do_warning("%s: not enough memory!", __func__);
+                       return -1;
+               }
 
                type = process_arg(event, arg, &token);
 
@@ -2768,10 +2894,8 @@ static int event_read_print(struct event_format *event)
        if (type == EVENT_DQUOTE) {
                char *cat;
 
-               cat = malloc_or_die(strlen(event->print_fmt.format) +
-                                   strlen(token) + 1);
-               strcpy(cat, event->print_fmt.format);
-               strcat(cat, token);
+               if (asprintf(&cat, "%s%s", event->print_fmt.format, token) < 0)
+                       goto fail;
                free_token(token);
                free_token(event->print_fmt.format);
                event->print_fmt.format = NULL;
@@ -2925,8 +3049,10 @@ static int get_common_info(struct pevent *pevent,
         * All events should have the same common elements.
         * Pick any event to find where the type is;
         */
-       if (!pevent->events)
-               die("no event_list!");
+       if (!pevent->events) {
+               do_warning("no event_list!");
+               return -1;
+       }
 
        event = pevent->events[0];
        field = pevent_find_common_field(event, type);
@@ -3084,7 +3210,8 @@ eval_num_arg(void *data, int size, struct event_format *event, struct print_arg
                if (!arg->field.field) {
                        arg->field.field = pevent_find_any_field(event, arg->field.name);
                        if (!arg->field.field)
-                               die("field %s not found", arg->field.name);
+                               goto out_warning_field;
+                       
                }
                /* must be a number */
                val = pevent_read_number(pevent, data + arg->field.field->offset,
@@ -3145,8 +3272,10 @@ eval_num_arg(void *data, int size, struct event_format *event, struct print_arg
                                if (!larg->field.field) {
                                        larg->field.field =
                                                pevent_find_any_field(event, larg->field.name);
-                                       if (!larg->field.field)
-                                               die("field %s not found", larg->field.name);
+                                       if (!larg->field.field) {
+                                               arg = larg;
+                                               goto out_warning_field;
+                                       }
                                }
                                field_size = larg->field.field->elementsize;
                                offset = larg->field.field->offset +
@@ -3182,7 +3311,7 @@ eval_num_arg(void *data, int size, struct event_format *event, struct print_arg
                                val = left != right;
                                break;
                        default:
-                               die("unknown op '%s'", arg->op.op);
+                               goto out_warning_op;
                        }
                        break;
                case '~':
@@ -3212,7 +3341,7 @@ eval_num_arg(void *data, int size, struct event_format *event, struct print_arg
                                val = left <= right;
                                break;
                        default:
-                               die("unknown op '%s'", arg->op.op);
+                               goto out_warning_op;
                        }
                        break;
                case '>':
@@ -3227,12 +3356,13 @@ eval_num_arg(void *data, int size, struct event_format *event, struct print_arg
                                val = left >= right;
                                break;
                        default:
-                               die("unknown op '%s'", arg->op.op);
+                               goto out_warning_op;
                        }
                        break;
                case '=':
                        if (arg->op.op[1] != '=')
-                               die("unknown op '%s'", arg->op.op);
+                               goto out_warning_op;
+
                        val = left == right;
                        break;
                case '-':
@@ -3248,13 +3378,21 @@ eval_num_arg(void *data, int size, struct event_format *event, struct print_arg
                        val = left * right;
                        break;
                default:
-                       die("unknown op '%s'", arg->op.op);
+                       goto out_warning_op;
                }
                break;
        default: /* not sure what to do there */
                return 0;
        }
        return val;
+
+out_warning_op:
+       do_warning("%s: unknown op '%s'", __func__, arg->op.op);
+       return 0;
+
+out_warning_field:
+       do_warning("%s: field %s not found", __func__, arg->field.name);
+       return 0;
 }
 
 struct flag {
@@ -3331,8 +3469,10 @@ static void print_str_arg(struct trace_seq *s, void *data, int size,
                field = arg->field.field;
                if (!field) {
                        field = pevent_find_any_field(event, arg->field.name);
-                       if (!field)
-                               die("field %s not found", arg->field.name);
+                       if (!field) {
+                               str = arg->field.name;
+                               goto out_warning_field;
+                       }
                        arg->field.field = field;
                }
                /* Zero sized fields, mean the rest of the data */
@@ -3349,7 +3489,11 @@ static void print_str_arg(struct trace_seq *s, void *data, int size,
                        trace_seq_printf(s, "%lx", addr);
                        break;
                }
-               str = malloc_or_die(len + 1);
+               str = malloc(len + 1);
+               if (!str) {
+                       do_warning("%s: not enough memory!", __func__);
+                       return;
+               }
                memcpy(str, data + field->offset, len);
                str[len] = 0;
                print_str_to_seq(s, format, len_arg, str);
@@ -3389,7 +3533,7 @@ static void print_str_arg(struct trace_seq *s, void *data, int size,
                        str = arg->hex.field->field.name;
                        field = pevent_find_any_field(event, str);
                        if (!field)
-                               die("field %s not found", str);
+                               goto out_warning_field;
                        arg->hex.field->field.field = field;
                }
                hex = data + field->offset;
@@ -3441,6 +3585,11 @@ static void print_str_arg(struct trace_seq *s, void *data, int size,
                /* well... */
                break;
        }
+
+       return;
+
+out_warning_field:
+       do_warning("%s: field %s not found", __func__, arg->field.name);
 }
 
 static unsigned long long
@@ -3467,7 +3616,11 @@ process_defined_func(struct trace_seq *s, void *data, int size,
        farg = arg->func.args;
        param = func_handle->params;
 
-       args = malloc_or_die(sizeof(*args) * func_handle->nr_args);
+       ret = ULLONG_MAX;
+       args = malloc(sizeof(*args) * func_handle->nr_args);
+       if (!args)
+               goto out;
+
        for (i = 0; i < func_handle->nr_args; i++) {
                switch (param->type) {
                case PEVENT_FUNC_ARG_INT:
@@ -3479,13 +3632,19 @@ process_defined_func(struct trace_seq *s, void *data, int size,
                        trace_seq_init(&str);
                        print_str_arg(&str, data, size, event, "%s", -1, farg);
                        trace_seq_terminate(&str);
-                       string = malloc_or_die(sizeof(*string));
+                       string = malloc(sizeof(*string));
+                       if (!string) {
+                               do_warning("%s(%d): malloc str", __func__, __LINE__);
+                               goto out_free;
+                       }
                        string->next = strings;
                        string->str = strdup(str.buffer);
-                       if (!string->str)
-                               die("malloc str");
-
-                       args[i] = (unsigned long long)string->str;
+                       if (!string->str) {
+                               free(string);
+                               do_warning("%s(%d): malloc str", __func__, __LINE__);
+                               goto out_free;
+                       }
+                       args[i] = (uintptr_t)string->str;
                        strings = string;
                        trace_seq_destroy(&str);
                        break;
@@ -3494,14 +3653,15 @@ process_defined_func(struct trace_seq *s, void *data, int size,
                         * Something went totally wrong, this is not
                         * an input error, something in this code broke.
                         */
-                       die("Unexpected end of arguments\n");
-                       break;
+                       do_warning("Unexpected end of arguments\n");
+                       goto out_free;
                }
                farg = farg->next;
                param = param->next;
        }
 
        ret = (*func_handle->func)(s, args);
+out_free:
        free(args);
        while (strings) {
                string = strings;
@@ -3515,6 +3675,18 @@ process_defined_func(struct trace_seq *s, void *data, int size,
        return ret;
 }
 
+static void free_args(struct print_arg *args)
+{
+       struct print_arg *next;
+
+       while (args) {
+               next = args->next;
+
+               free_arg(args);
+               args = next;
+       }
+}
+
 static struct print_arg *make_bprint_args(char *fmt, void *data, int size, struct event_format *event)
 {
        struct pevent *pevent = event->pevent;
@@ -3530,11 +3702,15 @@ static struct print_arg *make_bprint_args(char *fmt, void *data, int size, struc
 
        if (!field) {
                field = pevent_find_field(event, "buf");
-               if (!field)
-                       die("can't find buffer field for binary printk");
+               if (!field) {
+                       do_warning("can't find buffer field for binary printk");
+                       return NULL;
+               }
                ip_field = pevent_find_field(event, "ip");
-               if (!ip_field)
-                       die("can't find ip field for binary printk");
+               if (!ip_field) {
+                       do_warning("can't find ip field for binary printk");
+                       return NULL;
+               }
                pevent->bprint_buf_field = field;
                pevent->bprint_ip_field = ip_field;
        }
@@ -3545,13 +3721,18 @@ static struct print_arg *make_bprint_args(char *fmt, void *data, int size, struc
         * The first arg is the IP pointer.
         */
        args = alloc_arg();
+       if (!args) {
+               do_warning("%s(%d): not enough memory!", __func__, __LINE__);
+               return NULL;
+       }
        arg = args;
        arg->next = NULL;
        next = &arg->next;
 
        arg->type = PRINT_ATOM;
-       arg->atom.atom = malloc_or_die(32);
-       sprintf(arg->atom.atom, "%lld", ip);
+               
+       if (asprintf(&arg->atom.atom, "%lld", ip) < 0)
+               goto out_free;
 
        /* skip the first "%pf : " */
        for (ptr = fmt + 6, bptr = data + field->offset;
@@ -3606,10 +3787,17 @@ static struct print_arg *make_bprint_args(char *fmt, void *data, int size, struc
                                val = pevent_read_number(pevent, bptr, vsize);
                                bptr += vsize;
                                arg = alloc_arg();
+                               if (!arg) {
+                                       do_warning("%s(%d): not enough memory!",
+                                                  __func__, __LINE__);
+                                       goto out_free;
+                               }
                                arg->next = NULL;
                                arg->type = PRINT_ATOM;
-                               arg->atom.atom = malloc_or_die(32);
-                               sprintf(arg->atom.atom, "%lld", val);
+                               if (asprintf(&arg->atom.atom, "%lld", val) < 0) {
+                                       free(arg);
+                                       goto out_free;
+                               }
                                *next = arg;
                                next = &arg->next;
                                /*
@@ -3622,11 +3810,16 @@ static struct print_arg *make_bprint_args(char *fmt, void *data, int size, struc
                                break;
                        case 's':
                                arg = alloc_arg();
+                               if (!arg) {
+                                       do_warning("%s(%d): not enough memory!",
+                                                  __func__, __LINE__);
+                                       goto out_free;
+                               }
                                arg->next = NULL;
                                arg->type = PRINT_BSTRING;
                                arg->string.string = strdup(bptr);
                                if (!arg->string.string)
-                                       break;
+                                       goto out_free;
                                bptr += strlen(bptr) + 1;
                                *next = arg;
                                next = &arg->next;
@@ -3637,22 +3830,15 @@ static struct print_arg *make_bprint_args(char *fmt, void *data, int size, struc
        }
 
        return args;
-}
-
-static void free_args(struct print_arg *args)
-{
-       struct print_arg *next;
-
-       while (args) {
-               next = args->next;
 
-               free_arg(args);
-               args = next;
-       }
+out_free:
+       free_args(args);
+       return NULL;
 }
 
 static char *
-get_bprint_format(void *data, int size __unused, struct event_format *event)
+get_bprint_format(void *data, int size __maybe_unused,
+                 struct event_format *event)
 {
        struct pevent *pevent = event->pevent;
        unsigned long long addr;
@@ -3665,8 +3851,10 @@ get_bprint_format(void *data, int size __unused, struct event_format *event)
 
        if (!field) {
                field = pevent_find_field(event, "fmt");
-               if (!field)
-                       die("can't find format field for binary printk");
+               if (!field) {
+                       do_warning("can't find format field for binary printk");
+                       return NULL;
+               }
                pevent->bprint_fmt_field = field;
        }
 
@@ -3674,9 +3862,8 @@ get_bprint_format(void *data, int size __unused, struct event_format *event)
 
        printk = find_printk(pevent, addr);
        if (!printk) {
-               format = malloc_or_die(45);
-               sprintf(format, "%%pf : (NO FORMAT FOUND at %llx)\n",
-                       addr);
+               if (asprintf(&format, "%%pf : (NO FORMAT FOUND at %llx)\n", addr) < 0)
+                       return NULL;
                return format;
        }
 
@@ -3684,8 +3871,8 @@ get_bprint_format(void *data, int size __unused, struct event_format *event)
        /* Remove any quotes. */
        if (*p == '"')
                p++;
-       format = malloc_or_die(strlen(p) + 10);
-       sprintf(format, "%s : %s", "%pf", p);
+       if (asprintf(&format, "%s : %s", "%pf", p) < 0)
+               return NULL;
        /* remove ending quotes and new line since we will add one too */
        p = format + strlen(format) - 1;
        if (*p == '"')
@@ -3720,8 +3907,11 @@ static void print_mac_arg(struct trace_seq *s, int mac, void *data, int size,
        if (!arg->field.field) {
                arg->field.field =
                        pevent_find_any_field(event, arg->field.name);
-               if (!arg->field.field)
-                       die("field %s not found", arg->field.name);
+               if (!arg->field.field) {
+                       do_warning("%s: field %s not found",
+                                  __func__, arg->field.name);
+                       return;
+               }
        }
        if (arg->field.field->size != 6) {
                trace_seq_printf(s, "INVALIDMAC");
@@ -3888,8 +4078,11 @@ static void pretty_print(struct trace_seq *s, void *data, int size, struct event
                                goto cont_process;
                        case '*':
                                /* The argument is the length. */
-                               if (!arg)
-                                       die("no argument match");
+                               if (!arg) {
+                                       do_warning("no argument match");
+                                       event->flags |= EVENT_FL_FAILED;
+                                       goto out_failed;
+                               }
                                len_arg = eval_num_arg(data, size, event, arg);
                                len_as_arg = 1;
                                arg = arg->next;
@@ -3922,15 +4115,21 @@ static void pretty_print(struct trace_seq *s, void *data, int size, struct event
                        case 'x':
                        case 'X':
                        case 'u':
-                               if (!arg)
-                                       die("no argument match");
+                               if (!arg) {
+                                       do_warning("no argument match");
+                                       event->flags |= EVENT_FL_FAILED;
+                                       goto out_failed;
+                               }
 
                                len = ((unsigned long)ptr + 1) -
                                        (unsigned long)saveptr;
 
                                /* should never happen */
-                               if (len > 31)
-                                       die("bad format!");
+                               if (len > 31) {
+                                       do_warning("bad format!");
+                                       event->flags |= EVENT_FL_FAILED;
+                                       len = 31;
+                               }
 
                                memcpy(format, saveptr, len);
                                format[len] = 0;
@@ -3994,19 +4193,26 @@ static void pretty_print(struct trace_seq *s, void *data, int size, struct event
                                                trace_seq_printf(s, format, (long long)val);
                                        break;
                                default:
-                                       die("bad count (%d)", ls);
+                                       do_warning("bad count (%d)", ls);
+                                       event->flags |= EVENT_FL_FAILED;
                                }
                                break;
                        case 's':
-                               if (!arg)
-                                       die("no matching argument");
+                               if (!arg) {
+                                       do_warning("no matching argument");
+                                       event->flags |= EVENT_FL_FAILED;
+                                       goto out_failed;
+                               }
 
                                len = ((unsigned long)ptr + 1) -
                                        (unsigned long)saveptr;
 
                                /* should never happen */
-                               if (len > 31)
-                                       die("bad format!");
+                               if (len > 31) {
+                                       do_warning("bad format!");
+                                       event->flags |= EVENT_FL_FAILED;
+                                       len = 31;
+                               }
 
                                memcpy(format, saveptr, len);
                                format[len] = 0;
@@ -4024,6 +4230,11 @@ static void pretty_print(struct trace_seq *s, void *data, int size, struct event
                        trace_seq_putc(s, *ptr);
        }
 
+       if (event->flags & EVENT_FL_FAILED) {
+out_failed:
+               trace_seq_printf(s, "[FAILED TO PARSE]");
+       }
+
        if (args) {
                free_args(args);
                free(bprint_fmt);
@@ -4356,7 +4567,10 @@ get_event_fields(const char *type, const char *name,
        struct format_field *field;
        int i = 0;
 
-       fields = malloc_or_die(sizeof(*fields) * (count + 1));
+       fields = malloc(sizeof(*fields) * (count + 1));
+       if (!fields)
+               return NULL;
+
        for (field = list; field; field = field->next) {
                fields[i++] = field;
                if (i == count + 1) {
@@ -4672,8 +4886,7 @@ static int find_event_handle(struct pevent *pevent, struct event_format *event)
 }
 
 /**
- * pevent_parse_event - parse the event format
- * @pevent: the handle to the pevent
+ * __pevent_parse_format - parse the event format
  * @buf: the buffer storing the event format string
  * @size: the size of @buf
  * @sys: the system the event belongs to
@@ -4685,28 +4898,27 @@ static int find_event_handle(struct pevent *pevent, struct event_format *event)
  *
  * /sys/kernel/debug/tracing/events/.../.../format
  */
-int pevent_parse_event(struct pevent *pevent,
-                      const char *buf, unsigned long size,
-                      const char *sys)
+enum pevent_errno __pevent_parse_format(struct event_format **eventp,
+                                       struct pevent *pevent, const char *buf,
+                                       unsigned long size, const char *sys)
 {
        struct event_format *event;
        int ret;
 
        init_input_buf(buf, size);
 
-       event = alloc_event();
+       *eventp = event = alloc_event();
        if (!event)
-               return -ENOMEM;
+               return PEVENT_ERRNO__MEM_ALLOC_FAILED;
 
        event->name = event_read_name();
        if (!event->name) {
                /* Bad event? */
-               free(event);
-               return -1;
+               ret = PEVENT_ERRNO__MEM_ALLOC_FAILED;
+               goto event_alloc_failed;
        }
 
        if (strcmp(sys, "ftrace") == 0) {
-
                event->flags |= EVENT_FL_ISFTRACE;
 
                if (strcmp(event->name, "bprint") == 0)
@@ -4714,74 +4926,189 @@ int pevent_parse_event(struct pevent *pevent,
        }
                
        event->id = event_read_id();
-       if (event->id < 0)
-               die("failed to read event id");
+       if (event->id < 0) {
+               ret = PEVENT_ERRNO__READ_ID_FAILED;
+               /*
+                * This isn't an allocation error actually.
+                * But as the ID is critical, just bail out.
+                */
+               goto event_alloc_failed;
+       }
 
        event->system = strdup(sys);
-       if (!event->system)
-               die("failed to allocate system");
+       if (!event->system) {
+               ret = PEVENT_ERRNO__MEM_ALLOC_FAILED;
+               goto event_alloc_failed;
+       }
 
        /* Add pevent to event so that it can be referenced */
        event->pevent = pevent;
 
        ret = event_read_format(event);
        if (ret < 0) {
-               do_warning("failed to read event format for %s", event->name);
-               goto event_failed;
+               ret = PEVENT_ERRNO__READ_FORMAT_FAILED;
+               goto event_parse_failed;
        }
 
        /*
         * If the event has an override, don't print warnings if the event
         * print format fails to parse.
         */
-       if (find_event_handle(pevent, event))
+       if (pevent && find_event_handle(pevent, event))
                show_warning = 0;
 
        ret = event_read_print(event);
-       if (ret < 0) {
-               do_warning("failed to read event print fmt for %s",
-                          event->name);
-               show_warning = 1;
-               goto event_failed;
-       }
        show_warning = 1;
 
-       add_event(pevent, event);
+       if (ret < 0) {
+               ret = PEVENT_ERRNO__READ_PRINT_FAILED;
+               goto event_parse_failed;
+       }
 
        if (!ret && (event->flags & EVENT_FL_ISFTRACE)) {
                struct format_field *field;
                struct print_arg *arg, **list;
 
                /* old ftrace had no args */
-
                list = &event->print_fmt.args;
                for (field = event->format.fields; field; field = field->next) {
                        arg = alloc_arg();
-                       *list = arg;
-                       list = &arg->next;
+                       if (!arg) {
+                               event->flags |= EVENT_FL_FAILED;
+                               return PEVENT_ERRNO__OLD_FTRACE_ARG_FAILED;
+                       }
                        arg->type = PRINT_FIELD;
                        arg->field.name = strdup(field->name);
                        if (!arg->field.name) {
-                               do_warning("failed to allocate field name");
                                event->flags |= EVENT_FL_FAILED;
-                               return -1;
+                               free_arg(arg);
+                               return PEVENT_ERRNO__OLD_FTRACE_ARG_FAILED;
                        }
                        arg->field.field = field;
+                       *list = arg;
+                       list = &arg->next;
                }
                return 0;
        }
 
+       return 0;
+
+ event_parse_failed:
+       event->flags |= EVENT_FL_FAILED;
+       return ret;
+
+ event_alloc_failed:
+       free(event->system);
+       free(event->name);
+       free(event);
+       *eventp = NULL;
+       return ret;
+}
+
+/**
+ * pevent_parse_format - parse the event format
+ * @buf: the buffer storing the event format string
+ * @size: the size of @buf
+ * @sys: the system the event belongs to
+ *
+ * This parses the event format and creates an event structure
+ * to quickly parse raw data for a given event.
+ *
+ * These files currently come from:
+ *
+ * /sys/kernel/debug/tracing/events/.../.../format
+ */
+enum pevent_errno pevent_parse_format(struct event_format **eventp, const char *buf,
+                                     unsigned long size, const char *sys)
+{
+       return __pevent_parse_format(eventp, NULL, buf, size, sys);
+}
+
+/**
+ * pevent_parse_event - parse the event format
+ * @pevent: the handle to the pevent
+ * @buf: the buffer storing the event format string
+ * @size: the size of @buf
+ * @sys: the system the event belongs to
+ *
+ * This parses the event format and creates an event structure
+ * to quickly parse raw data for a given event.
+ *
+ * These files currently come from:
+ *
+ * /sys/kernel/debug/tracing/events/.../.../format
+ */
+enum pevent_errno pevent_parse_event(struct pevent *pevent, const char *buf,
+                                    unsigned long size, const char *sys)
+{
+       struct event_format *event = NULL;
+       int ret = __pevent_parse_format(&event, pevent, buf, size, sys);
+
+       if (event == NULL)
+               return ret;
+
+       if (add_event(pevent, event)) {
+               ret = PEVENT_ERRNO__MEM_ALLOC_FAILED;
+               goto event_add_failed;
+       }
+
 #define PRINT_ARGS 0
        if (PRINT_ARGS && event->print_fmt.args)
                print_args(event->print_fmt.args);
 
        return 0;
 
- event_failed:
-       event->flags |= EVENT_FL_FAILED;
-       /* still add it even if it failed */
-       add_event(pevent, event);
-       return -1;
+event_add_failed:
+       pevent_free_format(event);
+       return ret;
+}
+
+#undef _PE
+#define _PE(code, str) str
+static const char * const pevent_error_str[] = {
+       PEVENT_ERRORS
+};
+#undef _PE
+
+int pevent_strerror(struct pevent *pevent, enum pevent_errno errnum,
+                   char *buf, size_t buflen)
+{
+       int idx;
+       const char *msg;
+
+       if (errnum >= 0) {
+               msg = strerror_r(errnum, buf, buflen);
+               if (msg != buf) {
+                       size_t len = strlen(msg);
+                       memcpy(buf, msg, min(buflen - 1, len));
+                       *(buf + min(buflen - 1, len)) = '\0';
+               }
+               return 0;
+       }
+
+       if (errnum <= __PEVENT_ERRNO__START ||
+           errnum >= __PEVENT_ERRNO__END)
+               return -1;
+
+       idx = errnum - __PEVENT_ERRNO__START - 1;
+       msg = pevent_error_str[idx];
+
+       switch (errnum) {
+       case PEVENT_ERRNO__MEM_ALLOC_FAILED:
+       case PEVENT_ERRNO__PARSE_EVENT_FAILED:
+       case PEVENT_ERRNO__READ_ID_FAILED:
+       case PEVENT_ERRNO__READ_FORMAT_FAILED:
+       case PEVENT_ERRNO__READ_PRINT_FAILED:
+       case PEVENT_ERRNO__OLD_FTRACE_ARG_FAILED:
+               snprintf(buf, buflen, "%s", msg);
+               break;
+
+       default:
+               /* cannot reach here */
+               break;
+       }
+
+       return 0;
 }
 
 int get_field_val(struct trace_seq *s, struct format_field *field,
@@ -5000,6 +5327,7 @@ int pevent_register_print_function(struct pevent *pevent,
        struct pevent_func_params *param;
        enum pevent_func_arg_type type;
        va_list ap;
+       int ret;
 
        func_handle = find_func_handler(pevent, name);
        if (func_handle) {
@@ -5012,14 +5340,20 @@ int pevent_register_print_function(struct pevent *pevent,
                remove_func_handler(pevent, name);
        }
 
-       func_handle = malloc_or_die(sizeof(*func_handle));
-       memset(func_handle, 0, sizeof(*func_handle));
+       func_handle = calloc(1, sizeof(*func_handle));
+       if (!func_handle) {
+               do_warning("Failed to allocate function handler");
+               return PEVENT_ERRNO__MEM_ALLOC_FAILED;
+       }
 
        func_handle->ret_type = ret_type;
        func_handle->name = strdup(name);
        func_handle->func = func;
-       if (!func_handle->name)
-               die("Failed to allocate function name");
+       if (!func_handle->name) {
+               do_warning("Failed to allocate function name");
+               free(func_handle);
+               return PEVENT_ERRNO__MEM_ALLOC_FAILED;
+       }
 
        next_param = &(func_handle->params);
        va_start(ap, name);
@@ -5029,11 +5363,17 @@ int pevent_register_print_function(struct pevent *pevent,
                        break;
 
                if (type < 0 || type >= PEVENT_FUNC_ARG_MAX_TYPES) {
-                       warning("Invalid argument type %d", type);
+                       do_warning("Invalid argument type %d", type);
+                       ret = PEVENT_ERRNO__INVALID_ARG_TYPE;
                        goto out_free;
                }
 
-               param = malloc_or_die(sizeof(*param));
+               param = malloc(sizeof(*param));
+               if (!param) {
+                       do_warning("Failed to allocate function param");
+                       ret = PEVENT_ERRNO__MEM_ALLOC_FAILED;
+                       goto out_free;
+               }
                param->type = type;
                param->next = NULL;
 
@@ -5051,7 +5391,7 @@ int pevent_register_print_function(struct pevent *pevent,
  out_free:
        va_end(ap);
        free_func_handle(func_handle);
-       return -1;
+       return ret;
 }
 
 /**
@@ -5103,8 +5443,12 @@ int pevent_register_event_handler(struct pevent *pevent,
 
  not_found:
        /* Save for later use. */
-       handle = malloc_or_die(sizeof(*handle));
-       memset(handle, 0, sizeof(*handle));
+       handle = calloc(1, sizeof(*handle));
+       if (!handle) {
+               do_warning("Failed to allocate event handler");
+               return PEVENT_ERRNO__MEM_ALLOC_FAILED;
+       }
+
        handle->id = id;
        if (event_name)
                handle->event_name = strdup(event_name);
@@ -5113,7 +5457,11 @@ int pevent_register_event_handler(struct pevent *pevent,
 
        if ((event_name && !handle->event_name) ||
            (sys_name && !handle->sys_name)) {
-               die("Failed to allocate event/sys name");
+               do_warning("Failed to allocate event/sys name");
+               free((void *)handle->event_name);
+               free((void *)handle->sys_name);
+               free(handle);
+               return PEVENT_ERRNO__MEM_ALLOC_FAILED;
        }
 
        handle->func = func;
@@ -5129,13 +5477,10 @@ int pevent_register_event_handler(struct pevent *pevent,
  */
 struct pevent *pevent_alloc(void)
 {
-       struct pevent *pevent;
+       struct pevent *pevent = calloc(1, sizeof(*pevent));
 
-       pevent = malloc(sizeof(*pevent));
-       if (!pevent)
-               return NULL;
-       memset(pevent, 0, sizeof(*pevent));
-       pevent->ref_count = 1;
+       if (pevent)
+               pevent->ref_count = 1;
 
        return pevent;
 }
@@ -5164,7 +5509,7 @@ static void free_formats(struct format *format)
        free_format_fields(format->fields);
 }
 
-static void free_event(struct event_format *event)
+void pevent_free_format(struct event_format *event)
 {
        free(event->name);
        free(event->system);
@@ -5250,7 +5595,7 @@ void pevent_free(struct pevent *pevent)
        }
 
        for (i = 0; i < pevent->nr_events; i++)
-               free_event(pevent->events[i]);
+               pevent_free_format(pevent->events[i]);
 
        while (pevent->handlers) {
                handle = pevent->handlers;