Add memory size, build id, and debug link info to statedump and dl
[deliverable/lttng-ust.git] / liblttng-ust / lttng-ust-statedump.c
index 37f067ffa4cb5d3daf4bbeb1260ca1cc0c8b5110..0c0a7bddaa5329004e2ced770a0dfc1e7a018577 100644 (file)
 
 #define _LGPL_SOURCE
 #define _GNU_SOURCE
-#include <link.h>
 
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <unistd.h>
+#include <link.h>
 #include <limits.h>
-#include <stdlib.h>
-#include <errno.h>
-#include <stdint.h>
-#include <stddef.h>
 #include <stdio.h>
+#include <stdint.h>
+#include <stdlib.h>
+#include <sys/types.h>
+#include <unistd.h>
 
-#include <usterr-signal-safe.h>
+#include <lttng/ust-elf.h>
 #include "lttng-tracer-core.h"
 #include "lttng-ust-statedump.h"
 
@@ -49,9 +46,12 @@ struct soinfo_data {
        void *owner;
        void *base_addr_ptr;
        const char *resolved_path;
+       char *dbg_file;
+       uint8_t *build_id;
+       uint64_t memsz;
+       size_t build_id_len;
        int vdso;
-       off_t size;
-       time_t mtime;
+       uint32_t crc;
 };
 
 typedef void (*tracepoint_cb)(struct lttng_session *session, void *priv);
@@ -92,9 +92,28 @@ void trace_soinfo_cb(struct lttng_session *session, void *priv)
        struct soinfo_data *so_data = (struct soinfo_data *) priv;
 
        tracepoint(lttng_ust_statedump, soinfo,
-                  session, so_data->base_addr_ptr,
-                  so_data->resolved_path, so_data->size,
-                  so_data->mtime);
+               session, so_data->base_addr_ptr,
+               so_data->resolved_path, so_data->memsz);
+}
+
+static
+void trace_build_id_cb(struct lttng_session *session, void *priv)
+{
+       struct soinfo_data *so_data = (struct soinfo_data *) priv;
+
+       tracepoint(lttng_ust_statedump, build_id,
+               session, so_data->base_addr_ptr,
+               so_data->build_id, so_data->build_id_len);
+}
+
+static
+void trace_debug_link_cb(struct lttng_session *session, void *priv)
+{
+       struct soinfo_data *so_data = (struct soinfo_data *) priv;
+
+       tracepoint(lttng_ust_statedump, debug_link,
+               session, so_data->base_addr_ptr,
+               so_data->dbg_file, so_data->crc);
 }
 
 static
@@ -109,20 +128,78 @@ void trace_end_cb(struct lttng_session *session, void *priv)
        tracepoint(lttng_ust_statedump, end, session);
 }
 
+static
+int get_elf_info(struct soinfo_data *so_data, int *has_build_id,
+               int *has_debug_link) {
+       struct lttng_ust_elf *elf;
+       int ret = 0;
+
+       elf = lttng_ust_elf_create(so_data->resolved_path);
+       if (!elf) {
+               ret = -1;
+               goto end;
+       }
+
+       ret = lttng_ust_elf_get_memsz(elf, &so_data->memsz);
+       if (ret) {
+               goto end;
+       }
+
+       ret = lttng_ust_elf_get_build_id(elf, &so_data->build_id,
+                                       &so_data->build_id_len, has_build_id);
+       if (ret) {
+               goto end;
+       }
+       ret = lttng_ust_elf_get_debug_link(elf, &so_data->dbg_file,
+                                       &so_data->crc, has_debug_link);
+       if (ret) {
+               goto end;
+       }
+
+end:
+       lttng_ust_elf_destroy(elf);
+       return ret;
+}
+
 static
 int trace_baddr(struct soinfo_data *so_data)
 {
-       struct stat sostat;
+       int ret = 0, has_build_id = 0, has_debug_link = 0;
+
+       if (!so_data->vdso) {
+               ret = get_elf_info(so_data, &has_build_id, &has_debug_link);
+               if (ret) {
+                       goto end;
+               }
+       } else {
+               so_data->memsz = 0;
+       }
 
-       if (so_data->vdso || stat(so_data->resolved_path, &sostat)) {
-               sostat.st_size = 0;
-               sostat.st_mtime = -1;
+       ret = trace_statedump_event(trace_soinfo_cb, so_data->owner, so_data);
+       if (ret) {
+               goto end;
        }
 
-       so_data->size = sostat.st_size;
-       so_data->mtime = sostat.st_mtime;
+       if (has_build_id) {
+               ret = trace_statedump_event(
+                       trace_build_id_cb, so_data->owner, so_data);
+               free(so_data->build_id);
+               if (ret) {
+                       goto end;
+               }
+       }
+
+       if (has_debug_link) {
+               ret = trace_statedump_event(
+                       trace_debug_link_cb, so_data->owner, so_data);
+               free(so_data->dbg_file);
+               if (ret) {
+                       goto end;
+               }
+       }
 
-       return trace_statedump_event(trace_soinfo_cb, so_data->owner, so_data);
+end:
+       return ret;
 }
 
 static
This page took 0.026536 seconds and 5 git commands to generate.