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. Signed-off-by: Ilya Maximets <i.maxim...@ovn.org> --- .ci/linux-build.sh | 6 ++--- tests/test-ovsdb.c | 61 ++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 63 insertions(+), 4 deletions(-) diff --git a/.ci/linux-build.sh b/.ci/linux-build.sh index c396ec1e8..22e138df3 100755 --- a/.ci/linux-build.sh +++ b/.ci/linux-build.sh @@ -245,15 +245,13 @@ fi if [ "$ASAN" ]; then # This will override default option configured in tests/atlocal.in. export ASAN_OPTIONS='detect_leaks=1' - # -O2 generates few false-positive memory leak reports in test-ovsdb - # application, so lowering optimizations to -O1 here. - CFLAGS_ASAN="-O1 -fno-omit-frame-pointer -fno-common -fsanitize=address" + CFLAGS_ASAN="-fno-omit-frame-pointer -fno-common -fsanitize=address" CFLAGS_FOR_OVS="${CFLAGS_FOR_OVS} ${CFLAGS_ASAN}" fi if [ "$UBSAN" ]; then # Use the default options configured in tests/atlocal.in, in UBSAN_OPTIONS. - CFLAGS_UBSAN="-O1 -fno-omit-frame-pointer -fno-common -fsanitize=undefined" + CFLAGS_UBSAN="-fno-omit-frame-pointer -fno-common -fsanitize=undefined" CFLAGS_FOR_OVS="${CFLAGS_FOR_OVS} ${CFLAGS_UBSAN}" fi 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\": " -- 2.34.3 _______________________________________________ dev mailing list d...@openvswitch.org https://mail.openvswitch.org/mailman/listinfo/ovs-dev