ARM support, with some build system changes to support x86-64, arm, and i386 in an autoconf style build in Linux. The O2 build for the unit tests is still broken but I'm checking this in to unblock people
A=nealsid
R=ajwong, hannahtang, ted.mielczarek
git-svn-id: http://google-breakpad.googlecode.com/svn/trunk@541 4c0a9323-5329-0410-9bdc-e9ce6186880e
diff --git a/src/client/linux/minidump_writer/linux_dumper_unittest.cc b/src/client/linux/minidump_writer/linux_dumper_unittest.cc
index e060e53..6f1043c 100644
--- a/src/client/linux/minidump_writer/linux_dumper_unittest.cc
+++ b/src/client/linux/minidump_writer/linux_dumper_unittest.cc
@@ -29,10 +29,13 @@
#include <limits.h>
#include <unistd.h>
+#include <signal.h>
+#include <sys/types.h>
+#include "breakpad_googletest_includes.h"
#include "client/linux/minidump_writer/linux_dumper.h"
#include "common/linux/file_id.h"
-#include "breakpad_googletest_includes.h"
+#include "common/linux/memory.h"
using namespace google_breakpad;
@@ -67,7 +70,7 @@
LinuxDumper dumper(getpid());
ASSERT_TRUE(dumper.Init());
- ASSERT_GE(dumper.threads().size(), 1);
+ ASSERT_GE(dumper.threads().size(), (size_t)1);
bool found = false;
for (size_t i = 0; i < dumper.threads().size(); ++i) {
if (dumper.threads()[i] == getpid()) {
@@ -77,6 +80,55 @@
}
}
+TEST(LinuxDumperTest, VerifyStackReadWithMultipleThreads) {
+ static const int kNumberOfThreadsInHelperProgram = 5;
+ char kNumberOfThreadsArgument[2];
+ sprintf(kNumberOfThreadsArgument, "%d", kNumberOfThreadsInHelperProgram);
+
+ pid_t child_pid = fork();
+ if (child_pid == 0) {
+ // Set the number of threads
+ execl("src/client/linux/linux_dumper_unittest_helper",
+ "linux_dumper_unittest_helper",
+ kNumberOfThreadsArgument,
+ NULL);
+ // Kill if we get here.
+ printf("Errno from exec: %d", errno);
+ FAIL() << "Exec failed: " << strerror(errno);
+ exit(0);
+ }
+ // The sleep is flaky, but prevents us from reading
+ // the child process before all threads have been created.
+ sleep(1);
+ LinuxDumper dumper(child_pid);
+ EXPECT_TRUE(dumper.Init());
+ EXPECT_EQ((size_t)kNumberOfThreadsInHelperProgram, dumper.threads().size());
+ EXPECT_TRUE(dumper.ThreadsSuspend());
+
+ ThreadInfo one_thread;
+ for(size_t i = 0; i < dumper.threads().size(); ++i) {
+ EXPECT_TRUE(dumper.ThreadInfoGet(dumper.threads()[i], &one_thread));
+ // We know the threads are in a function which has allocated exactly
+ // one word off the stack to store its thread id.
+#if defined(__ARM_EABI__)
+ void* process_tid_location = (void *)(one_thread.regs.uregs[11] - 8);
+#elif defined(__i386)
+ void* process_tid_location = (void *)(one_thread.regs.ebp - 4);
+#elif defined(__x86_64)
+ void* process_tid_location = (void *)(one_thread.regs.rbp - 4);
+#else
+#error Platform not supported!
+#endif
+ pid_t one_thread_id;
+ dumper.CopyFromProcess(&one_thread_id,
+ dumper.threads()[i],
+ process_tid_location,
+ 4);
+ EXPECT_EQ(dumper.threads()[i], one_thread_id);
+ }
+ kill(child_pid, SIGKILL);
+}
+
TEST(LinuxDumperTest, BuildProcPath) {
const pid_t pid = getpid();
LinuxDumper dumper(pid);
@@ -106,28 +158,29 @@
#endif
}
+#if !defined(__ARM_EABI__)
TEST(LinuxDumperTest, MappingsIncludeLinuxGate) {
LinuxDumper dumper(getpid());
ASSERT_TRUE(dumper.Init());
void* linux_gate_loc = dumper.FindBeginningOfLinuxGateSharedLibrary(getpid());
- if (linux_gate_loc) {
- bool found_linux_gate = false;
+ ASSERT_TRUE(linux_gate_loc);
+ bool found_linux_gate = false;
- const wasteful_vector<MappingInfo*> mappings = dumper.mappings();
- const MappingInfo* mapping;
- for (unsigned i = 0; i < mappings.size(); ++i) {
- mapping = mappings[i];
- if (!strcmp(mapping->name, kLinuxGateLibraryName)) {
- found_linux_gate = true;
- break;
- }
+ const wasteful_vector<MappingInfo*> mappings = dumper.mappings();
+ const MappingInfo* mapping;
+ for (unsigned i = 0; i < mappings.size(); ++i) {
+ mapping = mappings[i];
+ if (!strcmp(mapping->name, kLinuxGateLibraryName)) {
+ found_linux_gate = true;
+ break;
}
- EXPECT_TRUE(found_linux_gate);
- EXPECT_EQ(linux_gate_loc, reinterpret_cast<void*>(mapping->start_addr));
- EXPECT_EQ(0, memcmp(linux_gate_loc, ELFMAG, SELFMAG));
}
+ EXPECT_TRUE(found_linux_gate);
+ EXPECT_EQ(linux_gate_loc, reinterpret_cast<void*>(mapping->start_addr));
+ EXPECT_EQ(0, memcmp(linux_gate_loc, ELFMAG, SELFMAG));
}
+#endif
TEST(LinuxDumperTest, FileIDsMatch) {
// Calculate the File ID of our binary using both