Updating MDRawMiscInfo to support verions 3 and 4 of the MINIDUMP_MISC_INFO_N structure. Added the necessary code for swapping and string conversion from UTF-16. Found and fixed a bug in MinidumpAssertion::Read where the max string length passed to UTF16codeunits was in bytes instead of UTF-16 chars.
Tested with a minidump containing a version 3 structure to validate the string conversion routines. Interestingly enough the time_zone names does not appear to be abbreviation as the documentation was suggesting but full names, e.g. Eastern Standard Time: MDRawMiscInfo size_of_info = 232 flags1 = 0xf7 process_id = 0x54c4 process_create_time = 0x51a9323c process_user_time = 0x1 process_kernel_time = 0x0 processor_max_mhz = 3100 processor_current_mhz = 1891 processor_mhz_limit = 3100 processor_max_idle_state = 0x1 processor_current_idle_state = 0x1 The new fileds follow: process_integrity_level = 0x1000 process_execute_flags = 0x4d protected_process = 0 time_zone_id = 2 time_zone.bias = 300 time_zone.standard_name = Eastern Standard Time time_zone.daylight_name = Eastern Daylight Time Review URL: https://breakpad.appspot.com/617002 git-svn-id: http://google-breakpad.googlecode.com/svn/trunk@1204 4c0a9323-5329-0410-9bdc-e9ce6186880e
This commit is contained in:
parent
9c1dc68a2f
commit
1d1b36d371
3 changed files with 246 additions and 62 deletions
|
@ -347,7 +347,7 @@ typedef enum {
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
uint32_t length; /* Length of buffer in bytes (not characters),
|
uint32_t length; /* Length of buffer in bytes (not characters),
|
||||||
* excluding 0-terminator */
|
* excluding 0-terminator */
|
||||||
uint16_t buffer[1]; /* UTF-16-encoded, 0-terminated */
|
uint16_t buffer[1]; /* UTF-16-encoded, 0-terminated */
|
||||||
} MDString; /* MINIDUMP_STRING */
|
} MDString; /* MINIDUMP_STRING */
|
||||||
|
|
||||||
|
@ -658,6 +658,55 @@ typedef enum {
|
||||||
MD_OS_NACL = 0x8205 /* Native Client (NaCl) */
|
MD_OS_NACL = 0x8205 /* Native Client (NaCl) */
|
||||||
} MDOSPlatform;
|
} MDOSPlatform;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
uint16_t year;
|
||||||
|
uint16_t month;
|
||||||
|
uint16_t day_of_week;
|
||||||
|
uint16_t day;
|
||||||
|
uint16_t hour;
|
||||||
|
uint16_t minute;
|
||||||
|
uint16_t second;
|
||||||
|
uint16_t milliseconds;
|
||||||
|
} MDSystemTime; /* SYSTEMTIME */
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
/* Required field. The bias is the difference, in minutes, between
|
||||||
|
* Coordinated Universal Time (UTC) and local time.
|
||||||
|
* Formula: UTC = local time + bias */
|
||||||
|
int32_t bias;
|
||||||
|
/* A description for standard time. For example, "EST" could indicate Eastern
|
||||||
|
* Standard Time. In practice this contains the full time zone names. This
|
||||||
|
* string can be empty. */
|
||||||
|
uint16_t standard_name[32]; /* UTF-16-encoded, 0-terminated */
|
||||||
|
/* A MDSystemTime structure that contains a date and local time when the
|
||||||
|
* transition from daylight saving time to standard time occurs on this
|
||||||
|
* operating system. If the time zone does not support daylight saving time,
|
||||||
|
* the month member in the MDSystemTime structure is zero. */
|
||||||
|
MDSystemTime standard_date;
|
||||||
|
/* The bias value to be used during local time translations that occur during
|
||||||
|
* standard time. */
|
||||||
|
int32_t standard_bias;
|
||||||
|
/* A description for daylight saving time. For example, "PDT" could indicate
|
||||||
|
* Pacific Daylight Time. In practice this contains the full time zone names.
|
||||||
|
* This string can be empty. */
|
||||||
|
uint16_t daylight_name[32]; /* UTF-16-encoded, 0-terminated */
|
||||||
|
/* A MDSystemTime structure that contains a date and local time when the
|
||||||
|
* transition from standard time to daylight saving time occurs on this
|
||||||
|
* operating system. If the time zone does not support daylight saving time,
|
||||||
|
* the month member in the MDSystemTime structure is zero.*/
|
||||||
|
MDSystemTime daylight_date;
|
||||||
|
/* The bias value to be used during local time translations that occur during
|
||||||
|
* daylight saving time. */
|
||||||
|
int32_t daylight_bias;
|
||||||
|
} MDTimeZoneInformation; /* TIME_ZONE_INFORMATION */
|
||||||
|
|
||||||
|
/* MAX_PATH from windef.h */
|
||||||
|
#define MD_MAX_PATH 260
|
||||||
|
|
||||||
|
/* The miscellaneous information stream contains a variety
|
||||||
|
* of small pieces of information. A member is valid if
|
||||||
|
* it's within the available size and its corresponding
|
||||||
|
* bit is set. */
|
||||||
typedef struct {
|
typedef struct {
|
||||||
uint32_t size_of_info; /* Length of entire MDRawMiscInfo structure. */
|
uint32_t size_of_info; /* Length of entire MDRawMiscInfo structure. */
|
||||||
uint32_t flags1;
|
uint32_t flags1;
|
||||||
|
@ -673,8 +722,8 @@ typedef struct {
|
||||||
uint32_t process_kernel_time; /* seconds of kernel CPU time */
|
uint32_t process_kernel_time; /* seconds of kernel CPU time */
|
||||||
|
|
||||||
/* The following fields are not present in MINIDUMP_MISC_INFO but are
|
/* The following fields are not present in MINIDUMP_MISC_INFO but are
|
||||||
* in MINIDUMP_MISC_INFO_2. When this struct is populated, these values
|
* in MINIDUMP_MISC_INFO_2. When this struct is populated, these value
|
||||||
* may not be set. Use flags1 or sizeOfInfo to determine whether these
|
* may not be set. Use flags1 or size_of_info to determine whether these
|
||||||
* values are present. These are only valid when flags1 contains
|
* values are present. These are only valid when flags1 contains
|
||||||
* MD_MISCINFO_FLAGS1_PROCESSOR_POWER_INFO. */
|
* MD_MISCINFO_FLAGS1_PROCESSOR_POWER_INFO. */
|
||||||
uint32_t processor_max_mhz;
|
uint32_t processor_max_mhz;
|
||||||
|
@ -682,20 +731,66 @@ typedef struct {
|
||||||
uint32_t processor_mhz_limit;
|
uint32_t processor_mhz_limit;
|
||||||
uint32_t processor_max_idle_state;
|
uint32_t processor_max_idle_state;
|
||||||
uint32_t processor_current_idle_state;
|
uint32_t processor_current_idle_state;
|
||||||
} MDRawMiscInfo; /* MINIDUMP_MISC_INFO, MINIDUMP_MISC_INFO2 */
|
|
||||||
|
|
||||||
#define MD_MISCINFO_SIZE 24
|
/* The following fields are not present in MINIDUMP_MISC_INFO_2 but are
|
||||||
#define MD_MISCINFO2_SIZE 44
|
* in MINIDUMP_MISC_INFO_3. When this struct is populated, these value
|
||||||
|
* may not be set. Use flags1 or size_of_info to determine whether these
|
||||||
|
* values are present. */
|
||||||
|
|
||||||
|
/* The following field is only valid if flags1 contains
|
||||||
|
* MD_MISCINFO_FLAGS1_PROCESS_INTEGRITY. */
|
||||||
|
uint32_t process_integrity_level;
|
||||||
|
|
||||||
|
/* The following field is only valid if flags1 contains
|
||||||
|
* MD_MISCINFO_FLAGS1_PROCESS_EXECUTE_FLAGS. */
|
||||||
|
uint32_t process_execute_flags;
|
||||||
|
|
||||||
|
/* The following field is only valid if flags1 contains
|
||||||
|
* MD_MISCINFO_FLAGS1_PROTECTED_PROCESS. */
|
||||||
|
uint32_t protected_process;
|
||||||
|
|
||||||
|
/* The following 2 fields are only valid if flags1 contains
|
||||||
|
* MD_MISCINFO_FLAGS1_TIMEZONE. */
|
||||||
|
uint32_t time_zone_id;
|
||||||
|
MDTimeZoneInformation time_zone;
|
||||||
|
|
||||||
|
/* The following fields are not present in MINIDUMP_MISC_INFO_3 but are
|
||||||
|
* in MINIDUMP_MISC_INFO_4. When this struct is populated, these value
|
||||||
|
* may not be set. Use size_of_info to determine whether these values are
|
||||||
|
* present. */
|
||||||
|
|
||||||
|
/* The following 2 fields are only valid if
|
||||||
|
* size_of_info is >= MD_MISCINFO4_SIZE */
|
||||||
|
uint16_t build_string[MD_MAX_PATH]; /* UTF-16-encoded, 0-terminated */
|
||||||
|
uint16_t dbg_bld_str[40]; /* UTF-16-encoded, 0-terminated */
|
||||||
|
} MDRawMiscInfo; /* MINIDUMP_MISC_INFO, MINIDUMP_MISC_INFO2,
|
||||||
|
* MINIDUMP_MISC_INFO3, MINIDUMP_MISC_INFO4 */
|
||||||
|
|
||||||
|
static const size_t MD_MISCINFO_SIZE =
|
||||||
|
offsetof(MDRawMiscInfo, processor_max_mhz);
|
||||||
|
static const size_t MD_MISCINFO2_SIZE =
|
||||||
|
offsetof(MDRawMiscInfo, process_integrity_level);
|
||||||
|
static const size_t MD_MISCINFO3_SIZE =
|
||||||
|
offsetof(MDRawMiscInfo, build_string[0]);
|
||||||
|
static const size_t MD_MISCINFO4_SIZE = sizeof(MDRawMiscInfo);
|
||||||
|
|
||||||
/* For (MDRawMiscInfo).flags1. These values indicate which fields in the
|
/* For (MDRawMiscInfo).flags1. These values indicate which fields in the
|
||||||
* MDRawMiscInfoStructure are valid. */
|
* MDRawMiscInfoStructure are valid. */
|
||||||
typedef enum {
|
typedef enum {
|
||||||
MD_MISCINFO_FLAGS1_PROCESS_ID = 0x00000001,
|
MD_MISCINFO_FLAGS1_PROCESS_ID = 0x00000001,
|
||||||
/* MINIDUMP_MISC1_PROCESS_ID */
|
/* MINIDUMP_MISC1_PROCESS_ID */
|
||||||
MD_MISCINFO_FLAGS1_PROCESS_TIMES = 0x00000002,
|
MD_MISCINFO_FLAGS1_PROCESS_TIMES = 0x00000002,
|
||||||
/* MINIDUMP_MISC1_PROCESS_TIMES */
|
/* MINIDUMP_MISC1_PROCESS_TIMES */
|
||||||
MD_MISCINFO_FLAGS1_PROCESSOR_POWER_INFO = 0x00000004
|
MD_MISCINFO_FLAGS1_PROCESSOR_POWER_INFO = 0x00000004,
|
||||||
/* MINIDUMP_MISC1_PROCESSOR_POWER_INFO */
|
/* MINIDUMP_MISC1_PROCESSOR_POWER_INFO */
|
||||||
|
MD_MISCINFO_FLAGS1_PROCESS_INTEGRITY = 0x00000010,
|
||||||
|
/* MINIDUMP_MISC3_PROCESS_INTEGRITY */
|
||||||
|
MD_MISCINFO_FLAGS1_PROCESS_EXECUTE_FLAGS = 0x00000020,
|
||||||
|
/* MINIDUMP_MISC3_PROCESS_EXECUTE_FLAGS */
|
||||||
|
MD_MISCINFO_FLAGS1_TIMEZONE = 0x00000040,
|
||||||
|
/* MINIDUMP_MISC3_TIMEZONE */
|
||||||
|
MD_MISCINFO_FLAGS1_PROTECTED_PROCESS = 0x00000080,
|
||||||
|
/* MINIDUMP_MISC3_PROTECTED_PROCESS */
|
||||||
} MDMiscInfoFlags1;
|
} MDMiscInfoFlags1;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
|
@ -782,6 +782,13 @@ class MinidumpMiscInfo : public MinidumpStream {
|
||||||
bool Read(uint32_t expected_size_);
|
bool Read(uint32_t expected_size_);
|
||||||
|
|
||||||
MDRawMiscInfo misc_info_;
|
MDRawMiscInfo misc_info_;
|
||||||
|
|
||||||
|
// Populated by Read. Contains the converted strings from the corresponding
|
||||||
|
// UTF-16 fields in misc_info_
|
||||||
|
string standard_name_;
|
||||||
|
string daylight_name_;
|
||||||
|
string build_string_;
|
||||||
|
string dbg_bld_str_;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -140,6 +140,19 @@ static void Swap(uint128_struct* value) {
|
||||||
Swap(&value->high);
|
Swap(&value->high);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Swapping signed integers
|
||||||
|
static inline void Swap(int16_t* value) {
|
||||||
|
Swap(reinterpret_cast<uint16_t*>(value));
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void Swap(int32_t* value) {
|
||||||
|
Swap(reinterpret_cast<uint32_t*>(value));
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void Swap(int64_t* value) {
|
||||||
|
Swap(reinterpret_cast<uint64_t*>(value));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
static inline void Swap(MDLocationDescriptor* location_descriptor) {
|
static inline void Swap(MDLocationDescriptor* location_descriptor) {
|
||||||
Swap(&location_descriptor->data_size);
|
Swap(&location_descriptor->data_size);
|
||||||
|
@ -160,6 +173,23 @@ static inline void Swap(MDGUID* guid) {
|
||||||
// Don't swap guid->data4[] because it contains 8-bit quantities.
|
// Don't swap guid->data4[] because it contains 8-bit quantities.
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static inline void Swap(MDSystemTime* system_time) {
|
||||||
|
Swap(&system_time->year);
|
||||||
|
Swap(&system_time->month);
|
||||||
|
Swap(&system_time->day_of_week);
|
||||||
|
Swap(&system_time->day);
|
||||||
|
Swap(&system_time->hour);
|
||||||
|
Swap(&system_time->minute);
|
||||||
|
Swap(&system_time->second);
|
||||||
|
Swap(&system_time->milliseconds);
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void Swap(uint16_t* data, size_t size_in_bytes) {
|
||||||
|
size_t data_length = size_in_bytes / sizeof(data[0]);
|
||||||
|
for (size_t i = 0; i < data_length; i++) {
|
||||||
|
Swap(&data[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
// Character conversion routines
|
// Character conversion routines
|
||||||
|
@ -176,7 +206,7 @@ static inline void Swap(MDGUID* guid) {
|
||||||
// CPU's endianness into consideration. It doesn't seems worth the trouble
|
// CPU's endianness into consideration. It doesn't seems worth the trouble
|
||||||
// of making it a dependency when we don't care about anything but UTF-16.
|
// of making it a dependency when we don't care about anything but UTF-16.
|
||||||
static string* UTF16ToUTF8(const vector<uint16_t>& in,
|
static string* UTF16ToUTF8(const vector<uint16_t>& in,
|
||||||
bool swap) {
|
bool swap) {
|
||||||
scoped_ptr<string> out(new string());
|
scoped_ptr<string> out(new string());
|
||||||
|
|
||||||
// Set the string's initial capacity to the number of UTF-16 characters,
|
// Set the string's initial capacity to the number of UTF-16 characters,
|
||||||
|
@ -256,6 +286,39 @@ static size_t UTF16codeunits(const uint16_t *string, size_t maxlen) {
|
||||||
return count;
|
return count;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static inline void Swap(MDTimeZoneInformation* time_zone) {
|
||||||
|
Swap(&time_zone->bias);
|
||||||
|
// Skip time_zone->standard_name. No need to swap UTF-16 fields.
|
||||||
|
// The swap will be done as part of the conversion to UTF-8.
|
||||||
|
Swap(&time_zone->standard_date);
|
||||||
|
Swap(&time_zone->standard_bias);
|
||||||
|
// Skip time_zone->daylight_name. No need to swap UTF-16 fields.
|
||||||
|
// The swap will be done as part of the conversion to UTF-8.
|
||||||
|
Swap(&time_zone->daylight_date);
|
||||||
|
Swap(&time_zone->daylight_bias);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void ConvertUTF16BufferToUTF8String(const uint16_t* utf16_data,
|
||||||
|
size_t max_length_in_bytes,
|
||||||
|
string* utf8_result,
|
||||||
|
bool swap) {
|
||||||
|
// Since there is no explicit byte length for each string, use
|
||||||
|
// UTF16codeunits to calculate word length, then derive byte
|
||||||
|
// length from that.
|
||||||
|
size_t max_word_length = max_length_in_bytes / sizeof(utf16_data[0]);
|
||||||
|
size_t word_length = UTF16codeunits(utf16_data, max_word_length);
|
||||||
|
if (word_length > 0) {
|
||||||
|
size_t byte_length = word_length * sizeof(utf16_data[0]);
|
||||||
|
vector<uint16_t> utf16_vector(word_length);
|
||||||
|
memcpy(&utf16_vector[0], &utf16_data[0], byte_length);
|
||||||
|
scoped_ptr<string> temp(UTF16ToUTF8(utf16_vector, swap));
|
||||||
|
if (temp.get()) {
|
||||||
|
utf8_result->assign(*temp);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
utf8_result->clear();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
// MinidumpObject
|
// MinidumpObject
|
||||||
|
@ -2355,12 +2418,7 @@ const MDImageDebugMisc* MinidumpModule::GetMiscRecord(uint32_t* size) {
|
||||||
uint16_t* data16 = reinterpret_cast<uint16_t*>(&(misc_record->data));
|
uint16_t* data16 = reinterpret_cast<uint16_t*>(&(misc_record->data));
|
||||||
unsigned int dataBytes = module_.misc_record.data_size -
|
unsigned int dataBytes = module_.misc_record.data_size -
|
||||||
MDImageDebugMisc_minsize;
|
MDImageDebugMisc_minsize;
|
||||||
unsigned int dataLength = dataBytes / 2;
|
Swap(data16, dataBytes);
|
||||||
for (unsigned int characterIndex = 0;
|
|
||||||
characterIndex < dataLength;
|
|
||||||
++characterIndex) {
|
|
||||||
Swap(&data16[characterIndex]);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3143,48 +3201,14 @@ bool MinidumpAssertion::Read(uint32_t expected_size) {
|
||||||
|
|
||||||
// Each of {expression, function, file} is a UTF-16 string,
|
// Each of {expression, function, file} is a UTF-16 string,
|
||||||
// we'll convert them to UTF-8 for ease of use.
|
// we'll convert them to UTF-8 for ease of use.
|
||||||
// expression
|
ConvertUTF16BufferToUTF8String(assertion_.expression,
|
||||||
// Since we don't have an explicit byte length for each string,
|
sizeof(assertion_.expression), &expression_,
|
||||||
// we use UTF16codeunits to calculate word length, then derive byte
|
minidump_->swap());
|
||||||
// length from that.
|
ConvertUTF16BufferToUTF8String(assertion_.function,
|
||||||
uint32_t word_length = UTF16codeunits(assertion_.expression,
|
sizeof(assertion_.function), &function_,
|
||||||
sizeof(assertion_.expression));
|
minidump_->swap());
|
||||||
if (word_length > 0) {
|
ConvertUTF16BufferToUTF8String(assertion_.file, sizeof(assertion_.file),
|
||||||
uint32_t byte_length = word_length * 2;
|
&file_, minidump_->swap());
|
||||||
vector<uint16_t> expression_utf16(word_length);
|
|
||||||
memcpy(&expression_utf16[0], &assertion_.expression[0], byte_length);
|
|
||||||
|
|
||||||
scoped_ptr<string> new_expression(UTF16ToUTF8(expression_utf16,
|
|
||||||
minidump_->swap()));
|
|
||||||
if (new_expression.get())
|
|
||||||
expression_ = *new_expression;
|
|
||||||
}
|
|
||||||
|
|
||||||
// assertion
|
|
||||||
word_length = UTF16codeunits(assertion_.function,
|
|
||||||
sizeof(assertion_.function));
|
|
||||||
if (word_length) {
|
|
||||||
uint32_t byte_length = word_length * 2;
|
|
||||||
vector<uint16_t> function_utf16(word_length);
|
|
||||||
memcpy(&function_utf16[0], &assertion_.function[0], byte_length);
|
|
||||||
scoped_ptr<string> new_function(UTF16ToUTF8(function_utf16,
|
|
||||||
minidump_->swap()));
|
|
||||||
if (new_function.get())
|
|
||||||
function_ = *new_function;
|
|
||||||
}
|
|
||||||
|
|
||||||
// file
|
|
||||||
word_length = UTF16codeunits(assertion_.file,
|
|
||||||
sizeof(assertion_.file));
|
|
||||||
if (word_length > 0) {
|
|
||||||
uint32_t byte_length = word_length * 2;
|
|
||||||
vector<uint16_t> file_utf16(word_length);
|
|
||||||
memcpy(&file_utf16[0], &assertion_.file[0], byte_length);
|
|
||||||
scoped_ptr<string> new_file(UTF16ToUTF8(file_utf16,
|
|
||||||
minidump_->swap()));
|
|
||||||
if (new_file.get())
|
|
||||||
file_ = *new_file;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (minidump_->swap()) {
|
if (minidump_->swap()) {
|
||||||
Swap(&assertion_.line);
|
Swap(&assertion_.line);
|
||||||
|
@ -3502,10 +3526,13 @@ bool MinidumpMiscInfo::Read(uint32_t expected_size) {
|
||||||
valid_ = false;
|
valid_ = false;
|
||||||
|
|
||||||
if (expected_size != MD_MISCINFO_SIZE &&
|
if (expected_size != MD_MISCINFO_SIZE &&
|
||||||
expected_size != MD_MISCINFO2_SIZE) {
|
expected_size != MD_MISCINFO2_SIZE &&
|
||||||
BPLOG(ERROR) << "MinidumpMiscInfo size mismatch, " << expected_size <<
|
expected_size != MD_MISCINFO3_SIZE &&
|
||||||
" != " << MD_MISCINFO_SIZE << ", " << MD_MISCINFO2_SIZE <<
|
expected_size != MD_MISCINFO4_SIZE) {
|
||||||
")";
|
BPLOG(ERROR) << "MinidumpMiscInfo size mismatch, " << expected_size
|
||||||
|
<< " != " << MD_MISCINFO_SIZE << ", " << MD_MISCINFO2_SIZE
|
||||||
|
<< ", " << MD_MISCINFO3_SIZE << ", " << MD_MISCINFO4_SIZE
|
||||||
|
<< ")";
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3515,6 +3542,7 @@ bool MinidumpMiscInfo::Read(uint32_t expected_size) {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (minidump_->swap()) {
|
if (minidump_->swap()) {
|
||||||
|
// Swap version 1 fields
|
||||||
Swap(&misc_info_.size_of_info);
|
Swap(&misc_info_.size_of_info);
|
||||||
Swap(&misc_info_.flags1);
|
Swap(&misc_info_.flags1);
|
||||||
Swap(&misc_info_.process_id);
|
Swap(&misc_info_.process_id);
|
||||||
|
@ -3522,12 +3550,26 @@ bool MinidumpMiscInfo::Read(uint32_t expected_size) {
|
||||||
Swap(&misc_info_.process_user_time);
|
Swap(&misc_info_.process_user_time);
|
||||||
Swap(&misc_info_.process_kernel_time);
|
Swap(&misc_info_.process_kernel_time);
|
||||||
if (misc_info_.size_of_info > MD_MISCINFO_SIZE) {
|
if (misc_info_.size_of_info > MD_MISCINFO_SIZE) {
|
||||||
|
// Swap version 2 fields
|
||||||
Swap(&misc_info_.processor_max_mhz);
|
Swap(&misc_info_.processor_max_mhz);
|
||||||
Swap(&misc_info_.processor_current_mhz);
|
Swap(&misc_info_.processor_current_mhz);
|
||||||
Swap(&misc_info_.processor_mhz_limit);
|
Swap(&misc_info_.processor_mhz_limit);
|
||||||
Swap(&misc_info_.processor_max_idle_state);
|
Swap(&misc_info_.processor_max_idle_state);
|
||||||
Swap(&misc_info_.processor_current_idle_state);
|
Swap(&misc_info_.processor_current_idle_state);
|
||||||
}
|
}
|
||||||
|
if (misc_info_.size_of_info > MD_MISCINFO2_SIZE) {
|
||||||
|
// Swap version 3 fields
|
||||||
|
Swap(&misc_info_.process_integrity_level);
|
||||||
|
Swap(&misc_info_.process_execute_flags);
|
||||||
|
Swap(&misc_info_.protected_process);
|
||||||
|
Swap(&misc_info_.time_zone_id);
|
||||||
|
Swap(&misc_info_.time_zone);
|
||||||
|
}
|
||||||
|
if (misc_info_.size_of_info > MD_MISCINFO3_SIZE) {
|
||||||
|
// Swap version 4 fields.
|
||||||
|
// Do not swap UTF-16 strings. The swap is done as part of the
|
||||||
|
// conversion to UTF-8 (code follows below).
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (expected_size != misc_info_.size_of_info) {
|
if (expected_size != misc_info_.size_of_info) {
|
||||||
|
@ -3536,6 +3578,26 @@ bool MinidumpMiscInfo::Read(uint32_t expected_size) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Convert UTF-16 strings
|
||||||
|
if (misc_info_.size_of_info > MD_MISCINFO2_SIZE) {
|
||||||
|
// Convert UTF-16 strings in version 3 fields
|
||||||
|
ConvertUTF16BufferToUTF8String(misc_info_.time_zone.standard_name,
|
||||||
|
sizeof(misc_info_.time_zone.standard_name),
|
||||||
|
&standard_name_, minidump_->swap());
|
||||||
|
ConvertUTF16BufferToUTF8String(misc_info_.time_zone.daylight_name,
|
||||||
|
sizeof(misc_info_.time_zone.daylight_name),
|
||||||
|
&daylight_name_, minidump_->swap());
|
||||||
|
}
|
||||||
|
if (misc_info_.size_of_info > MD_MISCINFO3_SIZE) {
|
||||||
|
// Convert UTF-16 strings in version 4 fields
|
||||||
|
ConvertUTF16BufferToUTF8String(misc_info_.build_string,
|
||||||
|
sizeof(misc_info_.build_string),
|
||||||
|
&build_string_, minidump_->swap());
|
||||||
|
ConvertUTF16BufferToUTF8String(misc_info_.dbg_bld_str,
|
||||||
|
sizeof(misc_info_.dbg_bld_str),
|
||||||
|
&dbg_bld_str_, minidump_->swap());
|
||||||
|
}
|
||||||
|
|
||||||
valid_ = true;
|
valid_ = true;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -3548,6 +3610,7 @@ void MinidumpMiscInfo::Print() {
|
||||||
}
|
}
|
||||||
|
|
||||||
printf("MDRawMiscInfo\n");
|
printf("MDRawMiscInfo\n");
|
||||||
|
// Print version 1 fields
|
||||||
printf(" size_of_info = %d\n", misc_info_.size_of_info);
|
printf(" size_of_info = %d\n", misc_info_.size_of_info);
|
||||||
printf(" flags1 = 0x%x\n", misc_info_.flags1);
|
printf(" flags1 = 0x%x\n", misc_info_.flags1);
|
||||||
printf(" process_id = 0x%x\n", misc_info_.process_id);
|
printf(" process_id = 0x%x\n", misc_info_.process_id);
|
||||||
|
@ -3558,6 +3621,7 @@ void MinidumpMiscInfo::Print() {
|
||||||
printf(" process_kernel_time = 0x%x\n",
|
printf(" process_kernel_time = 0x%x\n",
|
||||||
misc_info_.process_kernel_time);
|
misc_info_.process_kernel_time);
|
||||||
if (misc_info_.size_of_info > MD_MISCINFO_SIZE) {
|
if (misc_info_.size_of_info > MD_MISCINFO_SIZE) {
|
||||||
|
// Print version 2 fields
|
||||||
printf(" processor_max_mhz = %d\n",
|
printf(" processor_max_mhz = %d\n",
|
||||||
misc_info_.processor_max_mhz);
|
misc_info_.processor_max_mhz);
|
||||||
printf(" processor_current_mhz = %d\n",
|
printf(" processor_current_mhz = %d\n",
|
||||||
|
@ -3569,6 +3633,24 @@ void MinidumpMiscInfo::Print() {
|
||||||
printf(" processor_current_idle_state = 0x%x\n",
|
printf(" processor_current_idle_state = 0x%x\n",
|
||||||
misc_info_.processor_current_idle_state);
|
misc_info_.processor_current_idle_state);
|
||||||
}
|
}
|
||||||
|
if (misc_info_.size_of_info > MD_MISCINFO2_SIZE) {
|
||||||
|
// Print version 3 fields
|
||||||
|
printf(" process_integrity_level = 0x%x\n",
|
||||||
|
misc_info_.process_integrity_level);
|
||||||
|
printf(" process_execute_flags = 0x%x\n",
|
||||||
|
misc_info_.process_execute_flags);
|
||||||
|
printf(" protected_process = %d\n",
|
||||||
|
misc_info_.protected_process);
|
||||||
|
printf(" time_zone_id = %d\n", misc_info_.time_zone_id);
|
||||||
|
printf(" time_zone.bias = %d\n", misc_info_.time_zone.bias);
|
||||||
|
printf(" time_zone.standard_name = %s\n", standard_name_.c_str());
|
||||||
|
printf(" time_zone.daylight_name = %s\n", daylight_name_.c_str());
|
||||||
|
}
|
||||||
|
if (misc_info_.size_of_info > MD_MISCINFO3_SIZE) {
|
||||||
|
// Print version 4 fields
|
||||||
|
printf(" build_string = %s\n", build_string_.c_str());
|
||||||
|
printf(" dbg_bld_str = %s\n", dbg_bld_str_.c_str());
|
||||||
|
}
|
||||||
printf("\n");
|
printf("\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue