Use lib unload events to prune library mappings
[babeltrace.git] / lib / debug-info.c
index aa19ce4010aebf5517f1d14d19e7bd5dec7410a2..212238640ec223d9cc29470471fe6f3efd4fc1b5 100644 (file)
@@ -59,20 +59,24 @@ struct debug_info {
        GQuark q_statedump_build_id;
        GQuark q_statedump_start;
        GQuark q_dl_open;
+       GQuark q_lib_load;
+       GQuark q_lib_unload;
 };
 
 static
 int debug_info_init(struct debug_info *info)
 {
-       info->q_statedump_bin_info = g_quark_from_string(
+       info->q_statedump_bin_info = g_quark_from_static_string(
                        "lttng_ust_statedump:bin_info");
-       info->q_statedump_debug_link = g_quark_from_string(
+       info->q_statedump_debug_link = g_quark_from_static_string(
                        "lttng_ust_statedump:debug_link)");
-       info->q_statedump_build_id = g_quark_from_string(
+       info->q_statedump_build_id = g_quark_from_static_string(
                        "lttng_ust_statedump:build_id");
-       info->q_statedump_start = g_quark_from_string(
+       info->q_statedump_start = g_quark_from_static_string(
                        "lttng_ust_statedump:start");
-       info->q_dl_open = g_quark_from_string("lttng_ust_dl:dlopen");
+       info->q_dl_open = g_quark_from_static_string("lttng_ust_dl:dlopen");
+       info->q_lib_load = g_quark_from_static_string("lttng_ust_lib:load");
+       info->q_lib_unload = g_quark_from_static_string("lttng_ust_lib:unload");
 
        return bin_info_init();
 }
@@ -689,12 +693,64 @@ void handle_statedump_bin_info_event(struct debug_info *debug_info,
 }
 
 static inline
-void handle_dlopen_event(struct debug_info *debug_info,
+void handle_lib_load_event(struct debug_info *debug_info,
                struct ctf_event_definition *event_def)
 {
        handle_bin_info_event(debug_info, event_def, false);
 }
 
+static inline
+void handle_lib_unload_event(struct debug_info *debug_info,
+               struct ctf_event_definition *event_def)
+{
+       struct bt_definition *baddr_def = NULL;
+       struct bt_definition *event_fields_def = NULL;
+       struct bt_definition *sec_def = NULL;
+       struct bt_definition *vpid_def = NULL;
+       struct proc_debug_info_sources *proc_dbg_info_src;
+       uint64_t baddr;
+       int64_t vpid;
+       gpointer key_ptr = NULL;
+
+       event_fields_def = (struct bt_definition *) event_def->event_fields;
+       sec_def = (struct bt_definition *)
+                       event_def->stream->stream_event_context;
+       if (!event_fields_def || !sec_def) {
+               goto end;
+       }
+
+       baddr_def = bt_lookup_definition(event_fields_def, "_baddr");
+       if (!baddr_def) {
+               goto end;
+       }
+
+       vpid_def = bt_lookup_definition(sec_def, "_vpid");
+       if (!vpid_def) {
+               goto end;
+       }
+
+       if (baddr_def->declaration->id != BT_CTF_TYPE_ID_INTEGER) {
+               goto end;
+       }
+       if (vpid_def->declaration->id != BT_CTF_TYPE_ID_INTEGER) {
+               goto end;
+       }
+
+       baddr = bt_get_unsigned_int(baddr_def);
+       vpid = bt_get_signed_int(vpid_def);
+
+       proc_dbg_info_src = proc_debug_info_sources_ht_get_entry(
+                       debug_info->vpid_to_proc_dbg_info_src, vpid);
+       if (!proc_dbg_info_src) {
+               goto end;
+       }
+
+       key_ptr = (gpointer) &baddr;
+       assert(g_hash_table_remove(proc_dbg_info_src->baddr_to_bin_info,
+                       key_ptr));
+end:
+       return;
+}
 
 static
 void handle_statedump_start(struct debug_info *debug_info,
@@ -784,8 +840,18 @@ void debug_info_handle_event(struct debug_info *debug_info,
        if (event_class->name == debug_info->q_statedump_bin_info) {
                /* State dump */
                handle_statedump_bin_info_event(debug_info, event);
-       } else if (event_class->name == debug_info->q_dl_open) {
-               handle_dlopen_event(debug_info, event);
+       } else if (event_class->name == debug_info->q_dl_open ||
+                       event_class->name == debug_info->q_lib_load) {
+               /*
+                * dl_open and lib_load events are both checked for since
+                * only dl_open was produced as of lttng-ust 2.8.
+                *
+                * lib_load, which is produced from lttng-ust 2.9+, is a lot
+                * more reliable since it will be emitted when other functions
+                * of the dlopen family are called (e.g. dlmopen) and when
+                * library are transitively loaded.
+                */
+               handle_lib_load_event(debug_info, event);
        } else if (event_class->name == debug_info->q_statedump_start) {
                /* Start state dump */
                handle_statedump_start(debug_info, event);
@@ -795,11 +861,12 @@ void debug_info_handle_event(struct debug_info *debug_info,
        } else if (event_class->name == debug_info->q_statedump_build_id) {
                /* Build ID info */
                handle_statedump_build_id_event(debug_info, event);
+       } else if (event_class->name == debug_info-> q_lib_unload) {
+               handle_lib_unload_event(debug_info, event);
        } else {
                /* Other events: register debug infos */
                register_event_debug_infos(debug_info, event);
        }
-
 end:
        return;
 }
This page took 0.023952 seconds and 4 git commands to generate.