1
1
mirror of https://github.com/systemd/systemd-stable.git synced 2025-01-27 14:03:43 +03:00

coredumpctl: parse and print package metadata

This commit is contained in:
Luca Boccassi 2021-04-06 18:02:41 +01:00
parent c546154a44
commit d1b5a0c691

View File

@ -545,7 +545,8 @@ static int print_info(FILE *file, sd_journal *j, bool need_space) {
*boot_id = NULL, *machine_id = NULL, *hostname = NULL,
*slice = NULL, *cgroup = NULL, *owner_uid = NULL,
*message = NULL, *timestamp = NULL, *filename = NULL,
*truncated = NULL, *coredump = NULL;
*truncated = NULL, *coredump = NULL,
*pkgmeta_name = NULL, *pkgmeta_version = NULL, *pkgmeta_json = NULL;
const void *d;
size_t l;
bool normal_coredump;
@ -574,6 +575,9 @@ static int print_info(FILE *file, sd_journal *j, bool need_space) {
RETRIEVE(d, l, "COREDUMP_FILENAME", filename);
RETRIEVE(d, l, "COREDUMP_TRUNCATED", truncated);
RETRIEVE(d, l, "COREDUMP", coredump);
RETRIEVE(d, l, "COREDUMP_PKGMETA_PACKAGE", pkgmeta_name);
RETRIEVE(d, l, "COREDUMP_PKGMETA_PACKAGEVERSION", pkgmeta_version);
RETRIEVE(d, l, "COREDUMP_PKGMETA_JSON", pkgmeta_json);
RETRIEVE(d, l, "_BOOT_ID", boot_id);
RETRIEVE(d, l, "_MACHINE_ID", machine_id);
RETRIEVE(d, l, "MESSAGE", message);
@ -716,6 +720,68 @@ static int print_info(FILE *file, sd_journal *j, bool need_space) {
else
fprintf(file, " Storage: none\n");
if (pkgmeta_name && pkgmeta_version)
fprintf(file, " Package: %s/%s\n", pkgmeta_name, pkgmeta_version);
/* Print out the build-id of the 'main' ELF module, by matching the JSON key
* with the 'exe' field. */
if (exe && pkgmeta_json) {
_cleanup_(json_variant_unrefp) JsonVariant *v = NULL;
r = json_parse(pkgmeta_json, 0, &v, NULL, NULL);
if (r < 0) {
log_warning_errno(r, "json_parse on %s failed, ignoring: %m", pkgmeta_json);
} else {
const char *module_name;
JsonVariant *module_json;
/* Cannot nest two JSON_VARIANT_OBJECT_FOREACH as they define the same
* iterator variable '_state' */
for (struct json_variant_foreach_state _state2 = { (v), 0 }; \
json_variant_is_object(_state2.variant) && \
_state2.idx < json_variant_elements(_state2.variant) && \
({ module_name = json_variant_string(json_variant_by_index(_state2.variant, _state2.idx)); \
module_json = json_variant_by_index(_state2.variant, _state2.idx + 1); \
true; }); \
_state2.idx += 2) {
_cleanup_free_ char *module_basename = NULL, *exe_basename = NULL;
const char *key;
JsonVariant *w;
/* The module name, most likely parsed from the ELF core file,
* sometimes contains the full path and sometimes does not. */
r = path_extract_filename(module_name, &module_basename);
if (r < 0) {
log_warning_errno(r, "Failed to parse module basename: %m");
break;
}
r = path_extract_filename(exe, &exe_basename);
if (r < 0) {
log_warning_errno(r, "Failed to parse executable basename: %m");
break;
}
/* We only print the build-id for the 'main' ELF module */
if (!streq(module_basename, exe_basename))
continue;
JSON_VARIANT_OBJECT_FOREACH(key, w, module_json) {
if (!json_variant_is_string(w))
continue;
if (!streq(key, "buildid"))
continue;
fprintf(file, " build-id: %s\n", json_variant_string(w));
break;
}
break;
}
}
}
if (message) {
_cleanup_free_ char *m = NULL;