coredumpctl: parse and print package metadata
This commit is contained in:
@@ -545,7 +545,8 @@ static int print_info(FILE *file, sd_journal *j, bool need_space) {
|
|||||||
*boot_id = NULL, *machine_id = NULL, *hostname = NULL,
|
*boot_id = NULL, *machine_id = NULL, *hostname = NULL,
|
||||||
*slice = NULL, *cgroup = NULL, *owner_uid = NULL,
|
*slice = NULL, *cgroup = NULL, *owner_uid = NULL,
|
||||||
*message = NULL, *timestamp = NULL, *filename = 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;
|
const void *d;
|
||||||
size_t l;
|
size_t l;
|
||||||
bool normal_coredump;
|
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_FILENAME", filename);
|
||||||
RETRIEVE(d, l, "COREDUMP_TRUNCATED", truncated);
|
RETRIEVE(d, l, "COREDUMP_TRUNCATED", truncated);
|
||||||
RETRIEVE(d, l, "COREDUMP", coredump);
|
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, "_BOOT_ID", boot_id);
|
||||||
RETRIEVE(d, l, "_MACHINE_ID", machine_id);
|
RETRIEVE(d, l, "_MACHINE_ID", machine_id);
|
||||||
RETRIEVE(d, l, "MESSAGE", message);
|
RETRIEVE(d, l, "MESSAGE", message);
|
||||||
@@ -716,6 +720,68 @@ static int print_info(FILE *file, sd_journal *j, bool need_space) {
|
|||||||
else
|
else
|
||||||
fprintf(file, " Storage: none\n");
|
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) {
|
if (message) {
|
||||||
_cleanup_free_ char *m = NULL;
|
_cleanup_free_ char *m = NULL;
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user