]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
coredump: parse build-id out of core file
authorLuca Boccassi <luca.boccassi@microsoft.com>
Thu, 18 Mar 2021 11:19:09 +0000 (11:19 +0000)
committerLuca Boccassi <luca.boccassi@microsoft.com>
Tue, 6 Apr 2021 21:52:48 +0000 (22:52 +0100)
Parse the build-id of each ELF object contained in the core file
using the elfutils' libdwfl interface.
Add it to the journal.

src/coredump/coredump.c
src/coredump/stacktrace.c
src/coredump/stacktrace.h

index 2fb2404500e88c026241b69ad03c71178ac831e8..b862a6d3d3d9554300bc6c9e50ed14c712dfbb07 100644 (file)
@@ -757,7 +757,7 @@ static int submit_coredump(
                           "than %"PRIu64" (the configured maximum)",
                           coredump_size, arg_process_size_max);
         } else
-                coredump_make_stack_trace(coredump_fd, context->meta[META_EXE], &stacktrace);
+                coredump_parse_core(coredump_fd, context->meta[META_EXE], &stacktrace);
 #endif
 
 log:
index a29ab1211c2feae5a5f4e6f59301639a0abf8df6..cf4e9baa13bdf8924350328fa43b85e9fb12b73d 100644 (file)
@@ -1,6 +1,7 @@
 /* SPDX-License-Identifier: LGPL-2.1-or-later */
 
 #include <dwarf.h>
+#include <elfutils/libdwelf.h>
 #include <elfutils/libdwfl.h>
 #include <sys/types.h>
 #include <unistd.h>
@@ -9,6 +10,7 @@
 #include "fileio.h"
 #include "fd-util.h"
 #include "format-util.h"
+#include "hexdecoct.h"
 #include "macro.h"
 #include "stacktrace.h"
 #include "string-util.h"
@@ -111,10 +113,49 @@ static int thread_callback(Dwfl_Thread *thread, void *userdata) {
         return DWARF_CB_OK;
 }
 
-static int make_stack_trace(int fd, const char *executable, char **ret) {
+static int module_callback (Dwfl_Module *mod, void **userdata, const char *name, Dwarf_Addr start, void *arg)
+{
+        _cleanup_free_ char *id_hex = NULL;
+        struct stack_context *c = arg;
+        GElf_Addr id_vaddr;
+        const unsigned char *id;
+        int id_len;
+
+        assert(mod);
+        assert(c);
+
+        if (!name)
+                name = "(unnamed)"; /* For logging purposes */
+
+        fprintf(c->f, "Found module %s", name);
+
+        /* We are iterating on each "module", which is what dwfl calls ELF objects contained in the
+         * core file, and extracting the build-id first and then the package metadata.
+         * We proceed in a best-effort fashion - not all ELF objects might contain both or either.
+         * The build-id is easy, as libdwfl parses it during the dwfl_core_file_report() call and
+         * stores it separately in an internal library struct. */
+        id_len = dwfl_module_build_id(mod, &id, &id_vaddr);
+        if (id_len == 0) {
+                fprintf(c->f, " without build-id\n");
+                return DWARF_CB_OK;
+        }
+
+        id_hex = hexmem(id, id_len);
+        if (!id_hex) {
+                fprintf(c->f, "\n");
+                return DWARF_CB_ABORT;
+        }
+
+        fprintf(c->f, " with build-id: %s\n", id_hex);
+
+        return DWARF_CB_OK;
+}
+
+static int parse_core(int fd, const char *executable, char **ret) {
 
         static const Dwfl_Callbacks callbacks = {
                 .find_elf = dwfl_build_id_find_elf,
+                .section_address = dwfl_offline_section_address,
                 .find_debuginfo = dwfl_standard_find_debuginfo,
         };
 
@@ -157,6 +198,11 @@ static int make_stack_trace(int fd, const char *executable, char **ret) {
                 goto finish;
         }
 
+        if (dwfl_getmodules(c.dwfl, &module_callback, &c, 0) < 0) {
+                r = -EINVAL;
+                goto finish;
+        }
+
         if (dwfl_core_file_attach(c.dwfl, c.elf) < 0) {
                 r = -EINVAL;
                 goto finish;
@@ -187,10 +233,10 @@ finish:
         return r;
 }
 
-void coredump_make_stack_trace(int fd, const char *executable, char **ret) {
+void coredump_parse_core(int fd, const char *executable, char **ret) {
         int r;
 
-        r = make_stack_trace(fd, executable, ret);
+        r = parse_core(fd, executable, ret);
         if (r == -EINVAL)
                 log_warning("Failed to generate stack trace: %s", dwfl_errmsg(dwfl_errno()));
         else if (r < 0)
index b93574840424e5161366382d4da2a6a90c6f64ad..7f25bf1a6b127891cadb7ec0dab6a347cb62fa5b 100644 (file)
@@ -1,4 +1,4 @@
 /* SPDX-License-Identifier: LGPL-2.1-or-later */
 #pragma once
 
-void coredump_make_stack_trace(int fd, const char *executable, char **ret);
+void coredump_parse_core(int fd, const char *executable, char **ret);