From 17b9d620e2b48a8fd872cd23a85a5174e8f858e5 Mon Sep 17 00:00:00 2001 From: Michael Tuexen <tuexen@fh-muenster.de> Date: Sat, 13 Oct 2018 05:36:03 +0200 Subject: [PATCH] Add cleanup routines freeing memory. --- gtests/net/packetdrill/config.c | 28 +++++++++++++++- gtests/net/packetdrill/config.h | 5 ++- gtests/net/packetdrill/packetdrill.c | 4 +++ gtests/net/packetdrill/script.c | 50 ++++++++++++++++++++++++++++ gtests/net/packetdrill/script.h | 11 +++--- gtests/net/packetdrill/wire_client.c | 2 +- 6 files changed, 93 insertions(+), 7 deletions(-) diff --git a/gtests/net/packetdrill/config.c b/gtests/net/packetdrill/config.c index 77646729..14cd675b 100644 --- a/gtests/net/packetdrill/config.c +++ b/gtests/net/packetdrill/config.c @@ -210,7 +210,7 @@ static void set_ipv6_defaults(struct config *config) /* Set default configuration before we begin parsing. */ void set_default_config(struct config *config) { - memset(config, 0, sizeof(*config)); + cleanup_config(config); #if defined(__FreeBSD__) config->code_command_line = "/usr/local/bin/python"; #else @@ -387,6 +387,32 @@ void finalize_config(struct config *config) #endif } +void cleanup_config(struct config *config) +{ + struct definition *cur_def, *next_def; + int i; + + if (config->argv != NULL) { + for (i = 0; config->argv[i] != NULL; i++) { + free(config->argv[i]); + } + } + free(config->argv); + free(config->script_path); +#if defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__NetBSD__) + free(config->tun_device); +#endif + cur_def = config->defines; + while (cur_def != NULL) { + next_def = cur_def->next; + free(cur_def->symbol); + free(cur_def->value); + free(cur_def); + cur_def = next_def; + } + memset(config, 0, sizeof(struct config)); +} + /* Expect that arg is comma-delimited, allowing for spaces. */ void parse_non_fatal_arg(char *arg, struct config *config) { diff --git a/gtests/net/packetdrill/config.h b/gtests/net/packetdrill/config.h index 561785d3..31b5e92a 100644 --- a/gtests/net/packetdrill/config.h +++ b/gtests/net/packetdrill/config.h @@ -69,6 +69,7 @@ static inline void definition_set(struct definition **defs, if (def) { free(def->value); def->value = value; + free(symbol); } else { def = calloc(1, sizeof(struct definition)); def->symbol = symbol; @@ -87,7 +88,7 @@ static inline char *definition_get(struct definition *defs, char *symbol) } struct config { - const char **argv; /* a copy of process argv */ + char **argv; /* a copy of process argv */ enum ip_version_t ip_version; /* v4, v4-mapped-v6, v6 */ int socket_domain; /* AF_INET or AF_INET6 */ @@ -187,6 +188,8 @@ extern void parse_non_fatal_arg(char *arg, struct config *config); */ extern void finalize_config(struct config *config); +extern void cleanup_config(struct config *config); + extern void show_usage(void); /* Parse command line options. Returns a pointer to the first argument diff --git a/gtests/net/packetdrill/packetdrill.c b/gtests/net/packetdrill/packetdrill.c index 6450e4b7..81e2ebe7 100644 --- a/gtests/net/packetdrill/packetdrill.c +++ b/gtests/net/packetdrill/packetdrill.c @@ -76,6 +76,7 @@ int main(int argc, char *argv[]) pthread_set_name_np(pthread_self(), "main thread"); #endif + memset(&config, 0, sizeof(struct config)); set_default_config(&config); /* Get command line options and list of test scripts. */ arg = parse_command_line_options(argc, argv, &config); @@ -98,6 +99,7 @@ int main(int argc, char *argv[]) } } run_wire_server(&config); + cleanup_config(&config); return 0; } @@ -126,7 +128,9 @@ int main(int argc, char *argv[]) run_init_scripts(&config); run_script(&config, &script); + free_script(&script); } + cleanup_config(&config); return 0; } diff --git a/gtests/net/packetdrill/script.c b/gtests/net/packetdrill/script.c index 630abcb1..b57d0d62 100644 --- a/gtests/net/packetdrill/script.c +++ b/gtests/net/packetdrill/script.c @@ -47,6 +47,56 @@ void init_script(struct script *script) script->event_list = NULL; } +/* Free resources used by a script object */ +void free_script(struct script *script) +{ + struct option_list *cur_option, *next_option; + struct event *cur_event, *next_event; + + cur_option = script->option_list; + while (cur_option != NULL) { + next_option = cur_option->next; + free(cur_option->name); + free(cur_option->value); + free(cur_option); + cur_option = next_option; + } + cur_event = script->event_list; + while (cur_event != NULL) { + next_event = cur_event->next; + switch (cur_event->type) { + case PACKET_EVENT: + packet_free(cur_event->event.packet); + break; + case SYSCALL_EVENT: + free(cur_event->event.syscall->name); + free_expression_list(cur_event->event.syscall->arguments); + free_expression(cur_event->event.syscall->result); + if (cur_event->event.syscall->error != NULL) { + free(cur_event->event.syscall->error->errno_macro); + free(cur_event->event.syscall->error->strerror); + } + free(cur_event->event.syscall->error); + free(cur_event->event.syscall->note); + free(cur_event->event.syscall); + break; + case COMMAND_EVENT: + free(cur_event->event.command->command_line); + free(cur_event->event.command); + break; + case CODE_EVENT: + free(cur_event->event.code); + break; + default: + assert(!"bad event type"); + break; + } + free(cur_event); + cur_event = next_event; + } + free(script->buffer); +} + /* This table maps expression types to human-readable strings */ struct expression_type_entry { enum expression_t type; diff --git a/gtests/net/packetdrill/script.h b/gtests/net/packetdrill/script.h index 228442b0..5e21a2c5 100644 --- a/gtests/net/packetdrill/script.h +++ b/gtests/net/packetdrill/script.h @@ -666,8 +666,8 @@ struct sctp_udpencaps_expr { /* The errno-related info from strace to summarize a system call error */ struct errno_spec { - const char *errno_macro; /* errno symbol (C macro name) */ - const char *strerror; /* strerror translation of errno */ + char *errno_macro; /* errno symbol (C macro name) */ + char *strerror; /* strerror translation of errno */ }; /* A system call and its expected result. System calls that should @@ -677,7 +677,7 @@ struct errno_spec { * return. */ struct syscall_spec { - const char *name; /* name of system call */ + char *name; /* name of system call */ struct expression_list *arguments; /* arguments to system call */ struct expression *result; /* expected result from call */ struct errno_spec *error; /* errno symbol or NULL */ @@ -693,7 +693,7 @@ static inline bool is_blocking_syscall(struct syscall_spec *syscall) /* A shell command line to execute using system(3) */ struct command_spec { - const char *command_line; /* executed with /bin/sh */ + char *command_line; /* executed with /bin/sh */ }; /* An ASCII text snippet of code to insert in the post-processing @@ -783,6 +783,9 @@ struct flag_name { /* Initialize a script object */ extern void init_script(struct script *script); +/* Free resources used by a script object */ +extern void free_script(struct script *script); + /* Look up the value of the given symbol, and fill it in. On success, * return STATUS_OK; if the symbol cannot be found, return * STATUS_ERR and fill in an error message in *error. diff --git a/gtests/net/packetdrill/wire_client.c b/gtests/net/packetdrill/wire_client.c index b47c54f8..c05d7a56 100644 --- a/gtests/net/packetdrill/wire_client.c +++ b/gtests/net/packetdrill/wire_client.c @@ -53,7 +53,7 @@ static void wire_client_die(struct wire_client *wire_client, * characters between args. We do not send the -wire_client argument, * since we don't want to give the server an identity crisis. */ -static void wire_client_serialize_argv(const char **argv, char **args_ptr, +static void wire_client_serialize_argv(char **argv, char **args_ptr, int *args_len_ptr) { int i; -- GitLab