Add missing MD_MISCINFO_FLAGS1_BUILDSTRING. Revise documentation to clarify
that it is not enough to check the size of an MDRawMiscInfo stream to verify member validity, the flags1 field needs to be consulted as well. Update minidump_dump to correctly consider the validity of all fields in this structure. R=ivanpe@chromium.org Review URL: https://breakpad.appspot.com/3694002 git-svn-id: http://google-breakpad.googlecode.com/svn/trunk@1336 4c0a9323-5329-0410-9bdc-e9ce6186880e
This commit is contained in:
parent
dfdc7d2966
commit
91f746ec81
@ -724,8 +724,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 value
|
* in MINIDUMP_MISC_INFO_2. When this struct is populated, these values
|
||||||
* may not be set. Use flags1 or size_of_info to determine whether these
|
* may not be set. Use flags1 and 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;
|
||||||
@ -735,8 +735,8 @@ typedef struct {
|
|||||||
uint32_t processor_current_idle_state;
|
uint32_t processor_current_idle_state;
|
||||||
|
|
||||||
/* The following fields are not present in MINIDUMP_MISC_INFO_2 but are
|
/* The following fields are not present in MINIDUMP_MISC_INFO_2 but are
|
||||||
* in MINIDUMP_MISC_INFO_3. When this struct is populated, these value
|
* in MINIDUMP_MISC_INFO_3. When this struct is populated, these values
|
||||||
* may not be set. Use flags1 or size_of_info to determine whether these
|
* may not be set. Use flags1 and size_of_info to determine whether these
|
||||||
* values are present. */
|
* values are present. */
|
||||||
|
|
||||||
/* The following field is only valid if flags1 contains
|
/* The following field is only valid if flags1 contains
|
||||||
@ -757,16 +757,17 @@ typedef struct {
|
|||||||
MDTimeZoneInformation time_zone;
|
MDTimeZoneInformation time_zone;
|
||||||
|
|
||||||
/* The following fields are not present in MINIDUMP_MISC_INFO_3 but are
|
/* 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
|
* in MINIDUMP_MISC_INFO_4. When this struct is populated, these values
|
||||||
* may not be set. Use size_of_info to determine whether these values are
|
* may not be set. Use flags1 and size_of_info to determine whether these
|
||||||
* present. */
|
* values are present. */
|
||||||
|
|
||||||
/* The following 2 fields are only valid if
|
/* The following 2 fields are only valid if flags1 contains
|
||||||
* size_of_info is >= MD_MISCINFO4_SIZE */
|
* MD_MISCINFO_FLAGS1_BUILDSTRING. */
|
||||||
uint16_t build_string[MD_MAX_PATH]; /* UTF-16-encoded, 0-terminated */
|
uint16_t build_string[MD_MAX_PATH]; /* UTF-16-encoded, 0-terminated */
|
||||||
uint16_t dbg_bld_str[40]; /* UTF-16-encoded, 0-terminated */
|
uint16_t dbg_bld_str[40]; /* UTF-16-encoded, 0-terminated */
|
||||||
} MDRawMiscInfo; /* MINIDUMP_MISC_INFO, MINIDUMP_MISC_INFO2,
|
} MDRawMiscInfo; /* MINIDUMP_MISC_INFO, MINIDUMP_MISC_INFO_2,
|
||||||
* MINIDUMP_MISC_INFO3, MINIDUMP_MISC_INFO4 */
|
* MINIDUMP_MISC_INFO_3, MINIDUMP_MISC_INFO_4,
|
||||||
|
* MINIDUMP_MISC_INFO_N */
|
||||||
|
|
||||||
static const size_t MD_MISCINFO_SIZE =
|
static const size_t MD_MISCINFO_SIZE =
|
||||||
offsetof(MDRawMiscInfo, processor_max_mhz);
|
offsetof(MDRawMiscInfo, processor_max_mhz);
|
||||||
@ -793,6 +794,8 @@ typedef enum {
|
|||||||
/* MINIDUMP_MISC3_TIMEZONE */
|
/* MINIDUMP_MISC3_TIMEZONE */
|
||||||
MD_MISCINFO_FLAGS1_PROTECTED_PROCESS = 0x00000080,
|
MD_MISCINFO_FLAGS1_PROTECTED_PROCESS = 0x00000080,
|
||||||
/* MINIDUMP_MISC3_PROTECTED_PROCESS */
|
/* MINIDUMP_MISC3_PROTECTED_PROCESS */
|
||||||
|
MD_MISCINFO_FLAGS1_BUILDSTRING = 0x00000100,
|
||||||
|
/* MINIDUMP_MISC4_BUILDSTRING */
|
||||||
} MDMiscInfoFlags1;
|
} MDMiscInfoFlags1;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -344,6 +344,29 @@ static void ConvertUTF16BufferToUTF8String(const uint16_t* utf16_data,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// For fields that may or may not be valid, PrintValueOrInvalid will print the
|
||||||
|
// string "(invalid)" if the field is not valid, and will print the value if
|
||||||
|
// the field is valid. The value is printed as hexadecimal or decimal.
|
||||||
|
|
||||||
|
enum NumberFormat {
|
||||||
|
kNumberFormatDecimal,
|
||||||
|
kNumberFormatHexadecimal,
|
||||||
|
};
|
||||||
|
|
||||||
|
static void PrintValueOrInvalid(bool valid,
|
||||||
|
NumberFormat number_format,
|
||||||
|
uint32_t value) {
|
||||||
|
if (!valid) {
|
||||||
|
printf("(invalid)\n");
|
||||||
|
} else if (number_format == kNumberFormatDecimal) {
|
||||||
|
printf("%d\n", value);
|
||||||
|
} else {
|
||||||
|
printf("0x%x\n", value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
//
|
//
|
||||||
// MinidumpObject
|
// MinidumpObject
|
||||||
//
|
//
|
||||||
@ -3785,7 +3808,7 @@ void MinidumpSystemInfo::Print() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
printf("MDRawSystemInfo\n");
|
printf("MDRawSystemInfo\n");
|
||||||
printf(" processor_architecture = %d\n",
|
printf(" processor_architecture = 0x%x\n",
|
||||||
system_info_.processor_architecture);
|
system_info_.processor_architecture);
|
||||||
printf(" processor_level = %d\n",
|
printf(" processor_level = %d\n",
|
||||||
system_info_.processor_level);
|
system_info_.processor_level);
|
||||||
@ -3801,7 +3824,7 @@ void MinidumpSystemInfo::Print() {
|
|||||||
system_info_.minor_version);
|
system_info_.minor_version);
|
||||||
printf(" build_number = %d\n",
|
printf(" build_number = %d\n",
|
||||||
system_info_.build_number);
|
system_info_.build_number);
|
||||||
printf(" platform_id = %d\n",
|
printf(" platform_id = 0x%x\n",
|
||||||
system_info_.platform_id);
|
system_info_.platform_id);
|
||||||
printf(" csd_version_rva = 0x%x\n",
|
printf(" csd_version_rva = 0x%x\n",
|
||||||
system_info_.csd_version_rva);
|
system_info_.csd_version_rva);
|
||||||
@ -3937,43 +3960,124 @@ void MinidumpMiscInfo::Print() {
|
|||||||
// Print version 1 fields
|
// 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 = ");
|
||||||
printf(" process_create_time = 0x%x\n",
|
PrintValueOrInvalid(misc_info_.flags1 & MD_MISCINFO_FLAGS1_PROCESS_ID,
|
||||||
misc_info_.process_create_time);
|
kNumberFormatDecimal, misc_info_.process_id);
|
||||||
printf(" process_user_time = 0x%x\n",
|
if (misc_info_.flags1 & MD_MISCINFO_FLAGS1_PROCESS_TIMES) {
|
||||||
misc_info_.process_user_time);
|
struct tm timestruct;
|
||||||
printf(" process_kernel_time = 0x%x\n",
|
#ifdef _WIN32
|
||||||
misc_info_.process_kernel_time);
|
gmtime_s(×truct,
|
||||||
|
reinterpret_cast<time_t*>(&misc_info_.process_create_time));
|
||||||
|
#else
|
||||||
|
gmtime_r(reinterpret_cast<time_t*>(&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);
|
||||||
|
} else {
|
||||||
|
printf(" process_create_time = (invalid)\n");
|
||||||
|
}
|
||||||
|
printf(" process_user_time = ");
|
||||||
|
PrintValueOrInvalid(misc_info_.flags1 & MD_MISCINFO_FLAGS1_PROCESS_TIMES,
|
||||||
|
kNumberFormatDecimal, misc_info_.process_user_time);
|
||||||
|
printf(" process_kernel_time = ");
|
||||||
|
PrintValueOrInvalid(misc_info_.flags1 & MD_MISCINFO_FLAGS1_PROCESS_TIMES,
|
||||||
|
kNumberFormatDecimal, 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
|
// Print version 2 fields
|
||||||
printf(" processor_max_mhz = %d\n",
|
printf(" processor_max_mhz = ");
|
||||||
misc_info_.processor_max_mhz);
|
PrintValueOrInvalid(misc_info_.flags1 &
|
||||||
printf(" processor_current_mhz = %d\n",
|
MD_MISCINFO_FLAGS1_PROCESSOR_POWER_INFO,
|
||||||
misc_info_.processor_current_mhz);
|
kNumberFormatDecimal, misc_info_.processor_max_mhz);
|
||||||
printf(" processor_mhz_limit = %d\n",
|
printf(" processor_current_mhz = ");
|
||||||
misc_info_.processor_mhz_limit);
|
PrintValueOrInvalid(misc_info_.flags1 &
|
||||||
printf(" processor_max_idle_state = 0x%x\n",
|
MD_MISCINFO_FLAGS1_PROCESSOR_POWER_INFO,
|
||||||
misc_info_.processor_max_idle_state);
|
kNumberFormatDecimal, misc_info_.processor_current_mhz);
|
||||||
printf(" processor_current_idle_state = 0x%x\n",
|
printf(" processor_mhz_limit = ");
|
||||||
misc_info_.processor_current_idle_state);
|
PrintValueOrInvalid(misc_info_.flags1 &
|
||||||
|
MD_MISCINFO_FLAGS1_PROCESSOR_POWER_INFO,
|
||||||
|
kNumberFormatDecimal, misc_info_.processor_mhz_limit);
|
||||||
|
printf(" processor_max_idle_state = ");
|
||||||
|
PrintValueOrInvalid(misc_info_.flags1 &
|
||||||
|
MD_MISCINFO_FLAGS1_PROCESSOR_POWER_INFO,
|
||||||
|
kNumberFormatDecimal,
|
||||||
|
misc_info_.processor_max_idle_state);
|
||||||
|
printf(" processor_current_idle_state = ");
|
||||||
|
PrintValueOrInvalid(misc_info_.flags1 &
|
||||||
|
MD_MISCINFO_FLAGS1_PROCESSOR_POWER_INFO,
|
||||||
|
kNumberFormatDecimal,
|
||||||
|
misc_info_.processor_current_idle_state);
|
||||||
}
|
}
|
||||||
if (misc_info_.size_of_info > MD_MISCINFO2_SIZE) {
|
if (misc_info_.size_of_info > MD_MISCINFO2_SIZE) {
|
||||||
// Print version 3 fields
|
// Print version 3 fields
|
||||||
printf(" process_integrity_level = 0x%x\n",
|
printf(" process_integrity_level = ");
|
||||||
misc_info_.process_integrity_level);
|
PrintValueOrInvalid(misc_info_.flags1 &
|
||||||
printf(" process_execute_flags = 0x%x\n",
|
MD_MISCINFO_FLAGS1_PROCESS_INTEGRITY,
|
||||||
misc_info_.process_execute_flags);
|
kNumberFormatHexadecimal,
|
||||||
printf(" protected_process = %d\n",
|
misc_info_.process_integrity_level);
|
||||||
misc_info_.protected_process);
|
printf(" process_execute_flags = ");
|
||||||
printf(" time_zone_id = %d\n", misc_info_.time_zone_id);
|
PrintValueOrInvalid(misc_info_.flags1 &
|
||||||
printf(" time_zone.bias = %d\n", misc_info_.time_zone.bias);
|
MD_MISCINFO_FLAGS1_PROCESS_EXECUTE_FLAGS,
|
||||||
printf(" time_zone.standard_name = %s\n", standard_name_.c_str());
|
kNumberFormatHexadecimal,
|
||||||
printf(" time_zone.daylight_name = %s\n", daylight_name_.c_str());
|
misc_info_.process_execute_flags);
|
||||||
|
printf(" protected_process = ");
|
||||||
|
PrintValueOrInvalid(misc_info_.flags1 &
|
||||||
|
MD_MISCINFO_FLAGS1_PROTECTED_PROCESS,
|
||||||
|
kNumberFormatDecimal, misc_info_.protected_process);
|
||||||
|
printf(" time_zone_id = ");
|
||||||
|
PrintValueOrInvalid(misc_info_.flags1 & MD_MISCINFO_FLAGS1_TIMEZONE,
|
||||||
|
kNumberFormatDecimal, misc_info_.time_zone_id);
|
||||||
|
if (misc_info_.flags1 & MD_MISCINFO_FLAGS1_TIMEZONE) {
|
||||||
|
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.standard_date = "
|
||||||
|
"%04d-%02d-%02d (%d) %02d:%02d:%02d.%03d\n",
|
||||||
|
misc_info_.time_zone.standard_date.year,
|
||||||
|
misc_info_.time_zone.standard_date.month,
|
||||||
|
misc_info_.time_zone.standard_date.day,
|
||||||
|
misc_info_.time_zone.standard_date.day_of_week,
|
||||||
|
misc_info_.time_zone.standard_date.hour,
|
||||||
|
misc_info_.time_zone.standard_date.minute,
|
||||||
|
misc_info_.time_zone.standard_date.second,
|
||||||
|
misc_info_.time_zone.standard_date.milliseconds);
|
||||||
|
printf(" time_zone.standard_bias = %d\n",
|
||||||
|
misc_info_.time_zone.standard_bias);
|
||||||
|
printf(" time_zone.daylight_name = %s\n", daylight_name_.c_str());
|
||||||
|
printf(" time_zone.daylight_date = "
|
||||||
|
"%04d-%02d-%02d (%d) %02d:%02d:%02d.%03d\n",
|
||||||
|
misc_info_.time_zone.daylight_date.year,
|
||||||
|
misc_info_.time_zone.daylight_date.month,
|
||||||
|
misc_info_.time_zone.daylight_date.day,
|
||||||
|
misc_info_.time_zone.daylight_date.day_of_week,
|
||||||
|
misc_info_.time_zone.daylight_date.hour,
|
||||||
|
misc_info_.time_zone.daylight_date.minute,
|
||||||
|
misc_info_.time_zone.daylight_date.second,
|
||||||
|
misc_info_.time_zone.daylight_date.milliseconds);
|
||||||
|
printf(" time_zone.daylight_bias = %d\n",
|
||||||
|
misc_info_.time_zone.daylight_bias);
|
||||||
|
} else {
|
||||||
|
printf(" time_zone.bias = (invalid)\n");
|
||||||
|
printf(" time_zone.standard_name = (invalid)\n");
|
||||||
|
printf(" time_zone.standard_date = (invalid)\n");
|
||||||
|
printf(" time_zone.standard_bias = (invalid)\n");
|
||||||
|
printf(" time_zone.daylight_name = (invalid)\n");
|
||||||
|
printf(" time_zone.daylight_date = (invalid)\n");
|
||||||
|
printf(" time_zone.daylight_bias = (invalid)\n");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (misc_info_.size_of_info > MD_MISCINFO3_SIZE) {
|
if (misc_info_.size_of_info > MD_MISCINFO3_SIZE) {
|
||||||
// Print version 4 fields
|
// Print version 4 fields
|
||||||
printf(" build_string = %s\n", build_string_.c_str());
|
if (misc_info_.flags1 & MD_MISCINFO_FLAGS1_BUILDSTRING) {
|
||||||
printf(" dbg_bld_str = %s\n", dbg_bld_str_.c_str());
|
printf(" build_string = %s\n", build_string_.c_str());
|
||||||
|
printf(" dbg_bld_str = %s\n", dbg_bld_str_.c_str());
|
||||||
|
} else {
|
||||||
|
printf(" build_string = (invalid)\n");
|
||||||
|
printf(" dbg_bld_str = (invalid)\n");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
printf("\n");
|
printf("\n");
|
||||||
}
|
}
|
||||||
@ -4067,19 +4171,15 @@ void MinidumpBreakpadInfo::Print() {
|
|||||||
|
|
||||||
printf("MDRawBreakpadInfo\n");
|
printf("MDRawBreakpadInfo\n");
|
||||||
printf(" validity = 0x%x\n", breakpad_info_.validity);
|
printf(" validity = 0x%x\n", breakpad_info_.validity);
|
||||||
|
printf(" dump_thread_id = ");
|
||||||
if (breakpad_info_.validity & MD_BREAKPAD_INFO_VALID_DUMP_THREAD_ID) {
|
PrintValueOrInvalid(breakpad_info_.validity &
|
||||||
printf(" dump_thread_id = 0x%x\n", breakpad_info_.dump_thread_id);
|
MD_BREAKPAD_INFO_VALID_DUMP_THREAD_ID,
|
||||||
} else {
|
kNumberFormatHexadecimal, breakpad_info_.dump_thread_id);
|
||||||
printf(" dump_thread_id = (invalid)\n");
|
printf(" requesting_thread_id = ");
|
||||||
}
|
PrintValueOrInvalid(breakpad_info_.validity &
|
||||||
|
MD_BREAKPAD_INFO_VALID_REQUESTING_THREAD_ID,
|
||||||
if (breakpad_info_.validity & MD_BREAKPAD_INFO_VALID_DUMP_THREAD_ID) {
|
kNumberFormatHexadecimal,
|
||||||
printf(" requesting_thread_id = 0x%x\n",
|
breakpad_info_.requesting_thread_id);
|
||||||
breakpad_info_.requesting_thread_id);
|
|
||||||
} else {
|
|
||||||
printf(" requesting_thread_id = (invalid)\n");
|
|
||||||
}
|
|
||||||
|
|
||||||
printf("\n");
|
printf("\n");
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user