summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLennart Poettering <lennart@poettering.net>2012-04-18 02:18:50 +0200
committerLennart Poettering <lennart@poettering.net>2012-04-18 02:18:50 +0200
commitb156c88dee037db6bd4174e988fea23a31986a95 (patch)
tree10da63c2a226d3fdadf4e543dac49bf2b0aefede
parent8979b1a576ab0ec9b20086a55acd3400ad3b3377 (diff)
minicore: store system/process meta data in notes section
-rw-r--r--coredump.c6
-rw-r--r--minidump.c93
2 files changed, 92 insertions, 7 deletions
diff --git a/coredump.c b/coredump.c
index e8a304d..0a08898 100644
--- a/coredump.c
+++ b/coredump.c
@@ -183,14 +183,14 @@ int coredump_next_note(int fd, off_t *offset, off_t *length, ElfW(Nhdr) *n, off_
return -EIO;
j = sizeof(*n) +
- roundup(n->n_namesz, sizeof(long)) +
- roundup(n->n_descsz, sizeof(long));
+ roundup(n->n_namesz, sizeof(int)) +
+ roundup(n->n_descsz, sizeof(int));
if (j > *length)
return -EIO;
*name = *offset + sizeof(*n);
- *descriptor = *offset + sizeof(*n) + roundup(n->n_namesz, sizeof(long));
+ *descriptor = *offset + sizeof(*n) + roundup(n->n_namesz, sizeof(int));
*offset += j;
*length -= j;
diff --git a/minidump.c b/minidump.c
index 582a2f1..9705b50 100644
--- a/minidump.c
+++ b/minidump.c
@@ -670,6 +670,8 @@ static int coredump_read_threads(struct context *c) {
name[l] = 0;
+ fprintf(stderr, "Found note %s, type %u\n", name, note.n_type);
+
if (strcmp(name, "CORE") == 0 &&
note.n_type == NT_PRSTATUS) {
@@ -1120,12 +1122,31 @@ static int append_bytes(struct context *c, const void *data, size_t bytes, size_
int r;
assert(c);
+ assert(data || bytes <= 0);
r = reserve_bytes(c, bytes, &p, offset);
if (r < 0)
return r;
- memcpy(p, data, bytes);
+ if (bytes > 0)
+ memcpy(p, data, bytes);
+
+ return r;
+}
+
+static int null_bytes(struct context *c, size_t bytes, size_t *offset) {
+ void *p;
+ int r;
+
+ assert(c);
+
+ r = reserve_bytes(c, bytes, &p, offset);
+ if (r < 0)
+ return r;
+
+ if (bytes > 0)
+ memset(p, 0, bytes);
+
return r;
}
@@ -1711,8 +1732,10 @@ static int minicore_write_one_note(struct context *c, const char *name, ElfW(Wor
assert(c);
assert(name);
- assert(data);
- assert(length > 0);
+ assert(data || length <= 0);
+
+ if (length <= 0)
+ return 0;
memset(&nh, 0, sizeof(nh));
nh.n_namesz = strlen(name);
@@ -1727,7 +1750,15 @@ static int minicore_write_one_note(struct context *c, const char *name, ElfW(Wor
if (r < 0)
return r;
- r = append_bytes(c, data, length, NULL);
+ r = null_bytes(c, roundup(nh.n_namesz, sizeof(int)) - nh.n_namesz, NULL);
+ if (r < 0)
+ return r;
+
+ r = append_bytes(c, data, nh.n_descsz, NULL);
+ if (r < 0)
+ return r;
+
+ r = null_bytes(c, roundup(nh.n_descsz, sizeof(int)) - nh.n_descsz, NULL);
if (r < 0)
return r;
@@ -1819,6 +1850,56 @@ static int minicore_write_notes_for_thread(struct context *c, unsigned i) {
return 0;
}
+static int minicore_write_meta_notes(struct context *c) {
+ int r;
+
+ assert(c);
+
+ /* We use the same type identifiers as the minidump logic */
+
+ r = minicore_write_one_note(c, "LENNART", MINIDUMP_LINUX_MAPS, c->proc_maps.data, c->proc_maps.size);
+ if (r < 0)
+ return r;
+
+ r = minicore_write_one_note(c, "LENNART", MINIDUMP_LINUX_PROC_STATUS, c->proc_status.data, c->proc_status.size);
+ if (r < 0)
+ return r;
+
+ r = minicore_write_one_note(c, "LENNART", MINIDUMP_LINUX_ENVIRON, c->proc_environ.data, c->proc_environ.size);
+ if (r < 0)
+ return r;
+
+ r = minicore_write_one_note(c, "LENNART", MINIDUMP_LINUX_CMD_LINE, c->proc_cmdline.data, c->proc_cmdline.size);
+ if (r < 0)
+ return r;
+
+ r = minicore_write_one_note(c, "LENNART", MINIDUMP_LINUX_COMM, c->proc_comm.data, c->proc_comm.size);
+ if (r < 0)
+ return r;
+
+ r = minicore_write_one_note(c, "LENNART", MINIDUMP_LINUX_ATTR_CURRENT, c->proc_attr_current.data, c->proc_attr_current.size);
+ if (r < 0)
+ return r;
+
+ r = minicore_write_one_note(c, "LENNART", MINIDUMP_LINUX_ENVIRON, c->proc_exe.data, c->proc_exe.size);
+ if (r < 0)
+ return r;
+
+ r = minicore_write_one_note(c, "LENNART", MINIDUMP_LINUX_CPU_INFO, c->proc_cpuinfo.data, c->proc_cpuinfo.size);
+ if (r < 0)
+ return r;
+
+ r = minicore_write_one_note(c, "LENNART", MINIDUMP_LINUX_LSB_RELEASE, c->lsb_release.data, c->lsb_release.size);
+ if (r < 0)
+ return r;
+
+ r = minicore_write_one_note(c, "LENNART", MINIDUMP_LINUX_OS_RELEASE, c->os_release.data, c->os_release.size);
+ if (r < 0)
+ return r;
+
+ return 0;
+}
+
static int minicore_write_notes(struct context *c) {
ElfW(Phdr) ph;
unsigned i;
@@ -1836,6 +1917,10 @@ static int minicore_write_notes(struct context *c) {
return r;
}
+ r = minicore_write_meta_notes(c);
+ if (r < 0)
+ return r;
+
memset(&ph, 0, sizeof(ph));
ph.p_type = PT_NOTE;
ph.p_offset = offset;