aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorted.mielczarek <ted.mielczarek@4c0a9323-5329-0410-9bdc-e9ce6186880e>2011-05-06 23:23:31 +0000
committerted.mielczarek <ted.mielczarek@4c0a9323-5329-0410-9bdc-e9ce6186880e>2011-05-06 23:23:31 +0000
commit1807e385d74aba56b2fb61ea570a5f848da224d5 (patch)
tree851a16bfc05c3bc3a7116fcd259bd1b0975b9121 /src
parentFixed message about unregistered msdia*dll. Builds with different DiaSDK need... (diff)
downloadbreakpad-1807e385d74aba56b2fb61ea570a5f848da224d5.tar.xz
Fix linux-gate handling in LinuxDumper so it gets a valid debug ID
A=ted R=nealsid at http://breakpad.appspot.com/284001 git-svn-id: http://google-breakpad.googlecode.com/svn/trunk@788 4c0a9323-5329-0410-9bdc-e9ce6186880e
Diffstat (limited to 'src')
-rw-r--r--src/client/linux/minidump_writer/linux_dumper.cc15
-rw-r--r--src/client/linux/minidump_writer/linux_dumper_unittest.cc79
2 files changed, 92 insertions, 2 deletions
diff --git a/src/client/linux/minidump_writer/linux_dumper.cc b/src/client/linux/minidump_writer/linux_dumper.cc
index 76dc4db4..ab3a5ea5 100644
--- a/src/client/linux/minidump_writer/linux_dumper.cc
+++ b/src/client/linux/minidump_writer/linux_dumper.cc
@@ -213,6 +213,21 @@ LinuxDumper::ElfFileIdentifierForMapping(const MappingInfo& mapping,
if (IsMappedFileOpenUnsafe(mapping))
return false;
+ // Special-case linux-gate because it's not a real file.
+ if (my_strcmp(mapping.name, kLinuxGateLibraryName) == 0) {
+ const uintptr_t kPageSize = getpagesize();
+ void* linux_gate = NULL;
+ if (pid_ == sys_getpid()) {
+ linux_gate = reinterpret_cast<void*>(mapping.start_addr);
+ } else {
+ linux_gate = allocator_.Alloc(kPageSize);
+ CopyFromProcess(linux_gate, pid_,
+ reinterpret_cast<const void*>(mapping.start_addr),
+ kPageSize);
+ }
+ return FileID::ElfFileIdentifierFromMappedFile(linux_gate, identifier);
+ }
+
char filename[NAME_MAX];
size_t filename_len = my_strlen(mapping.name);
assert(filename_len < NAME_MAX);
diff --git a/src/client/linux/minidump_writer/linux_dumper_unittest.cc b/src/client/linux/minidump_writer/linux_dumper_unittest.cc
index c537ce93..1eee9a18 100644
--- a/src/client/linux/minidump_writer/linux_dumper_unittest.cc
+++ b/src/client/linux/minidump_writer/linux_dumper_unittest.cc
@@ -276,6 +276,7 @@ TEST(LinuxDumperTest, BuildProcPath) {
}
#if !defined(__ARM_EABI__)
+// Ensure that the linux-gate VDSO is included in the mapping list.
TEST(LinuxDumperTest, MappingsIncludeLinuxGate) {
LinuxDumper dumper(getpid());
ASSERT_TRUE(dumper.Init());
@@ -297,6 +298,80 @@ TEST(LinuxDumperTest, MappingsIncludeLinuxGate) {
EXPECT_EQ(linux_gate_loc, reinterpret_cast<void*>(mapping->start_addr));
EXPECT_EQ(0, memcmp(linux_gate_loc, ELFMAG, SELFMAG));
}
+
+// Ensure that the linux-gate VDSO can generate a non-zeroed File ID.
+TEST(LinuxDumperTest, LinuxGateMappingID) {
+ LinuxDumper dumper(getpid());
+ ASSERT_TRUE(dumper.Init());
+
+ bool found_linux_gate = false;
+ const wasteful_vector<MappingInfo*> mappings = dumper.mappings();
+ unsigned index = 0;
+ for (unsigned i = 0; i < mappings.size(); ++i) {
+ if (!strcmp(mappings[i]->name, kLinuxGateLibraryName)) {
+ found_linux_gate = true;
+ index = i;
+ break;
+ }
+ }
+ ASSERT_TRUE(found_linux_gate);
+
+ uint8_t identifier[sizeof(MDGUID)];
+ ASSERT_TRUE(dumper.ElfFileIdentifierForMapping(*mappings[index],
+ true,
+ index,
+ identifier));
+ uint8_t empty_identifier[sizeof(MDGUID)];
+ memset(empty_identifier, 0, sizeof(empty_identifier));
+ EXPECT_NE(0, memcmp(empty_identifier, identifier, sizeof(identifier)));
+}
+
+// Ensure that the linux-gate VDSO can generate a non-zeroed File ID
+// from a child process.
+TEST(LinuxDumperTest, LinuxGateMappingIDChild) {
+ int fds[2];
+ ASSERT_NE(-1, pipe(fds));
+
+ // Fork a child so ptrace works.
+ const pid_t child = fork();
+ if (child == 0) {
+ close(fds[1]);
+ // Now wait forever for the parent.
+ char b;
+ HANDLE_EINTR(read(fds[0], &b, sizeof(b)));
+ close(fds[0]);
+ syscall(__NR_exit);
+ }
+ close(fds[0]);
+
+ LinuxDumper dumper(child);
+ ASSERT_TRUE(dumper.Init());
+
+ bool found_linux_gate = false;
+ const wasteful_vector<MappingInfo*> mappings = dumper.mappings();
+ unsigned index = 0;
+ for (unsigned i = 0; i < mappings.size(); ++i) {
+ if (!strcmp(mappings[i]->name, kLinuxGateLibraryName)) {
+ found_linux_gate = true;
+ index = i;
+ break;
+ }
+ }
+ ASSERT_TRUE(found_linux_gate);
+
+ // Need to suspend the child so ptrace actually works.
+ ASSERT_TRUE(dumper.ThreadsSuspend());
+ uint8_t identifier[sizeof(MDGUID)];
+ ASSERT_TRUE(dumper.ElfFileIdentifierForMapping(*mappings[index],
+ true,
+ index,
+ identifier));
+ uint8_t empty_identifier[sizeof(MDGUID)];
+ memset(empty_identifier, 0, sizeof(empty_identifier));
+ EXPECT_NE(0, memcmp(empty_identifier, identifier, sizeof(identifier)));
+ EXPECT_TRUE(dumper.ThreadsResume());
+ close(fds[1]);
+}
#endif
TEST(LinuxDumperTest, FileIDsMatch) {
@@ -311,11 +386,11 @@ TEST(LinuxDumperTest, FileIDsMatch) {
int fds[2];
ASSERT_NE(-1, pipe(fds));
- // fork a child so we can ptrace it
+ // Fork a child so ptrace works.
const pid_t child = fork();
if (child == 0) {
close(fds[1]);
- // now wait forever for the parent
+ // Now wait forever for the parent.
char b;
HANDLE_EINTR(read(fds[0], &b, sizeof(b)));
close(fds[0]);