summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLennart Poettering <lennart@poettering.net>2012-03-09 18:15:18 +0100
committerLennart Poettering <lennart@poettering.net>2012-03-09 18:15:18 +0100
commit7b27f1855d0a665e96d422b42f0521c594bbecd4 (patch)
treeb2e5287ebc8ac51353713c19df2814f92b130ac4
parent655457ce666e2ed6da3c8e21210bb2aa0901676d (diff)
write system info stream
-rw-r--r--format.h60
-rw-r--r--minidump.c105
2 files changed, 159 insertions, 6 deletions
diff --git a/format.h b/format.h
index 52e4d70..efae177 100644
--- a/format.h
+++ b/format.h
@@ -52,11 +52,11 @@ enum {
MINIDUMP_UNUSED_STREAM = 0,
MINIDUMP_RESERVED_STREAM_0 = 1,
MINIDUMP_RESERVED_STREAM_1 = 2,
- MINIDUMP_THREAD_LIST_STREAM = 3,
- MINIDUMP_MODULE_LIST_STREAM = 4,
- MINIDUMP_MEMORY_LIST_STREAM = 5,
- MINIDUMP_EXCEPTION_STREAM = 6,
- MINIDUMP_SYSTEM_INFO_STREAM = 7,
+ MINIDUMP_THREAD_LIST_STREAM = 3, /* TODO XXXX */
+ MINIDUMP_MODULE_LIST_STREAM = 4, /* TODO XXXX */
+ MINIDUMP_MEMORY_LIST_STREAM = 5, /* TODO XXXX */
+ MINIDUMP_EXCEPTION_STREAM = 6, /* TODO XXXX */
+ MINIDUMP_SYSTEM_INFO_STREAM = 7, /* done */
MINIDUMP_THREAD_EX_LIST_STREAM = 8,
MINIDUMP_MEMORY_64_LIST_STREAM = 9,
MINIDUMP_COMMENT_STREAM_A = 10,
@@ -83,7 +83,7 @@ enum {
MINIDUMP_LINUX_ENVIRON = 0x47670007, /* done */
MINIDUMP_LINUX_AUXV = 0x47670008, /* done */
MINIDUMP_LINUX_MAPS = 0x47670009, /* done */
- MINIDUMP_LINUX_DSO_DEBUG = 0x4767000A,
+ MINIDUMP_LINUX_DSO_DEBUG = 0x4767000A, /* TODO XXXX */
/* libminidump extensions */
MINIDUMP_LINUX_OS_RELEASE = 0x4c500001,
@@ -93,5 +93,53 @@ enum {
MINIDUMP_LINUX_CORE_EHDR = 0x4c500005 /* done */
};
+struct minidump_system_info {
+ uint16_t processor_architecture;
+ uint16_t processor_level;
+ uint16_t processor_revision;
+ uint8_t number_of_processors;
+ uint8_t product_type;
+ uint32_t major_version;
+ uint32_t minor_version;
+ uint32_t build_number;
+ uint32_t platform_id;
+ uint32_t csd_version_rva;
+ uint16_t suite_mask;
+ uint16_t reserved2;
+ union {
+ struct {
+ uint32_t vendor_id[3];
+ uint32_t version_information;
+ uint32_t feature_information;
+ uint32_t amd_extended_cpu_features;
+ } x86_cpu_info;
+ struct {
+ uint64_t processor_features[2];
+ } other_cpu_info;
+ } cpu;
+};
+
+enum {
+ MINIDUMP_PROCESSOR_ARCHITECTURE_INTEL = 0,
+ MINIDUMP_PROCESSOR_ARCHITECTURE_MIPS = 1,
+ MINIDUMP_PROCESSOR_ARCHITECTURE_PPC = 3,
+ MINIDUMP_PROCESSOR_ARCHITECTURE_ARM = 5,
+ MINIDUMP_PROCESSOR_ARCHITECTURE_IA64 = 6,
+ MINIDUMP_PROCESSOR_ARCHITECTURE_AMD64 = 9,
+
+ /* Breakpad extension */
+ MINIDUMP_PROCESSOR_ARCHITECTURE_SPARC = 0x8001
+};
+
+enum {
+ MINIDUMP_PLATFORM_WIN32S = 0,
+ MINIDUMP_PLATFORM_WIN32_WINDOWS = 1,
+ MINIDUMP_PLATFORM_WIN32_NT = 2,
+ MINIDUMP_PLATFORM_WIN32_CE = 3,
+
+ /* Breakpad extensions */
+ MINIDUMP_PLATFORM_LINUX = 0x8201
+};
+
#endif
diff --git a/minidump.c b/minidump.c
index ec43a2e..c16eda9 100644
--- a/minidump.c
+++ b/minidump.c
@@ -15,6 +15,8 @@
#include <sys/uio.h>
#include <unistd.h>
#include <time.h>
+#include <stdarg.h>
+#include <sys/utsname.h>
#include "coredump.h"
#include "format.h"
@@ -706,6 +708,107 @@ static int write_proc_readlink_stream(struct context *c, uint32_t stream_type, c
return write_blob_stream(c, stream_type, path, r);
}
+static int append_concat_string(struct context *c, size_t *offset, size_t *size, ...) {
+ va_list ap;
+ bool first = true;
+ size_t sum = 0, o = 0;
+ int r;
+
+ assert(c);
+
+ va_start(ap, size);
+
+ for (;;) {
+ size_t l;
+ const char *p;
+
+ p = va_arg(ap, const char *);
+ if (!p)
+ break;
+
+ l = strlen(p);
+ r = append_bytes(c, p, l, first ? &o : NULL);
+ if (r < 0)
+ goto finish;
+
+ sum += l;
+ first = false;
+ }
+
+ r = append_bytes(c, "", 1, first ? &o : NULL);
+ if (r < 0)
+ goto finish;
+
+ sum += 1;
+
+ if (offset)
+ *offset = o;
+
+ if (size)
+ *size = sum;
+
+finish:
+ va_end(ap);
+
+ return r;
+}
+
+static int write_system_info_stream(struct context *c) {
+ struct minidump_system_info i;
+ long l;
+ struct utsname u;
+ int r;
+ size_t offset;
+
+ assert(c);
+
+ memset(&i, 0, sizeof(i));
+
+#if defined(__i386)
+ i.processor_architecture = MINIDUMP_PROCESSOR_ARCHITECTURE_INTEL;
+#elif defined(__mips__)
+ i.processor_architecture = MINIDUMP_PROCESSOR_ARCHITECTURE_MIPS;
+#elif defined(__ppc__)
+ i.processor_architecture = MINIDUMP_PROCESSOR_ARCHITECTURE_PPC;
+#elif defined (__arm__)
+ i.processor_architecture = MINIDUMP_PROCESSOR_ARCHITECTURE_ARM;
+#elif defined (__ia64__)
+ i.processor_architecture = MINIDUMP_PROCESSOR_ARCHITECTURE_IA64;
+#elif defined (__x86_64)
+ i.processor_architecture = MINIDUMP_PROCESSOR_ARCHITECTURE_AMD64;
+#elif defined (__sparc__)
+ i.processor_architecture = MINIDUMP_PROCESSOR_ARCHITECTURE_SPARC;
+#else
+#error "I need porting"
+#endif
+ /* FIXME: i.processor_level = "cpu family"; */
+ /* FIXME: i.processor_revision = "model" << 8 | "stepping"; */
+ /* FIXME: i.cpu.x86_cpu_info.vendor_id = "vendor_id"; */
+
+ i.platform_id = MINIDUMP_PLATFORM_LINUX;
+
+ l = sysconf(_SC_NPROCESSORS_ONLN);
+ i.number_of_processors = l <= 0 ? 1 : l;
+
+ r = uname(&u);
+ if (r < 0)
+ return -errno;
+
+ r = append_concat_string(c,
+ &offset, NULL,
+ u.sysname, " ",
+ u.release, " ",
+ u.version, " ",
+ u.machine, " ",
+ NULL);
+ if (r < 0)
+ return r;
+
+ i.csd_version_rva = htole32((uint32_t) offset);
+
+ return write_blob_stream(c, MINIDUMP_SYSTEM_INFO_STREAM, &i, sizeof(i));
+}
+
static int write_directory(struct context *c) {
size_t offset;
struct minidump_header *h;
@@ -753,6 +856,8 @@ static int write_dump(struct context *c) {
/* write rpm info */
/* write debug */
+ write_system_info_stream(c);
+
/* This is a Ubuntuism, but Google is doing this, hence let's stay compatible here */
write_file_stream(c, MINIDUMP_LINUX_LSB_RELEASE, "/etc/lsb-release");
/* It's much nicer to write /etc/os-release instead, which is more widely supported */