diff options
author | Lennart Poettering <lennart@poettering.net> | 2012-03-09 18:15:18 +0100 |
---|---|---|
committer | Lennart Poettering <lennart@poettering.net> | 2012-03-09 18:15:18 +0100 |
commit | 7b27f1855d0a665e96d422b42f0521c594bbecd4 (patch) | |
tree | b2e5287ebc8ac51353713c19df2814f92b130ac4 | |
parent | 655457ce666e2ed6da3c8e21210bb2aa0901676d (diff) |
write system info stream
-rw-r--r-- | format.h | 60 | ||||
-rw-r--r-- | minidump.c | 105 |
2 files changed, 159 insertions, 6 deletions
@@ -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 @@ -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 */ |