From 238b7404b66983c6ba15c3a44bfbf642f20bdabe Mon Sep 17 00:00:00 2001 From: Philippe Proulx Date: Fri, 30 Nov 2018 15:51:42 -0500 Subject: [PATCH] lib: trace IR, values: reset pointers to `NULL` on destruction When an object's member is destroyed, internally, reset its pointer to `NULL` immediately. This makes it possible to log partial objects during destruction while keeping Valgrind's memcheck happy. Signed-off-by: Philippe Proulx --- lib/trace-ir/attributes.c | 2 +- lib/trace-ir/clock-class.c | 4 ++++ lib/trace-ir/clock-value.c | 2 +- lib/trace-ir/event-class.c | 6 ++++-- lib/trace-ir/event.c | 7 ++++++- lib/trace-ir/field-classes.c | 18 ++++++++++++------ lib/trace-ir/field-path.c | 1 + lib/trace-ir/field-wrapper.c | 1 + lib/trace-ir/fields.c | 6 +++++- lib/trace-ir/packet.c | 8 +++++++- lib/trace-ir/stream-class.c | 11 +++++++---- lib/trace-ir/stream.c | 2 ++ lib/trace-ir/trace.c | 8 ++++++++ lib/values.c | 3 +++ 14 files changed, 62 insertions(+), 17 deletions(-) diff --git a/lib/trace-ir/attributes.c b/lib/trace-ir/attributes.c index 68c83f5f..44068de2 100644 --- a/lib/trace-ir/attributes.c +++ b/lib/trace-ir/attributes.c @@ -71,7 +71,7 @@ BT_HIDDEN void bt_attributes_destroy(struct bt_private_value *attr_obj) { BT_LOGD("Destroying attributes object: addr=%p", attr_obj); - bt_object_put_ref(attr_obj); + BT_OBJECT_PUT_REF_AND_RESET(attr_obj); } BT_HIDDEN diff --git a/lib/trace-ir/clock-class.c b/lib/trace-ir/clock-class.c index d268ec3f..4cfd01c8 100644 --- a/lib/trace-ir/clock-class.c +++ b/lib/trace-ir/clock-class.c @@ -50,10 +50,14 @@ void destroy_clock_class(struct bt_object *obj) if (clock_class->name.str) { g_string_free(clock_class->name.str, TRUE); + clock_class->name.str = NULL; + clock_class->name.value = NULL; } if (clock_class->description.str) { g_string_free(clock_class->description.str, TRUE); + clock_class->description.str = NULL; + clock_class->description.value = NULL; } bt_object_pool_finalize(&clock_class->cv_pool); diff --git a/lib/trace-ir/clock-value.c b/lib/trace-ir/clock-value.c index 877d8687..affc565c 100644 --- a/lib/trace-ir/clock-value.c +++ b/lib/trace-ir/clock-value.c @@ -39,7 +39,7 @@ BT_HIDDEN void bt_clock_value_destroy(struct bt_clock_value *clock_value) { BT_LIB_LOGD("Destroying clock value: %!+k", clock_value); - bt_object_put_ref(clock_value->clock_class); + BT_OBJECT_PUT_REF_AND_RESET(clock_value->clock_class); g_free(clock_value); } diff --git a/lib/trace-ir/event-class.c b/lib/trace-ir/event-class.c index 15397ff6..685c09c3 100644 --- a/lib/trace-ir/event-class.c +++ b/lib/trace-ir/event-class.c @@ -63,16 +63,18 @@ void destroy_event_class(struct bt_object *obj) if (event_class->name.str) { g_string_free(event_class->name.str, TRUE); + event_class->name.str = NULL; } if (event_class->emf_uri.str) { g_string_free(event_class->emf_uri.str, TRUE); + event_class->emf_uri.str = NULL; } BT_LOGD_STR("Putting context field classe."); - bt_object_put_ref(event_class->specific_context_fc); + BT_OBJECT_PUT_REF_AND_RESET(event_class->specific_context_fc); BT_LOGD_STR("Putting payload field classe."); - bt_object_put_ref(event_class->payload_fc); + BT_OBJECT_PUT_REF_AND_RESET(event_class->payload_fc); bt_object_pool_finalize(&event_class->event_pool); g_free(obj); } diff --git a/lib/trace-ir/event.c b/lib/trace-ir/event.c index dc88ab5c..7d31a401 100644 --- a/lib/trace-ir/event.c +++ b/lib/trace-ir/event.c @@ -283,21 +283,25 @@ void bt_event_destroy(struct bt_event *event) if (event->header_field) { BT_LOGD_STR("Releasing event's header field."); release_event_header_field(event->header_field, event); + event->header_field = NULL; } if (event->common_context_field) { BT_LOGD_STR("Destroying event's stream event context field."); bt_field_destroy(event->common_context_field); + event->common_context_field = NULL; } if (event->specific_context_field) { BT_LOGD_STR("Destroying event's context field."); bt_field_destroy(event->specific_context_field); + event->specific_context_field = NULL; } if (event->payload_field) { BT_LOGD_STR("Destroying event's payload field."); bt_field_destroy(event->payload_field); + event->payload_field = NULL; } BT_LOGD_STR("Putting event's class."); @@ -305,10 +309,11 @@ void bt_event_destroy(struct bt_event *event) if (event->default_cv) { bt_clock_value_recycle(event->default_cv); + event->default_cv = NULL; } BT_LOGD_STR("Putting event's packet."); - bt_object_put_ref(event->packet); + BT_OBJECT_PUT_REF_AND_RESET(event->packet); g_free(event); } diff --git a/lib/trace-ir/field-classes.c b/lib/trace-ir/field-classes.c index 485482f8..2adf0348 100644 --- a/lib/trace-ir/field-classes.c +++ b/lib/trace-ir/field-classes.c @@ -216,10 +216,12 @@ void destroy_enumeration_field_class(struct bt_object *obj) } g_array_free(fc->mappings, TRUE); + fc->mappings = NULL; } if (fc->label_buf) { g_ptr_array_free(fc->label_buf, TRUE); + fc->label_buf = NULL; } g_free(fc); @@ -668,7 +670,7 @@ void finalize_named_field_class(struct bt_named_field_class *named_fc) } BT_LOGD_STR("Putting named field class's field class."); - bt_object_put_ref(named_fc->fc); + BT_OBJECT_PUT_REF_AND_RESET(named_fc->fc); } static @@ -876,7 +878,9 @@ void destroy_variant_field_class(struct bt_object *obj) BT_LIB_LOGD("Destroying variant field class object: %!+F", fc); finalize_named_field_classes_container((void *) fc); BT_LOGD_STR("Putting selector field path."); - bt_object_put_ref(fc->selector_field_path); + BT_OBJECT_PUT_REF_AND_RESET(fc->selector_field_path); + BT_LOGD_STR("Putting selector field class."); + BT_OBJECT_PUT_REF_AND_RESET(fc->selector_fc); g_free(fc); } @@ -920,7 +924,7 @@ int bt_private_field_class_variant_set_selector_field_class( BT_ASSERT_PRE_FC_HAS_ID(fc, BT_FIELD_CLASS_TYPE_VARIANT, "Field class"); BT_ASSERT_PRE_FC_IS_ENUM(selector_fc, "Selector field class"); BT_ASSERT_PRE_FC_HOT(fc, "Variant field class"); - var_fc->selector_fc = (void *) selector_fc; + var_fc->selector_fc = bt_object_get_ref(selector_fc); bt_field_class_freeze((void *) selector_fc); return 0; } @@ -1008,7 +1012,7 @@ void finalize_array_field_class(struct bt_field_class_array *array_fc) { BT_ASSERT(array_fc); BT_LOGD_STR("Putting element field class."); - bt_object_put_ref(array_fc->element_fc); + BT_OBJECT_PUT_REF_AND_RESET(array_fc->element_fc); } static @@ -1086,7 +1090,9 @@ void destroy_dynamic_array_field_class(struct bt_object *obj) BT_LIB_LOGD("Destroying dynamic array field class object: %!+F", fc); finalize_array_field_class((void *) fc); BT_LOGD_STR("Putting length field path."); - bt_object_put_ref(fc->length_field_path); + BT_OBJECT_PUT_REF_AND_RESET(fc->length_field_path); + BT_LOGD_STR("Putting length field class."); + BT_OBJECT_PUT_REF_AND_RESET(fc->length_fc); g_free(fc); } @@ -1130,7 +1136,7 @@ int bt_private_field_class_dynamic_array_set_length_field_class( "Field class"); BT_ASSERT_PRE_FC_IS_UNSIGNED_INT(length_fc, "Length field class"); BT_ASSERT_PRE_FC_HOT(fc, "Dynamic array field class"); - array_fc->length_fc = length_fc; + array_fc->length_fc = bt_object_get_ref(length_fc); bt_field_class_freeze(length_fc); return 0; } diff --git a/lib/trace-ir/field-path.c b/lib/trace-ir/field-path.c index 613974e6..48a03a86 100644 --- a/lib/trace-ir/field-path.c +++ b/lib/trace-ir/field-path.c @@ -44,6 +44,7 @@ void destroy_field_path(struct bt_object *obj) BT_ASSERT(field_path); BT_LIB_LOGD("Destroying field path: %!+P", field_path); g_array_free(field_path->indexes, TRUE); + field_path->indexes = NULL; g_free(field_path); } diff --git a/lib/trace-ir/field-wrapper.c b/lib/trace-ir/field-wrapper.c index ed50537a..08cd11e6 100644 --- a/lib/trace-ir/field-wrapper.c +++ b/lib/trace-ir/field-wrapper.c @@ -58,6 +58,7 @@ void bt_field_wrapper_destroy(struct bt_field_wrapper *field_wrapper) if (field_wrapper->field) { BT_LOGD_STR("Destroying field."); bt_field_destroy((void *) field_wrapper->field); + field_wrapper->field = NULL; } BT_LOGD_STR("Putting stream class."); diff --git a/lib/trace-ir/fields.c b/lib/trace-ir/fields.c index 91e85099..8eadc757 100644 --- a/lib/trace-ir/fields.c +++ b/lib/trace-ir/fields.c @@ -871,7 +871,7 @@ void bt_field_finalize(struct bt_field *field) { BT_ASSERT(field); BT_LOGD_STR("Putting field's class."); - bt_object_put_ref(field->class); + BT_OBJECT_PUT_REF_AND_RESET(field->class); } static @@ -903,6 +903,7 @@ void destroy_structure_field(struct bt_field *field) if (struct_field->fields) { g_ptr_array_free(struct_field->fields, TRUE); + struct_field->fields = NULL; } g_free(field); @@ -919,6 +920,7 @@ void destroy_variant_field(struct bt_field *field) if (var_field->fields) { g_ptr_array_free(var_field->fields, TRUE); + var_field->fields = NULL; } g_free(field); @@ -935,6 +937,7 @@ void destroy_array_field(struct bt_field *field) if (array_field->fields) { g_ptr_array_free(array_field->fields, TRUE); + array_field->fields = NULL; } g_free(field); @@ -951,6 +954,7 @@ void destroy_string_field(struct bt_field *field) if (string_field->buf) { g_array_free(string_field->buf, TRUE); + string_field->buf = NULL; } g_free(field); diff --git a/lib/trace-ir/packet.c b/lib/trace-ir/packet.c index 44a06fb0..983887c4 100644 --- a/lib/trace-ir/packet.c +++ b/lib/trace-ir/packet.c @@ -218,6 +218,8 @@ void bt_packet_destroy(struct bt_packet *packet) } else { bt_field_wrapper_destroy(packet->header_field); } + + packet->header_field = NULL; } if (packet->context_field) { @@ -228,20 +230,24 @@ void bt_packet_destroy(struct bt_packet *packet) } else { bt_field_wrapper_destroy(packet->context_field); } + + packet->context_field = NULL; } if (packet->default_beginning_cv) { BT_LOGD_STR("Recycling beginning clock value."); bt_clock_value_recycle(packet->default_beginning_cv); + packet->default_beginning_cv = NULL; } if (packet->default_end_cv) { BT_LOGD_STR("Recycling end clock value."); bt_clock_value_recycle(packet->default_end_cv); + packet->default_end_cv = NULL; } BT_LOGD_STR("Putting packet's stream."); - bt_object_put_ref(packet->stream); + BT_OBJECT_PUT_REF_AND_RESET(packet->stream); g_free(packet); } diff --git a/lib/trace-ir/stream-class.c b/lib/trace-ir/stream-class.c index d3e1e90e..9d016844 100644 --- a/lib/trace-ir/stream-class.c +++ b/lib/trace-ir/stream-class.c @@ -56,23 +56,26 @@ void destroy_stream_class(struct bt_object *obj) BT_LIB_LOGD("Destroying stream class: %!+S", stream_class); BT_LOGD_STR("Putting default clock class."); - bt_object_put_ref(stream_class->default_clock_class); + BT_OBJECT_PUT_REF_AND_RESET(stream_class->default_clock_class); if (stream_class->event_classes) { BT_LOGD_STR("Destroying event classes."); g_ptr_array_free(stream_class->event_classes, TRUE); + stream_class->event_classes = NULL; } if (stream_class->name.str) { g_string_free(stream_class->name.str, TRUE); + stream_class->name.str = NULL; + stream_class->name.value = NULL; } BT_LOGD_STR("Putting event header field classe."); - bt_object_put_ref(stream_class->event_header_fc); + BT_OBJECT_PUT_REF_AND_RESET(stream_class->event_header_fc); BT_LOGD_STR("Putting packet context field classe."); - bt_object_put_ref(stream_class->packet_context_fc); + BT_OBJECT_PUT_REF_AND_RESET(stream_class->packet_context_fc); BT_LOGD_STR("Putting event common context field classe."); - bt_object_put_ref(stream_class->event_common_context_fc); + BT_OBJECT_PUT_REF_AND_RESET(stream_class->event_common_context_fc); bt_object_pool_finalize(&stream_class->event_header_field_pool); bt_object_pool_finalize(&stream_class->packet_context_field_pool); g_free(stream_class); diff --git a/lib/trace-ir/stream.c b/lib/trace-ir/stream.c index 5bf37b52..c90728da 100644 --- a/lib/trace-ir/stream.c +++ b/lib/trace-ir/stream.c @@ -54,6 +54,8 @@ void destroy_stream(struct bt_object *obj) if (stream->name.str) { g_string_free(stream->name.str, TRUE); + stream->name.str = NULL; + stream->name.value = NULL; } bt_object_pool_finalize(&stream->packet_pool); diff --git a/lib/trace-ir/trace.c b/lib/trace-ir/trace.c index b57f2dcc..f5c66cb8 100644 --- a/lib/trace-ir/trace.c +++ b/lib/trace-ir/trace.c @@ -89,6 +89,7 @@ void destroy_trace(struct bt_object *obj) } g_array_free(trace->is_static_listeners, TRUE); + trace->is_static_listeners = NULL; } bt_object_pool_finalize(&trace->packet_header_field_pool); @@ -96,28 +97,35 @@ void destroy_trace(struct bt_object *obj) if (trace->environment) { BT_LOGD_STR("Destroying environment attributes."); bt_attributes_destroy(trace->environment); + trace->environment = NULL; } if (trace->name.str) { g_string_free(trace->name.str, TRUE); + trace->name.str = NULL; + trace->name.value = NULL; } if (trace->streams) { BT_LOGD_STR("Destroying streams."); g_ptr_array_free(trace->streams, TRUE); + trace->streams = NULL; } if (trace->stream_classes) { BT_LOGD_STR("Destroying stream classes."); g_ptr_array_free(trace->stream_classes, TRUE); + trace->stream_classes = NULL; } if (trace->stream_classes_stream_count) { g_hash_table_destroy(trace->stream_classes_stream_count); + trace->stream_classes_stream_count = NULL; } BT_LOGD_STR("Putting packet header field classe."); bt_object_put_ref(trace->packet_header_fc); + trace->packet_header_fc = NULL; g_free(trace); } diff --git a/lib/values.c b/lib/values.c index d14bec84..ffe289c2 100644 --- a/lib/values.c +++ b/lib/values.c @@ -130,6 +130,7 @@ static void bt_value_string_destroy(struct bt_value *object) { g_string_free(BT_VALUE_TO_STRING(object)->gstr, TRUE); + BT_VALUE_TO_STRING(object)->gstr = NULL; } static @@ -140,6 +141,7 @@ void bt_value_array_destroy(struct bt_value *object) * of putting each contained object. */ g_ptr_array_free(BT_VALUE_TO_ARRAY(object)->garray, TRUE); + BT_VALUE_TO_ARRAY(object)->garray = NULL; } static @@ -151,6 +153,7 @@ void bt_value_map_destroy(struct bt_value *object) * be destroyed anyway. */ g_hash_table_destroy(BT_VALUE_TO_MAP(object)->ght); + BT_VALUE_TO_MAP(object)->ght = NULL; } static -- 2.34.1