aboutsummaryrefslogtreecommitdiff
path: root/src/processor/minidump.cc
diff options
context:
space:
mode:
authorted.mielczarek <ted.mielczarek@4c0a9323-5329-0410-9bdc-e9ce6186880e>2009-12-02 17:43:57 +0000
committerted.mielczarek <ted.mielczarek@4c0a9323-5329-0410-9bdc-e9ce6186880e>2009-12-02 17:43:57 +0000
commit0314e487e46a45229e275eb78b09f0538a5a7769 (patch)
treee8703a4ed915335696767a5ae3362effd5940f45 /src/processor/minidump.cc
parentUpstreaming several patches from Chrome: (diff)
downloadbreakpad-0314e487e46a45229e275eb78b09f0538a5a7769.tar.xz
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
Diffstat (limited to 'src/processor/minidump.cc')
-rw-r--r--src/processor/minidump.cc117
1 files changed, 117 insertions, 0 deletions
diff --git a/src/processor/minidump.cc b/src/processor/minidump.cc
index cd6da170..ab4e4286 100644
--- a/src/processor/minidump.cc
+++ b/src/processor/minidump.cc
@@ -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;