aboutsummaryrefslogtreecommitdiff
path: root/src/common/stabs_reader_unittest.cc
diff options
context:
space:
mode:
authorjimblandy <jimblandy@4c0a9323-5329-0410-9bdc-e9ce6186880e>2010-05-05 17:34:19 +0000
committerjimblandy <jimblandy@4c0a9323-5329-0410-9bdc-e9ce6186880e>2010-05-05 17:34:19 +0000
commit775c6f7640a02841b667fd6300e877bbed574544 (patch)
tree0d0b83bd37a170951f968aafd1daa6d595f00b8b /src/common/stabs_reader_unittest.cc
parentBreakpad STABS parser: Use a test fixture in StabsReader unit tests. (diff)
downloadbreakpad-775c6f7640a02841b667fd6300e877bbed574544.tar.xz
Breakpad Linux dumper: Handle STABS-in-symbol-table, and line number records outside functions.
This patch addresses two differences between Linux and Macintosh OS X STABS data: - StabsReader assumes that the STABS entries follow the conventions for storing STABS data in object file sections (that is, .stabs and .stabstr), rather than in the object files's linker symbol table. On Mac OS X, STABS entries live in the Mach-O file's LC_SYMTAB load command, along with all the other linker symbols; they are not grouped into units by N_UNDF entries. This patch adds a boolean argument to the StabsReader constructor indicating whether the parser should treat N_UNDF entries as unit boundaries; this argument should be true on Linux, and false on Mac. The patch changes src/common/linux/dump_symbols.cc to pass this new argument. - Mac OS X STABS place SLINE (line number) records immediately before the FUN record for the function to which they belong, and the values of such records are absolute, not relative to the function start. This patch extends the parser to queue up such records and report them to the handler when we do see the FUN record. The meaning of StabsHandler::Line remains unchanged; existing handlers do not need to be adjusted. This patch also adds unit tests for the new parser behaviors. a=jimblandy, r=mark git-svn-id: http://google-breakpad.googlecode.com/svn/trunk@587 4c0a9323-5329-0410-9bdc-e9ce6186880e
Diffstat (limited to 'src/common/stabs_reader_unittest.cc')
-rw-r--r--src/common/stabs_reader_unittest.cc89
1 files changed, 80 insertions, 9 deletions
diff --git a/src/common/stabs_reader_unittest.cc b/src/common/stabs_reader_unittest.cc
index c739bade..9d2f88cc 100644
--- a/src/common/stabs_reader_unittest.cc
+++ b/src/common/stabs_reader_unittest.cc
@@ -31,17 +31,18 @@
// stabs_reader_unittest.cc: Unit tests for google_breakpad::StabsReader.
-#include <cassert>
-#include <cerrno>
-#include <cstdarg>
-#include <cstdlib>
-#include <cstring>
+#include <assert.h>
+#include <errno.h>
+#include <stab.h>
+#include <stdarg.h>
+#include <stdlib.h>
+#include <string.h>
+
#include <fstream>
#include <iomanip>
#include <iostream>
#include <map>
#include <sstream>
-#include <stab.h>
#include "breakpad_googletest_includes.h"
#include "common/stabs_reader.h"
@@ -225,7 +226,7 @@ class MockStabsReaderHandler: public StabsHandler {
};
struct StabsFixture {
- StabsFixture() : stabs(&strings) { }
+ StabsFixture() : stabs(&strings), unitized(true) { }
// Create a StabsReader to parse the mock stabs data in stabs and
// strings, and pass the parsed information to mock_handler. Use the
@@ -244,12 +245,14 @@ struct StabsFixture {
stabs_contents.size(),
reinterpret_cast<const uint8_t *>(stabstr_contents.data()),
stabstr_contents.size(),
- stabs.endianness() == kBigEndian, stabs.value_size(), &mock_handler);
+ stabs.endianness() == kBigEndian, stabs.value_size(), unitized,
+ &mock_handler);
return reader.Process();
}
StringAssembler strings;
StabsAssembler stabs;
+ bool unitized;
MockStabsReaderHandler mock_handler;
};
@@ -401,7 +404,10 @@ TEST_F(Stabs, NoCUEnd) {
ASSERT_TRUE(ApplyHandlerToMockStabsData());
}
-TEST_F(Stabs, MultipleCUs) {
+// On systems that store STABS in sections, string offsets are relative to
+// the beginning of that compilation unit's strings, marked with N_UNDF
+// symbols; see the comments for StabsReader::StabsReader.
+TEST_F(Stabs, Unitized) {
stabs.set_endianness(kBigEndian);
stabs.set_value_size(4);
stabs
@@ -441,6 +447,32 @@ TEST_F(Stabs, MultipleCUs) {
ASSERT_TRUE(ApplyHandlerToMockStabsData());
}
+// On systems that store STABS entries in the real symbol table, the N_UNDF
+// entries have no special meaning, and shouldn't mess up the string
+// indices.
+TEST_F(Stabs, NonUnitized) {
+ stabs.set_endianness(kLittleEndian);
+ stabs.set_value_size(4);
+ unitized = false;
+ stabs
+ .Stab(N_UNDF, 21, 11551, 0x9bad2b2e, "")
+ .Stab(N_UNDF, 21, 11551, 0x9bad2b2e, "")
+ .Stab(N_SO, 71, 45139, 0x11a97352, "Tanzania")
+ .Stab(N_SO, 221, 41976, 0x21a97352, "");
+
+ {
+ InSequence s;
+ EXPECT_CALL(mock_handler,
+ StartCompilationUnit(StrEq("Tanzania"),
+ 0x11a97352, NULL))
+ .WillOnce(Return(true));
+ EXPECT_CALL(mock_handler, EndCompilationUnit(0x21a97352))
+ .WillOnce(Return(true));
+ }
+
+ ASSERT_TRUE(ApplyHandlerToMockStabsData());
+}
+
TEST_F(Stabs, FunctionEnd) {
stabs.set_endianness(kLittleEndian);
stabs.set_value_size(8);
@@ -484,6 +516,45 @@ TEST_F(Stabs, FunctionEnd) {
ASSERT_TRUE(ApplyHandlerToMockStabsData());
}
+// On Mac OS X, SLINE records can appear before the FUN stab to which they
+// belong, and their values are absolute addresses, not offsets.
+TEST_F(Stabs, LeadingLine) {
+ stabs.set_endianness(kBigEndian);
+ stabs.set_value_size(4);
+ stabs
+ .Stab(N_SO, 179, 27357, 0x8adabc15, "build directory/")
+ .Stab(N_SO, 52, 53058, 0x4c7e3bf4, "compilation unit")
+ .Stab(N_SOL, 165, 12086, 0x6a797ca3, "source file name")
+ .Stab(N_SLINE, 229, 20015, 0x4cb3d7e0, "")
+ .Stab(N_SLINE, 89, 43802, 0x4cba8b88, "")
+ .Stab(N_FUN, 251, 51639, 0xce1b98fa, "rutabaga")
+ .Stab(N_FUN, 218, 16113, 0x5798, "")
+ .Stab(N_SO, 52, 53058, 0xd4af4415, "");
+
+ {
+ InSequence s;
+ EXPECT_CALL(mock_handler,
+ StartCompilationUnit(StrEq("compilation unit"),
+ 0x4c7e3bf4, StrEq("build directory/")))
+ .WillOnce(Return(true));
+ EXPECT_CALL(mock_handler,
+ StartFunction(Eq("rutabaga"), 0xce1b98fa))
+ .WillOnce(Return(true));
+ EXPECT_CALL(mock_handler,
+ Line(0x4cb3d7e0, StrEq("source file name"), 20015))
+ .WillOnce(Return(true));
+ EXPECT_CALL(mock_handler,
+ Line(0x4cba8b88, StrEq("source file name"), 43802))
+ .WillOnce(Return(true));
+ EXPECT_CALL(mock_handler, EndFunction(0xce1b98fa + 0x5798))
+ .WillOnce(Return(true));
+ EXPECT_CALL(mock_handler, EndCompilationUnit(0xd4af4415))
+ .WillOnce(Return(true));
+ }
+
+ ASSERT_TRUE(ApplyHandlerToMockStabsData());
+}
+
// name duplication
} // anonymous namespace