From: David Lamparter Date: Wed, 25 Jan 2017 01:27:29 +0000 (+0100) Subject: lib: parser: fix memory management X-Git-Tag: frr-3.0-branchpoint~64^2~8^2 X-Git-Url: https://git.puffer.fish/?a=commitdiff_plain;h=refs%2Fpull%2F114%2Fhead;p=mirror%2Ffrr.git lib: parser: fix memory management command.c had: DEFINE_MTYPE_STATIC(LIB, CMD_TOKENS, "Command desc") while command_match.c had: DEFINE_MTYPE_STATIC(LIB, CMD_TOKENS, "Command Tokens") ... which means that there are 2 distinct MTYPE_CMD_TOKENS. (The description text being different does not matter, even with the same text it'd be 2 distinct types.) command_match.c allocates token->arg in command_match_r() while command.c frees it in del_cmd_token(). Therefore with each command being executed, the allocation count goes up on one, down on the other. => clean up parser allocation counting. Also, use separate MTYPEs for the different fields in struct cmd_token. Fixes: #108 / ee9216cf ("lib, ripngd: clean up merge leftovers") Signed-off-by: David Lamparter Cc: Quentin Young --- diff --git a/lib/command.c b/lib/command.c index b5dae5f28e..781f627bb5 100644 --- a/lib/command.c +++ b/lib/command.c @@ -43,7 +43,10 @@ DEFINE_MTYPE( LIB, HOST, "Host config") DEFINE_MTYPE( LIB, STRVEC, "String vector") -DEFINE_MTYPE_STATIC(LIB, CMD_TOKENS, "Command desc") +DEFINE_MTYPE_STATIC(LIB, CMD_TOKENS, "Command Tokens") +DEFINE_MTYPE_STATIC(LIB, CMD_DESC, "Command Token Text") +DEFINE_MTYPE_STATIC(LIB, CMD_TEXT, "Command Token Help") +DEFINE_MTYPE( LIB, CMD_ARG, "Command Argument") /* Command vector which includes some level of command lists. Normally each daemon maintains each own cmdvec. */ @@ -2405,13 +2408,14 @@ cmd_init (int terminal) } struct cmd_token * -new_cmd_token (enum cmd_token_type type, u_char attr, char *text, char *desc) +new_cmd_token (enum cmd_token_type type, u_char attr, + const char *text, const char *desc) { struct cmd_token *token = XCALLOC (MTYPE_CMD_TOKENS, sizeof (struct cmd_token)); token->type = type; token->attr = attr; - token->text = text; - token->desc = desc; + token->text = text ? XSTRDUP (MTYPE_CMD_TEXT, text) : NULL; + token->desc = desc ? XSTRDUP (MTYPE_CMD_DESC, desc) : NULL; token->arg = NULL; token->allowrepeat = false; @@ -2424,11 +2428,11 @@ del_cmd_token (struct cmd_token *token) if (!token) return; if (token->text) - XFREE (MTYPE_CMD_TOKENS, token->text); + XFREE (MTYPE_CMD_TEXT, token->text); if (token->desc) - XFREE (MTYPE_CMD_TOKENS, token->desc); + XFREE (MTYPE_CMD_DESC, token->desc); if (token->arg) - XFREE (MTYPE_CMD_TOKENS, token->arg); + XFREE (MTYPE_CMD_ARG, token->arg); XFREE (MTYPE_CMD_TOKENS, token); } @@ -2439,9 +2443,9 @@ copy_cmd_token (struct cmd_token *token) struct cmd_token *copy = new_cmd_token (token->type, token->attr, NULL, NULL); copy->max = token->max; copy->min = token->min; - copy->text = token->text ? XSTRDUP (MTYPE_CMD_TOKENS, token->text) : NULL; - copy->desc = token->desc ? XSTRDUP (MTYPE_CMD_TOKENS, token->desc) : NULL; - copy->arg = token->arg ? XSTRDUP (MTYPE_CMD_TOKENS, token->arg) : NULL; + copy->text = token->text ? XSTRDUP (MTYPE_CMD_TEXT, token->text) : NULL; + copy->desc = token->desc ? XSTRDUP (MTYPE_CMD_DESC, token->desc) : NULL; + copy->arg = token->arg ? XSTRDUP (MTYPE_CMD_ARG, token->arg) : NULL; return copy; } diff --git a/lib/command.h b/lib/command.h index 1e1698fc7d..1e490cc4cd 100644 --- a/lib/command.h +++ b/lib/command.h @@ -31,6 +31,7 @@ #include "hash.h" DECLARE_MTYPE(HOST) +DECLARE_MTYPE(CMD_ARG) /* for test-commands.c */ DECLARE_MTYPE(STRVEC) @@ -420,12 +421,10 @@ extern void cmd_exit (struct vty *vty); extern int cmd_list_cmds (struct vty *vty, int do_permute); /* memory management for cmd_token */ -struct cmd_token * -new_cmd_token (enum cmd_token_type, u_char attr, char *, char *); -void -del_cmd_token (struct cmd_token *); -struct cmd_token * -copy_cmd_token (struct cmd_token *); +extern struct cmd_token *new_cmd_token (enum cmd_token_type, u_char attr, + const char *text, const char *desc); +extern void del_cmd_token (struct cmd_token *); +extern struct cmd_token *copy_cmd_token (struct cmd_token *); extern void command_parse_format (struct graph *graph, struct cmd_element *cmd); diff --git a/lib/command_match.c b/lib/command_match.c index d228563240..aa58313134 100644 --- a/lib/command_match.c +++ b/lib/command_match.c @@ -27,7 +27,6 @@ #include "command_match.h" #include "memory.h" -DEFINE_MTYPE_STATIC(LIB, CMD_TOKENS, "Command Tokens") DEFINE_MTYPE_STATIC(LIB, CMD_MATCHSTACK, "Command Match Stack") #define MAXDEPTH 64 @@ -322,7 +321,7 @@ command_match_r (struct graph_node *start, vector vline, unsigned int n, // copy token, set arg and prepend to currbest struct cmd_token *token = start->data; struct cmd_token *copy = copy_cmd_token (token); - copy->arg = XSTRDUP (MTYPE_CMD_TOKENS, input_token); + copy->arg = XSTRDUP (MTYPE_CMD_ARG, input_token); listnode_add_before (currbest, currbest->head, copy); matcher_rv = MATCHER_OK; } diff --git a/lib/command_parse.y b/lib/command_parse.y index c920e11380..7f98704f90 100644 --- a/lib/command_parse.y +++ b/lib/command_parse.y @@ -115,7 +115,7 @@ }; /* helper functions for parser */ - static char * + static const char * doc_next (struct parser_ctx *ctx); static struct graph_node * @@ -130,8 +130,8 @@ static struct graph_node * new_token_node (struct parser_ctx *, enum cmd_token_type type, - char *text, - char *doc); + const char *text, + const char *doc); static void terminate_graph (struct parser_ctx *ctx, @@ -222,7 +222,7 @@ compound_token: literal_token: WORD { - $$ = new_token_node (ctx, WORD_TKN, strdup($1), doc_next(ctx)); + $$ = new_token_node (ctx, WORD_TKN, $1, doc_next(ctx)); free ($1); } ; @@ -230,32 +230,32 @@ literal_token: WORD placeholder_token: IPV4 { - $$ = new_token_node (ctx, IPV4_TKN, strdup($1), doc_next(ctx)); + $$ = new_token_node (ctx, IPV4_TKN, $1, doc_next(ctx)); free ($1); } | IPV4_PREFIX { - $$ = new_token_node (ctx, IPV4_PREFIX_TKN, strdup($1), doc_next(ctx)); + $$ = new_token_node (ctx, IPV4_PREFIX_TKN, $1, doc_next(ctx)); free ($1); } | IPV6 { - $$ = new_token_node (ctx, IPV6_TKN, strdup($1), doc_next(ctx)); + $$ = new_token_node (ctx, IPV6_TKN, $1, doc_next(ctx)); free ($1); } | IPV6_PREFIX { - $$ = new_token_node (ctx, IPV6_PREFIX_TKN, strdup($1), doc_next(ctx)); + $$ = new_token_node (ctx, IPV6_PREFIX_TKN, $1, doc_next(ctx)); free ($1); } | VARIABLE { - $$ = new_token_node (ctx, VARIABLE_TKN, strdup($1), doc_next(ctx)); + $$ = new_token_node (ctx, VARIABLE_TKN, $1, doc_next(ctx)); free ($1); } | RANGE { - $$ = new_token_node (ctx, RANGE_TKN, strdup($1), doc_next(ctx)); + $$ = new_token_node (ctx, RANGE_TKN, $1, doc_next(ctx)); struct cmd_token *token = $$->data; // get the numbers out @@ -462,10 +462,7 @@ terminate_graph (struct parser_ctx *ctx, struct graph_node *finalnode) // * -> finalnode -> END_TKN -> cmd_element struct cmd_element *element = ctx->el; struct graph_node *end_token_node = - new_token_node (ctx, - END_TKN, - strdup (CMD_CR_TEXT), - strdup ("")); + new_token_node (ctx, END_TKN, CMD_CR_TEXT, ""); struct graph_node *end_element_node = graph_new_node (ctx->graph, element, NULL); @@ -476,7 +473,7 @@ terminate_graph (struct parser_ctx *ctx, struct graph_node *finalnode) graph_add_edge (end_token_node, end_element_node); } -static char * +static const char * doc_next (struct parser_ctx *ctx) { const char *piece = ctx->docstr ? strsep (&ctx->docstr, "\n") : ""; @@ -486,12 +483,12 @@ doc_next (struct parser_ctx *ctx) piece = ""; } - return strdup (piece); + return piece; } static struct graph_node * new_token_node (struct parser_ctx *ctx, enum cmd_token_type type, - char *text, char *doc) + const char *text, const char *doc) { struct cmd_token *token = new_cmd_token (type, ctx->el->attr, text, doc); return graph_new_node (ctx->graph, token, (void (*)(void *)) &del_cmd_token);