From a5da1e193c825796eb273fdd6ced0432b6301512 Mon Sep 17 00:00:00 2001 From: "mark@chromium.org" Date: Tue, 17 Jun 2014 18:03:31 +0000 Subject: [PATCH] minidump_dump: bug fixes. - Convert time_t values to UTC correctly. It is incorrect to cast a uint32_t* to time_t* because the two types may have different widths. This is the case on many 64-bit systems, where time_t is a 64-bit signed integer. Conversion is unified in a single function, and additional uses of time_t in minidump files not previously displayed in UTC are now displayed. - Interpret the IMAGE_DEBUG_MISC structure correctly. - When printing MINIDUMP_SYSTEM_INFO structures, always show the "x86" side of the union, and state whether it's expected to be valid. (Existing Breakpad-produced non-Windows minidumps for x86_64 use the "x86" side of union, but Windows minidumps for x86_64 use the "other" side, so I want to print both.) R=ivanpe@chromium.org Review URL: https://breakpad.appspot.com/5674002 git-svn-id: http://google-breakpad.googlecode.com/svn/trunk@1339 4c0a9323-5329-0410-9bdc-e9ce6186880e --- src/processor/minidump.cc | 83 +++++++++++++++++++++++++-------------- 1 file changed, 53 insertions(+), 30 deletions(-) diff --git a/src/processor/minidump.cc b/src/processor/minidump.cc index 911fe9ba..99f285ca 100644 --- a/src/processor/minidump.cc +++ b/src/processor/minidump.cc @@ -366,6 +366,24 @@ static void PrintValueOrInvalid(bool valid, } } +// Converts a time_t to a string showing the time in UTC. +string TimeTToUTCString(time_t tt) { + struct tm timestruct; +#ifdef _WIN32 + gmtime_s(×truct, &tt); +#else + gmtime_r(&tt, ×truct); +#endif + + char timestr[20]; + int rv = strftime(timestr, 20, "%Y-%m-%d %H:%M:%S", ×truct); + if (rv == 0) { + return string(); + } + + return string(timestr); +} + // // MinidumpObject @@ -2797,8 +2815,9 @@ void MinidumpModule::Print() { module_.size_of_image); printf(" checksum = 0x%x\n", module_.checksum); - printf(" time_date_stamp = 0x%x\n", - module_.time_date_stamp); + printf(" time_date_stamp = 0x%x %s\n", + module_.time_date_stamp, + TimeTToUTCString(module_.time_date_stamp).c_str()); printf(" module_name_rva = 0x%x\n", module_.module_name_rva); printf(" version_info.signature = 0x%x\n", @@ -2872,8 +2891,9 @@ void MinidumpModule::Print() { cv_record_20->cv_header.signature); printf(" (cv_record).cv_header.offset = 0x%x\n", cv_record_20->cv_header.offset); - printf(" (cv_record).signature = 0x%x\n", - cv_record_20->signature); + printf(" (cv_record).signature = 0x%x %s\n", + cv_record_20->signature, + TimeTToUTCString(cv_record_20->signature).c_str()); printf(" (cv_record).age = %d\n", cv_record_20->age); printf(" (cv_record).pdb_file_name = \"%s\"\n", @@ -2899,13 +2919,19 @@ void MinidumpModule::Print() { misc_record->length); printf(" (misc_record).unicode = %d\n", misc_record->unicode); - // Don't bother printing the UTF-16, we don't really even expect to ever - // see this misc_record anyway. - if (misc_record->unicode) + if (misc_record->unicode) { + string misc_record_data_utf8; + ConvertUTF16BufferToUTF8String( + reinterpret_cast(misc_record->data), + misc_record->length - offsetof(MDImageDebugMisc, data), + &misc_record_data_utf8, + false); // already swapped + printf(" (misc_record).data = \"%s\"\n", + misc_record_data_utf8.c_str()); + } else { printf(" (misc_record).data = \"%s\"\n", misc_record->data); - else - printf(" (misc_record).data = (UTF-16)\n"); + } } else { printf(" (misc_record) = (null)\n"); } @@ -3830,6 +3856,12 @@ void MinidumpSystemInfo::Print() { system_info_.csd_version_rva); printf(" suite_mask = 0x%x\n", system_info_.suite_mask); + if (system_info_.processor_architecture == MD_CPU_ARCHITECTURE_X86 || + system_info_.processor_architecture == MD_CPU_ARCHITECTURE_X86_WIN64) { + printf(" cpu.x86_cpu_info (valid):\n"); + } else { + printf(" cpu.x86_cpu_info (invalid):\n"); + } for (unsigned int i = 0; i < 3; ++i) { printf(" cpu.x86_cpu_info.vendor_id[%d] = 0x%x\n", i, system_info_.cpu.x86_cpu_info.vendor_id[i]); @@ -3840,6 +3872,14 @@ void MinidumpSystemInfo::Print() { system_info_.cpu.x86_cpu_info.feature_information); printf(" cpu.x86_cpu_info.amd_extended_cpu_features = 0x%x\n", system_info_.cpu.x86_cpu_info.amd_extended_cpu_features); + if (system_info_.processor_architecture != MD_CPU_ARCHITECTURE_X86 && + system_info_.processor_architecture != MD_CPU_ARCHITECTURE_X86_WIN64) { + printf(" cpu.other_cpu_info (valid):\n"); + for (unsigned int i = 0; i < 2; ++i) { + printf(" cpu.other_cpu_info.processor_features[%d] = 0x%" PRIx64 "\n", + i, system_info_.cpu.other_cpu_info.processor_features[i]); + } + } const string* csd_version = GetCSDVersion(); if (csd_version) { printf(" (csd_version) = \"%s\"\n", @@ -3964,19 +4004,9 @@ void MinidumpMiscInfo::Print() { PrintValueOrInvalid(misc_info_.flags1 & MD_MISCINFO_FLAGS1_PROCESS_ID, kNumberFormatDecimal, misc_info_.process_id); if (misc_info_.flags1 & MD_MISCINFO_FLAGS1_PROCESS_TIMES) { - struct tm timestruct; -#ifdef _WIN32 - gmtime_s(×truct, - reinterpret_cast(&misc_info_.process_create_time)); -#else - gmtime_r(reinterpret_cast(&misc_info_.process_create_time), - ×truct); -#endif - char timestr[20]; - strftime(timestr, 20, "%Y-%m-%d %H:%M:%S", ×truct); printf(" process_create_time = 0x%x %s\n", misc_info_.process_create_time, - timestr); + TimeTToUTCString(misc_info_.process_create_time).c_str()); } else { printf(" process_create_time = (invalid)\n"); } @@ -4786,16 +4816,9 @@ void Minidump::Print() { printf(" stream_count = %d\n", header_.stream_count); printf(" stream_directory_rva = 0x%x\n", header_.stream_directory_rva); printf(" checksum = 0x%x\n", header_.checksum); - struct tm timestruct; -#ifdef _WIN32 - gmtime_s(×truct, reinterpret_cast(&header_.time_date_stamp)); -#else - gmtime_r(reinterpret_cast(&header_.time_date_stamp), ×truct); -#endif - char timestr[20]; - strftime(timestr, 20, "%Y-%m-%d %H:%M:%S", ×truct); - printf(" time_date_stamp = 0x%x %s\n", header_.time_date_stamp, - timestr); + printf(" time_date_stamp = 0x%x %s\n", + header_.time_date_stamp, + TimeTToUTCString(header_.time_date_stamp).c_str()); printf(" flags = 0x%" PRIx64 "\n", header_.flags); printf("\n");