issue 170 - Report assertion type in minidump_stackwalk output. r=mark at http://breakpad.appspot.com/45001

git-svn-id: http://google-breakpad.googlecode.com/svn/trunk@433 4c0a9323-5329-0410-9bdc-e9ce6186880e
This commit is contained in:
ted.mielczarek
2009-12-02 17:43:57 +00:00
parent 096992fac7
commit 0314e487e4
8 changed files with 248 additions and 1 deletions

View File

@@ -243,6 +243,15 @@ static string* UTF16ToUTF8(const vector<u_int16_t>& in,
return out.release();
}
// Return the smaller of the number of code units in the UTF-16 string,
// not including the terminating null word, or maxlen.
static size_t UTF16codeunits(const u_int16_t *string, size_t maxlen) {
size_t count = 0;
while (count < maxlen && string[count] != 0)
count++;
return count;
}
//
// MinidumpObject
@@ -2768,6 +2777,109 @@ void MinidumpException::Print() {
}
}
//
// MinidumpAssertion
//
MinidumpAssertion::MinidumpAssertion(Minidump* minidump)
: MinidumpStream(minidump),
assertion_(),
expression_(),
function_(),
file_() {
}
MinidumpAssertion::~MinidumpAssertion() {
}
bool MinidumpAssertion::Read(u_int32_t expected_size) {
// Invalidate cached data.
valid_ = false;
if (expected_size != sizeof(assertion_)) {
BPLOG(ERROR) << "MinidumpAssertion size mismatch, " << expected_size <<
" != " << sizeof(assertion_);
return false;
}
if (!minidump_->ReadBytes(&assertion_, sizeof(assertion_))) {
BPLOG(ERROR) << "MinidumpAssertion cannot read assertion";
return false;
}
// Each of {expression, function, file} is a UTF-16 string,
// we'll convert them to UTF-8 for ease of use.
// expression
// Since we don't have an explicit byte length for each string,
// we use UTF16codeunits to calculate word length, then derive byte
// length from that.
u_int32_t word_length = UTF16codeunits(assertion_.expression,
sizeof(assertion_.expression));
if (word_length > 0) {
u_int32_t byte_length = word_length * 2;
vector<u_int16_t> expression_utf16(word_length);
memcpy(&expression_utf16[0], &assertion_.expression[0], byte_length);
scoped_ptr<string> new_expression(UTF16ToUTF8(expression_utf16,
minidump_->swap()));
expression_ = *new_expression;
}
// assertion
word_length = UTF16codeunits(assertion_.function,
sizeof(assertion_.function));
if (word_length) {
u_int32_t byte_length = word_length * 2;
vector<u_int16_t> function_utf16(word_length);
memcpy(&function_utf16[0], &assertion_.function[0], byte_length);
scoped_ptr<string> new_function(UTF16ToUTF8(function_utf16,
minidump_->swap()));
function_ = *new_function;
}
// file
word_length = UTF16codeunits(assertion_.file,
sizeof(assertion_.file));
if (word_length > 0) {
u_int32_t byte_length = word_length * 2;
vector<u_int16_t> file_utf16(word_length);
memcpy(&file_utf16[0], &assertion_.file[0], byte_length);
scoped_ptr<string> new_file(UTF16ToUTF8(file_utf16,
minidump_->swap()));
file_ = *new_file;
}
if (minidump_->swap()) {
Swap(&assertion_.line);
Swap(&assertion_.type);
}
valid_ = true;
return true;
}
void MinidumpAssertion::Print() {
if (!valid_) {
BPLOG(ERROR) << "MinidumpAssertion cannot print invalid data";
return;
}
printf("MDAssertion\n");
printf(" expression = %s\n",
expression_.c_str());
printf(" function = %s\n",
function_.c_str());
printf(" file = %s\n",
file_.c_str());
printf(" line = %u\n",
assertion_.line);
printf(" type = %u\n",
assertion_.type);
printf("\n");
}
//
// MinidumpSystemInfo
@@ -3415,6 +3527,11 @@ MinidumpException* Minidump::GetException() {
return GetStream(&exception);
}
MinidumpAssertion* Minidump::GetAssertion() {
MinidumpAssertion* assertion;
return GetStream(&assertion);
}
MinidumpSystemInfo* Minidump::GetSystemInfo() {
MinidumpSystemInfo* system_info;