qom: add trace events for object/property lifecycle
This adds tracing around object allocation & finalization, the addition & deletion of properties, and the addition & deletion of children. Tested-by: Philippe Mathieu-Daudé <philmd@linaro.org> Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org> Reviewed-by: Marc-André Lureau <marcandre.lureau@redhat.com> Signed-off-by: Daniel P. Berrangé <berrange@redhat.com>
Daniel P. Berrangé committed
Apr 17, 2026 at 15:06 UTC
e89cff07a902f697f554624853df056042e4e20d
2 files changed
+37
-9
qom/object.c
+27
-7
@@ -594,6 +594,8 @@ static void object_property_del_all(Object *obj)
594
object_property_iter_init(&iter, obj);
595
while ((prop = object_property_iter_next(&iter)) != NULL) {
596
if (g_hash_table_add(done, prop)) {
597
+ trace_object_property_del(obj, obj->class->type->name,
598
+ prop->name, prop->opaque);
599
if (prop->release) {
600
prop->release(obj, prop->name, prop->opaque);
601
released = true;
@@ -612,10 +614,14 @@ static void object_property_del_child(Object *obj, Object *child)
614
GHashTableIter iter;
615
gpointer key, value;
616
617
+ trace_object_property_del_child(obj, obj->class->type->name,
618
+ child, child->class->type->name);
619
g_hash_table_iter_init(&iter, obj->properties);
620
while (g_hash_table_iter_next(&iter, &key, &value)) {
621
prop = value;
622
if (object_property_is_child(prop) && prop->opaque == child) {
623
+ trace_object_property_del(obj, obj->class->type->name,
624
+ prop->name, prop->opaque);
625
if (prop->release) {
626
prop->release(obj, prop->name, prop->opaque);
627
prop->release = NULL;
@@ -655,7 +661,7 @@ static void object_finalize(void *data)
661
{
662
Object *obj = data;
663
TypeImpl *ti = obj->class->type;
658
-
664
+ trace_object_finalize(obj, obj->class->type->name);
665
object_property_del_all(obj);
666
object_deinit(obj, ti);
667
@@ -705,6 +711,7 @@ static Object *object_new_with_type(Type type)
711
object_initialize_with_type(obj, size, type);
712
obj->free = obj_free;
713
714
+ trace_object_new(obj, obj->class->type->name);
715
return obj;
716
}
717
@@ -835,8 +842,9 @@ Object *object_dynamic_cast(Object *obj, const char *typename)
842
Object *object_dynamic_cast_assert(Object *obj, const char *typename,
843
const char *file, int line, const char *func)
844
{
838
- trace_object_dynamic_cast_assert(obj ? obj->class->type->name : "(null)",
839
- typename, file, line, func);
845
+ trace_object_dynamic_cast_assert(
846
+ obj, obj ? obj->class->type->name : "(null)",
847
+ typename, file, line, func);
848
849
#ifdef CONFIG_QOM_CAST_DEBUG
850
int i;
@@ -926,8 +934,9 @@ ObjectClass *object_class_dynamic_cast_assert(ObjectClass *class,
934
{
935
ObjectClass *ret;
936
929
- trace_object_class_dynamic_cast_assert(class ? class->type->name : "(null)",
930
- typename, file, line, func);
937
+ trace_object_class_dynamic_cast_assert(
938
+ class ? class->type->name : "(null)",
939
+ typename, file, line, func);
940
941
#ifdef CONFIG_QOM_CAST_DEBUG
942
int i;
@@ -1211,6 +1220,8 @@ object_property_try_add(Object *obj, const char *name, const char *type,
1220
prop->release = release;
1221
prop->opaque = opaque;
1222
1223
+ trace_object_property_add(obj, obj->class->type->name,
1224
+ prop->name, prop->opaque);
1225
g_hash_table_insert(obj->properties, prop->name, prop);
1226
return prop;
1227
}
@@ -1249,6 +1260,8 @@ object_class_property_add(ObjectClass *klass,
1260
prop->release = release;
1261
prop->opaque = opaque;
1262
1263
+ trace_object_class_property_add(klass->type->name, prop->name,
1264
+ prop->opaque);
1265
g_hash_table_insert(klass->properties, prop->name, prop);
1266
1267
return prop;
@@ -1337,6 +1350,8 @@ void object_property_del(Object *obj, const char *name)
1350
{
1351
ObjectProperty *prop = g_hash_table_lookup(obj->properties, name);
1352
1353
+ trace_object_property_del(obj, obj->class->type->name, prop->name,
1354
+ prop->opaque);
1355
if (prop->release) {
1356
prop->release(obj, name, prop->opaque);
1357
}
@@ -1625,8 +1640,11 @@ int object_property_get_enum(Object *obj, const char *name,
1640
bool object_property_parse(Object *obj, const char *name,
1641
const char *string, Error **errp)
1642
{
1628
- Visitor *v = string_input_visitor_new(string);
1629
- bool ok = object_property_set(obj, name, v, errp);
1643
+ Visitor *v;
1644
+ bool ok;
1645
+ trace_object_property_parse(obj, obj->class->type->name, name, string);
1646
+ v = string_input_visitor_new(string);
1647
+ ok = object_property_set(obj, name, v, errp);
1648
1649
visit_free(v);
1650
return ok;
@@ -1757,6 +1775,8 @@ object_property_try_add_child(Object *obj, const char *name,
1775
g_autofree char *type = NULL;
1776
ObjectProperty *op;
1777
1778
+ trace_object_property_add_child(obj, obj->class->type->name, name,
1779
+ child, child->class->type->name);
1780
assert(!child->parent);
1781
1782
type = g_strdup_printf("child<%s>", object_get_typename(child));
qom/trace-events
+10
-2
@@ -1,5 +1,13 @@
1
# See docs/devel/tracing.rst for syntax documentation.
2
3
# object.c
4
-object_dynamic_cast_assert(const char *type, const char *target, const char *file, int line, const char *func) "%s->%s (%s:%d:%s)"
5
-object_class_dynamic_cast_assert(const char *type, const char *target, const char *file, int line, const char *func) "%s->%s (%s:%d:%s)"
4
+object_dynamic_cast_assert(void *obj, const char *type, const char *target, const char *file, int line, const char *func) "obj=%p type=%s->%s (%s:%d:%s)"
5
+object_finalize(void *obj, const char *type) "obj=%p type=%s"
6
+object_new(void *obj, const char *type) "obj=%p type=%s"
7
+object_property_add(void *obj, const char *type, const char *name, void *value) "obj=%p type=%s name=%s value=%p"
8
+object_property_add_child(void *obj, const char *type, const char *name, void *child, const char *childtype) "obj=%p type=%s name=%s child=%p child-type=%s"
9
+object_property_del(void *obj, const char *type, const char *name, void *value) "obj=%p type=%s name=%s value=%p"
10
+object_property_del_child(void *obj, const char *type, void *child, const char *childtype) "obj=%p type=%s child=%p child-type=%s"
11
+object_property_parse(void *obj, const char *type, const char *name, const char *value) "obj=%p type=%s prop=%s value=%s"
12
+object_class_dynamic_cast_assert(const char *type, const char *target, const char *file, int line, const char *func) "type=%s->%s (%s:%d:%s)"
13
+object_class_property_add(const char *type, const char *name, void *value) "type=%s name=%s value=%p"