[minicoredumper] [PATCH 04/14] minicoredumper: dump NT_GNU_BUILD_ID notes

Mateusz Moscicki m.moscicki2 at partner.samsung.com
Tue May 21 14:52:40 CEST 2019


From: Mateusz Moscicki <mmoscicki2 at partner.samsung.com>

Allow dumping of NT_GNU_BUILD_ID notes from memory mapped ELF files.
This is disabled in default configuration to keep the default
behaviour unchanged.

Change-Id: I1d2bff4bd75a485b603cac50c62acf49199a31b2
---
 etc/minicoredumper/generic.recept.json          |  1 +
 src/minicoredumper/corestripper.c               | 66 +++++++++++++++++++++++++
 src/minicoredumper/minicoredumper.recept.json.5 |  3 ++
 src/minicoredumper/prog_config.c                |  7 +++
 src/minicoredumper/prog_config.h                |  1 +
 5 files changed, 78 insertions(+)

diff --git a/etc/minicoredumper/generic.recept.json b/etc/minicoredumper/generic.recept.json
index e1c953e..15406fb 100644
--- a/etc/minicoredumper/generic.recept.json
+++ b/etc/minicoredumper/generic.recept.json
@@ -18,6 +18,7 @@
     "dump_pthread_list": true,
     "dump_robust_mutex_list": true,
     "dump_scope": 1024,
+    "dump_build_id": false,
     "live_dumper": true,
     "write_proc_info": false,
     "write_debug_log": false,
diff --git a/src/minicoredumper/corestripper.c b/src/minicoredumper/corestripper.c
index 8ebcb4b..116b875 100644
--- a/src/minicoredumper/corestripper.c
+++ b/src/minicoredumper/corestripper.c
@@ -2100,6 +2100,64 @@ static int map_is_interesting(struct dump_info *di, const char *name,
 }
 
 /*
+ * Find end of notes
+ */
+bool get_notes_end_offset(int fd, size_t start, size_t *off_to_note_end) {
+	uint8_t *buff = (uint8_t *)malloc(sizeof(ElfW(Ehdr)));
+	uint8_t *header_buff = NULL;
+	bool result = true;
+
+	if (!buff) {
+		info("allocation of %d bytes error:  %s", sizeof(ElfW(Ehdr)), strerror(errno));
+		result = false;
+		goto out;
+	}
+
+	size_t tmp_ret = pread64(fd, buff, sizeof(ElfW(Ehdr)), start);
+	if (tmp_ret != sizeof(ElfW(Ehdr))) {
+		info("pread64 (len: %d addr: 0x%lx) error: %s", sizeof(ElfW(Ehdr)), start, strerror(errno));
+		result = false;
+		goto out;
+	}
+
+	if (memcmp(buff, "\x7f""ELF", 4) == 0) {
+		uint16_t phdr_item_size;
+		uint16_t phdr_item_count;
+
+		ElfW(Ehdr) *ehdr = (ElfW(Ehdr) *)buff;
+		phdr_item_size = ehdr->e_phentsize;
+		phdr_item_count = ehdr->e_phnum;
+
+		header_buff = (uint8_t *)malloc((size_t)(phdr_item_size*phdr_item_count));
+
+		tmp_ret = pread64(fd, header_buff, phdr_item_size*phdr_item_count, start+ehdr->e_phoff);
+		if (tmp_ret != phdr_item_size*phdr_item_count) {
+			info("pread64 (len: %d addr: 0x%lx) error: %s", phdr_item_size*phdr_item_count, start+ehdr->e_phoff, strerror(errno));
+			result = false;
+			goto out;
+		}
+
+		for (int i = 0; i < phdr_item_count; i++) {
+			ElfW(Phdr) *phdr = (ElfW(Phdr) *)(header_buff + i*phdr_item_size);
+			if (phdr->p_type == PT_NOTE) {
+				*off_to_note_end = phdr->p_offset + phdr->p_memsz;
+				goto out;
+			}
+		}
+		result = false;
+	} else {
+		*off_to_note_end = 0;
+		result = false;
+	}
+
+out:
+	free(header_buff);
+	free(buff);
+
+	return result;
+}
+
+/*
  * Iterates over all maps and dumps the selected ones.
  */
 static int dump_maps(struct dump_info *di, int get_only)
@@ -2143,6 +2201,14 @@ static int dump_maps(struct dump_info *di, int get_only)
 		if (perms[0] != 'r')
 			continue;
 
+		/* dump build id */
+		if (di->cfg->prog_config.dump_build_id) {
+			size_t off_to_note_end = 0;
+			if (get_notes_end_offset(di->mem_fd, start, &off_to_note_end)) {
+					dump_vma(di, start, off_to_note_end, 0, "notes");
+			}
+		}
+
 		if (get_only) {
 			add_vma(di, start, end, end, start, 0);
 			continue;
diff --git a/src/minicoredumper/minicoredumper.recept.json.5 b/src/minicoredumper/minicoredumper.recept.json.5
index 78459b3..4bac92b 100644
--- a/src/minicoredumper/minicoredumper.recept.json.5
+++ b/src/minicoredumper/minicoredumper.recept.json.5
@@ -66,6 +66,9 @@ to identify mutex attributes and states in shared memory.
 .B dump_scope
 (integer) Only registered dumps at or below this value will be dumped.
 .TP
+.B dump_build_id
+(boolean) Dump GNU_BUILD_ID note
+.TP
 .B live_dumper
 (boolean) Whether the
 .BR minicoredumper (1)
diff --git a/src/minicoredumper/prog_config.c b/src/minicoredumper/prog_config.c
index 88721d5..0cd195b 100644
--- a/src/minicoredumper/prog_config.c
+++ b/src/minicoredumper/prog_config.c
@@ -364,6 +364,10 @@ static int read_prog_config(struct json_object *root, struct prog_config *cfg)
 			if (read_prog_compression_config(v, cfg) != 0)
 				return -1;
 
+		} else if (strcmp(n, "dump_build_id") == 0) {
+			if (get_json_boolean(v, &cfg->dump_build_id) != 0)
+				return -1;
+
 		} else if (strcmp(n, "dump_robust_mutex_list") == 0) {
 			if (get_json_boolean(v,
 					&cfg->dump_robust_mutex_list) != 0) {
@@ -687,6 +691,9 @@ static void set_config_defaults(struct prog_config *cfg)
 
 	/* for compression, pack in tarball */
 	cfg->core_in_tar = true;
+
+	/* dump NT_GNU_BUILD_ID */
+	cfg->dump_build_id = false;
 }
 
 int init_prog_config(struct config *cfg, const char *cfg_file)
diff --git a/src/minicoredumper/prog_config.h b/src/minicoredumper/prog_config.h
index fcd11b8..5d77f2d 100644
--- a/src/minicoredumper/prog_config.h
+++ b/src/minicoredumper/prog_config.h
@@ -45,6 +45,7 @@ struct prog_config {
 	char *core_compressor_ext;
 	bool core_in_tar;
 	bool core_compressed;
+	bool dump_build_id;
 	bool dump_fat_core;
 	bool dump_auxv_so_list;
 	bool dump_pthread_list;
-- 
2.7.4




More information about the minicoredumper mailing list