On Thu, Jul 28, 2022 at 5:43 PM Ilya Maximets <i.maxim...@ovn.org> wrote:
> 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 > > Hi Ilya, I actually saw that couple of times even when running the OVN tests. Acked-by: Ales Musil <amu...@redhat.com> Thanks, Ales -- Ales Musil Senior Software Engineer - OVN Core Red Hat EMEA <https://www.redhat.com> amu...@redhat.com IM: amusil <https://red.ht/sig> _______________________________________________ dev mailing list d...@openvswitch.org https://mail.openvswitch.org/mailman/listinfo/ovs-dev