From c43da842fb26e74653e5456ff796b30947f1c6ff Mon Sep 17 00:00:00 2001 From: Ilya Maximets Date: Thu, 28 Jul 2022 17:42:32 +0200 Subject: test-ovsdb: Fix false-positive leaks from LeakSanitizer. LeakSanitizer for some reason reports these json objects as leaked, even though we do have references to them at the moment ovs_fatal() called from check_ovsdb_error(). Previously it complained only with -O2, but with newer versions of clang/llvm it started complaining even with -O1. For example, negative ovsdb parsing tests are failing on ubuntu 22.04 with clang 14 if built with ASan and detect_leaks=1. Fix that by destroying the json object before aborting the process. And we may also build with default -O2 in CI with that change. Alternative implementation might be to just pass the json to destroy to every check_ovsdb_error() call, but indirect registering of the pointer seems a bit less invasive. Acked-by: Ales Musil Signed-off-by: Ilya Maximets --- tests/test-ovsdb.c | 61 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 61 insertions(+) (limited to 'tests/test-ovsdb.c') diff --git a/tests/test-ovsdb.c b/tests/test-ovsdb.c index 343833151..965b0f913 100644 --- a/tests/test-ovsdb.c +++ b/tests/test-ovsdb.c @@ -300,11 +300,24 @@ print_and_free_ovsdb_error(struct ovsdb_error *error) free(string); } +static struct json **json_to_destroy; + +static void +destroy_on_ovsdb_error(struct json **json) +{ + json_to_destroy = json; +} + static void check_ovsdb_error(struct ovsdb_error *error) { if (error) { char *s = ovsdb_error_to_string_free(error); + + if (json_to_destroy) { + json_destroy(*json_to_destroy); + json_to_destroy = NULL; + } ovs_fatal(0, "%s", s); } } @@ -487,6 +500,8 @@ do_diff_data(struct ovs_cmdl_context *ctx) struct json *json; struct ovsdb_datum new, old, diff, reincarnation; + destroy_on_ovsdb_error(&json); + json = unbox_json(parse_json(ctx->argv[1])); check_ovsdb_error(ovsdb_type_from_json(&type, json)); json_destroy(json); @@ -562,6 +577,8 @@ do_parse_atomic_type(struct ovs_cmdl_context *ctx) enum ovsdb_atomic_type type; struct json *json; + destroy_on_ovsdb_error(&json); + json = unbox_json(parse_json(ctx->argv[1])); check_ovsdb_error(ovsdb_atomic_type_from_json(&type, json)); json_destroy(json); @@ -574,6 +591,8 @@ do_parse_base_type(struct ovs_cmdl_context *ctx) struct ovsdb_base_type base; struct json *json; + destroy_on_ovsdb_error(&json); + json = unbox_json(parse_json(ctx->argv[1])); check_ovsdb_error(ovsdb_base_type_from_json(&base, json)); json_destroy(json); @@ -587,6 +606,8 @@ do_parse_type(struct ovs_cmdl_context *ctx) struct ovsdb_type type; struct json *json; + destroy_on_ovsdb_error(&json); + json = unbox_json(parse_json(ctx->argv[1])); check_ovsdb_error(ovsdb_type_from_json(&type, json)); json_destroy(json); @@ -601,6 +622,8 @@ do_parse_atoms(struct ovs_cmdl_context *ctx) struct json *json; int i; + destroy_on_ovsdb_error(&json); + json = unbox_json(parse_json(ctx->argv[1])); check_ovsdb_error(ovsdb_base_type_from_json(&base, json)); json_destroy(json); @@ -630,6 +653,8 @@ do_parse_atom_strings(struct ovs_cmdl_context *ctx) struct json *json; int i; + destroy_on_ovsdb_error(&json); + json = unbox_json(parse_json(ctx->argv[1])); check_ovsdb_error(ovsdb_base_type_from_json(&base, json)); json_destroy(json); @@ -675,6 +700,8 @@ do_parse_data__(int argc, char *argv[], struct json *json; int i; + destroy_on_ovsdb_error(&json); + json = unbox_json(parse_json(argv[1])); check_ovsdb_error(ovsdb_type_from_json(&type, json)); json_destroy(json); @@ -706,6 +733,8 @@ do_parse_data_strings(struct ovs_cmdl_context *ctx) struct json *json; int i; + destroy_on_ovsdb_error(&json); + json = unbox_json(parse_json(ctx->argv[1])); check_ovsdb_error(ovsdb_type_from_json(&type, json)); json_destroy(json); @@ -746,6 +775,8 @@ do_sort_atoms(struct ovs_cmdl_context *ctx) size_t n_atoms; int i; + destroy_on_ovsdb_error(&json); + json = unbox_json(parse_json(ctx->argv[1])); check_ovsdb_error(ovsdb_base_type_from_json(&base, json)); json_destroy(json); @@ -785,6 +816,8 @@ do_parse_column(struct ovs_cmdl_context *ctx) struct ovsdb_column *column; struct json *json; + destroy_on_ovsdb_error(&json); + json = parse_json(ctx->argv[2]); check_ovsdb_error(ovsdb_column_from_json(json, ctx->argv[1], &column)); json_destroy(json); @@ -801,6 +834,8 @@ do_parse_table(struct ovs_cmdl_context *ctx) default_is_root = ctx->argc > 3 && !strcmp(ctx->argv[3], "true"); + destroy_on_ovsdb_error(&json); + json = parse_json(ctx->argv[2]); check_ovsdb_error(ovsdb_table_schema_from_json(json, ctx->argv[1], &ts)); json_destroy(json); @@ -817,6 +852,8 @@ do_parse_rows(struct ovs_cmdl_context *ctx) struct json *json; int i; + destroy_on_ovsdb_error(&json); + json = unbox_json(parse_json(ctx->argv[1])); check_ovsdb_error(ovsdb_table_schema_from_json(json, "mytable", &ts)); json_destroy(json); @@ -876,6 +913,8 @@ do_compare_rows(struct ovs_cmdl_context *ctx) int n_rows; int i, j; + destroy_on_ovsdb_error(&json); + json = unbox_json(parse_json(ctx->argv[1])); check_ovsdb_error(ovsdb_table_schema_from_json(json, "mytable", &ts)); json_destroy(json); @@ -935,6 +974,8 @@ do_parse_conditions(struct ovs_cmdl_context *ctx) int exit_code = 0; int i; + destroy_on_ovsdb_error(&json); + json = unbox_json(parse_json(ctx->argv[1])); check_ovsdb_error(ovsdb_table_schema_from_json(json, "mytable", &ts)); json_destroy(json); @@ -977,6 +1018,8 @@ do_evaluate_condition__(struct ovs_cmdl_context *ctx, int mode) struct json *json; size_t i, j; + destroy_on_ovsdb_error(&json); + /* Parse table schema, create table. */ json = unbox_json(parse_json(ctx->argv[1])); check_ovsdb_error(ovsdb_table_schema_from_json(json, "mytable", &ts)); @@ -1064,6 +1107,8 @@ do_compare_conditions(struct ovs_cmdl_context *ctx) struct json *json; size_t i; + destroy_on_ovsdb_error(&json); + /* Parse table schema, create table. */ json = unbox_json(parse_json(ctx->argv[1])); check_ovsdb_error(ovsdb_table_schema_from_json(json, "mytable", &ts)); @@ -1105,6 +1150,8 @@ do_parse_mutations(struct ovs_cmdl_context *ctx) int exit_code = 0; int i; + destroy_on_ovsdb_error(&json); + json = unbox_json(parse_json(ctx->argv[1])); check_ovsdb_error(ovsdb_table_schema_from_json(json, "mytable", &ts)); json_destroy(json); @@ -1144,6 +1191,8 @@ do_execute_mutations(struct ovs_cmdl_context *ctx) struct json *json; size_t i, j; + destroy_on_ovsdb_error(&json); + /* Parse table schema, create table. */ json = unbox_json(parse_json(ctx->argv[1])); check_ovsdb_error(ovsdb_table_schema_from_json(json, "mytable", &ts)); @@ -1268,6 +1317,8 @@ do_query(struct ovs_cmdl_context *ctx) int exit_code = 0; size_t i; + destroy_on_ovsdb_error(&json); + /* Parse table schema, create table. */ json = unbox_json(parse_json(ctx->argv[1])); check_ovsdb_error(ovsdb_table_schema_from_json(json, "mytable", &ts)); @@ -1362,6 +1413,8 @@ do_query_distinct(struct ovs_cmdl_context *ctx) int exit_code = 0; size_t i; + destroy_on_ovsdb_error(&json); + /* Parse table schema, create table. */ json = unbox_json(parse_json(ctx->argv[1])); check_ovsdb_error(ovsdb_table_schema_from_json(json, "mytable", &ts)); @@ -1489,6 +1542,8 @@ do_parse_schema(struct ovs_cmdl_context *ctx) struct ovsdb_schema *schema; struct json *json; + destroy_on_ovsdb_error(&json); + json = parse_json(ctx->argv[1]); check_ovsdb_error(ovsdb_schema_from_json(json, &schema)); json_destroy(json); @@ -1504,6 +1559,8 @@ do_execute__(struct ovs_cmdl_context *ctx, bool ro) struct ovsdb *db; int i; + destroy_on_ovsdb_error(&json); + /* Create database. */ json = parse_json(ctx->argv[1]); check_ovsdb_error(ovsdb_schema_from_json(json, &schema)); @@ -1570,6 +1627,8 @@ do_trigger(struct ovs_cmdl_context *ctx) int number; int i; + destroy_on_ovsdb_error(&json); + /* Create database. */ json = parse_json(ctx->argv[1]); check_ovsdb_error(ovsdb_schema_from_json(json, &schema)); @@ -1796,6 +1855,8 @@ do_transact(struct ovs_cmdl_context *ctx) struct json *json; int i; + destroy_on_ovsdb_error(&json); + /* Create table. */ json = parse_json("{\"name\": \"testdb\", " " \"tables\": " -- cgit v1.2.1