1
0
mirror of https://github.com/systemd/systemd synced 2024-07-08 20:15:55 +00:00

coredump: shorten output about package metadata to one line

We would print the whole thing in extenso. Users generally don't care,
and would likely prefer to just get the compact identifier of the package
that they can use in a bug report or package manager commands.

Before:
systemd-coredump[40645]: [🡕] Process 1975 (gnome-shell) of user 1000 dumped core.

                         Module /usr/bin/gnome-shell (deleted) with build-id aafdb7d69a7efca937e490080ad9348541fc57d8
                         Metadata for module /usr/bin/gnome-shell (deleted) owned by FDO found: {
                                 "type" : "rpm",
                                 "name" : "gnome-shell",
                                 "version" : "43~rc-3.fc37",
                                 "architecture" : "x86_64",
                                 "osCpe" : "cpe:/o:fedoraproject:fedora:37"
                         }

                         Module /usr/lib64/gnome-shell/libgvc.so (deleted) with build-id 56cbb9862e1ee84ca1549b94f2b4cda03537613e
                         Metadata for module /usr/lib64/gnome-shell/libgvc.so (deleted) owned by FDO found: {
                                 "type" : "rpm",
                                 "name" : "gnome-shell",
                                 "version" : "43~rc-2.fc37",
                                 "architecture" : "x86_64",
                                 "osCpe" : "cpe:/o:fedoraproject:fedora:37"
                         }

                         Module /usr/lib64/libLLVM-14.so (deleted) with build-id ffa7e43f48eb4c189304c0241b1862710de4c3a4
                         Metadata for module /usr/lib64/libLLVM-14.so (deleted) owned by FDO found: {
                                 "type" : "rpm",
                                 "name" : "gnome-shell",
                                 "version" : "43~rc-2.fc37",
                                 "architecture" : "x86_64",
                                 "osCpe" : "cpe:/o:fedoraproject:fedora:37"
                         }

After:
systemd-coredump[235218]: [🡕] Process 235216 (bash) of user 1000 dumped core.

                          Module libtinfo.so.6 from rpm ncurses-6.3-3.20220501.fc37.x86_64, build-id=71a04d23fd572525eb6efc47026c379725e06d96
                          Module bash from rpm bash-5.1.16-3.fc37.x86_64, build-id=6c936aff95a2ccda04a3fb685a81a84a0a8d10da
                          Stack trace of thread 235216:
                          #0  0x00007fa409ec8d8b kill (libc.so.6 + 0x38d8b)
                          #1  0x0000560d35e366b1 kill_builtin (bash + 0xad6b1)
                          #2  0x0000560d35dd7227 execute_builtin.lto_priv.0 (bash + 0x4e227)
                          #3  0x0000560d35dd0459 execute_simple_command (bash + 0x47459)
                          #4  0x0000560d35dd1de0 execute_command_internal (bash + 0x48de0)
                          #5  0x0000560d35e307aa parse_and_execute (bash + 0xa77aa)
                          #6  0x0000560d35e91b08 run_one_command.isra.0 (bash + 0x108b08)
                          #7  0x0000560d35dba07c main (bash + 0x3107c)
                          #8  0x00007fa409eb3510 __libc_start_call_main (libc.so.6 + 0x23510)
                          #9  0x00007fa409eb35c9 __libc_start_main@@GLIBC_2.34 (libc.so.6 + 0x235c9)
                          #10 0x0000560d35dbad85 _start (bash + 0x31d85)
This commit is contained in:
Zbigniew Jędrzejewski-Szmek 2022-09-18 19:26:29 +02:00
parent 87707784c7
commit 1a0281a3eb
2 changed files with 66 additions and 23 deletions

3
TODO
View File

@ -2018,8 +2018,7 @@ Features:
* coredump:
- save coredump in Windows/Mozilla minidump format
- when truncating coredumps, also log the full size that the process had, and make a metadata field so we can report truncated coredumps
- when using package notes, compact output to one-line-per-module:
libfoo.so, build-id DEADF12340, foo-libs-33.4-1.fc12
- add examples for other distros in ELF_PACKAGE_METADATA
* support crash reporting operation modes (https://live.gnome.org/GnomeOS/Design/Whiteboards/ProblemReporting)

View File

@ -266,6 +266,60 @@ static int thread_callback(Dwfl_Thread *thread, void *userdata) {
return DWARF_CB_OK;
}
static char* build_package_reference(
const char *type,
const char *name,
const char *version,
const char *arch) {
/* Construct an identifier for a specific version of the package. The syntax is most suitable for
* rpm: the resulting string can be used directly in queries and rpm/dnf/yum commands. For dpkg and
* other systems, it might not be usable directly, but users should still be able to figure out the
* meaning.
*/
return strjoin(type ?: "package",
" ",
name,
version ? "-" : "",
strempty(version),
/* arch is meaningful even without version, so always print it */
arch ? "." : "",
strempty(arch));
}
static void report_module_metadata(StackContext *c, const char *name, JsonVariant *metadata) {
assert(c);
assert(name);
assert(metadata);
if (!c->f)
return;
const char
*build_id = json_variant_string(json_variant_by_key(metadata, "buildId")),
*type = json_variant_string(json_variant_by_key(metadata, "type")),
*package = json_variant_string(json_variant_by_key(metadata, "name")),
*version = json_variant_string(json_variant_by_key(metadata, "version")),
*arch = json_variant_string(json_variant_by_key(metadata, "architecture"));
fprintf(c->f, "Module %s", name);
if (package) {
/* Version/architecture is only meaningful with a package name.
* Skip the detailed fields if package is unknown. */
_cleanup_free_ char *id = build_package_reference(type, package, version, arch);
fprintf(c->f, " from %s", strnull(id));
}
if (build_id)
fprintf(c->f, ", build-id=%s", build_id);
fputs("\n", c->f);
}
static int parse_package_metadata(const char *name, JsonVariant *id_json, Elf *elf, bool *ret_interpreter_found, StackContext *c) {
bool interpreter_found = false;
size_t n_program_headers;
@ -315,7 +369,6 @@ static int parse_package_metadata(const char *name, JsonVariant *id_json, Elf *e
(note_offset = sym_gelf_getnote(data, note_offset, &note_header, &name_offset, &desc_offset)) > 0;) {
_cleanup_(json_variant_unrefp) JsonVariant *v = NULL, *w = NULL;
const char *note_name = (const char *)data->d_buf + name_offset;
const char *payload = (const char *)data->d_buf + desc_offset;
if (note_header.n_namesz == 0 || note_header.n_descsz == 0)
@ -343,23 +396,18 @@ static int parse_package_metadata(const char *name, JsonVariant *id_json, Elf *e
if (r < 0)
return log_error_errno(r, "json_parse on %s failed: %m", payload);
/* First pretty-print to the buffer, so that the metadata goes as
* plaintext in the journal. */
if (c->f) {
fprintf(c->f, "Metadata for module %s owned by %s found: ",
name, note_name);
json_variant_dump(v, JSON_FORMAT_NEWLINE|JSON_FORMAT_PRETTY, c->f, NULL);
fputc('\n', c->f);
}
/* Secondly, if we have a build-id, merge it in the same JSON object
* so that it appears all nicely together in the logs/metadata. */
/* If we have a build-id, merge it in the same JSON object so that it appears all
* nicely together in the logs/metadata. */
if (id_json) {
r = json_variant_merge(&v, id_json);
if (r < 0)
return log_error_errno(r, "json_variant_merge of package meta with buildid failed: %m");
return log_error_errno(r, "json_variant_merge of package meta with buildId failed: %m");
}
/* Pretty-print to the buffer, so that the metadata goes as plaintext in the
* journal. */
report_module_metadata(c, name, v);
/* Then we build a new object using the module name as the key, and merge it
* with the previous parses, so that in the end it all fits together in a single
* JSON blob. */
@ -369,7 +417,7 @@ static int parse_package_metadata(const char *name, JsonVariant *id_json, Elf *e
r = json_variant_merge(c->package_metadata, w);
if (r < 0)
return log_error_errno(r, "json_variant_merge of package meta with buildid failed: %m");
return log_error_errno(r, "json_variant_merge of package meta with buildId failed: %m");
/* Finally stash the name, so we avoid double visits. */
r = set_put_strdup(c->modules, name);
@ -418,13 +466,7 @@ static int parse_buildid(Dwfl_Module *mod, Elf *elf, const char *name, StackCont
* will then be added as metadata to the journal message with the stack trace. */
r = json_build(&id_json, JSON_BUILD_OBJECT(JSON_BUILD_PAIR("buildId", JSON_BUILD_HEX(id, id_len))));
if (r < 0)
return log_error_errno(r, "json_build on build-id failed: %m");
if (c->f) {
JsonVariant *build_id = json_variant_by_key(id_json, "buildId");
assert(build_id);
fprintf(c->f, "Module %s with build-id %s\n", name, json_variant_string(build_id));
}
return log_error_errno(r, "json_build on buildId failed: %m");
}
if (ret_id_json)
@ -478,6 +520,8 @@ static int module_callback(Dwfl_Module *mod, void **userdata, const char *name,
if (r < 0) {
log_warning("Could not parse number of program headers from core file: %s",
sym_elf_errmsg(-1)); /* -1 retrieves the most recent error */
report_module_metadata(c, name, id_json);
return DWARF_CB_OK;
}