aboutsummaryrefslogtreecommitdiff
path: root/src/client
diff options
context:
space:
mode:
authorjimblandy <jimblandy@4c0a9323-5329-0410-9bdc-e9ce6186880e>2010-03-29 18:23:42 +0000
committerjimblandy <jimblandy@4c0a9323-5329-0410-9bdc-e9ce6186880e>2010-03-29 18:23:42 +0000
commitb68b800189e8b05d9332bcd265f7b75b53863587 (patch)
tree5737b1c44cbe35f63ff0ab55330fa80634d58a80 /src/client
parentFix HandleInvalidParameter to provide a locally created exception record for ... (diff)
downloadbreakpad-b68b800189e8b05d9332bcd265f7b75b53863587.tar.xz
Breakpad Linux client: Simplify VerifyStackReadWithMultipleThreads unit test.
As written, the VerifyStackReadWithMultipleThreads unit test makes assumptions about the layout of thread_function's stack frame. As a result, the test will fail when compiled with some compilers, or built with certain optimization levels. As an extension to C++, the GNU compilers allow you to request that a variable be placed in a specific register. Using this, we can have thread_function put the thread id in place where the test can find it reliably. a=jimblandy, r=nealsid git-svn-id: http://google-breakpad.googlecode.com/svn/trunk@558 4c0a9323-5329-0410-9bdc-e9ce6186880e
Diffstat (limited to 'src/client')
-rw-r--r--src/client/linux/minidump_writer/linux_dumper_unittest.cc12
-rw-r--r--src/client/linux/minidump_writer/linux_dumper_unittest_helper.cc17
2 files changed, 19 insertions, 10 deletions
diff --git a/src/client/linux/minidump_writer/linux_dumper_unittest.cc b/src/client/linux/minidump_writer/linux_dumper_unittest.cc
index 6f1043c3..da454742 100644
--- a/src/client/linux/minidump_writer/linux_dumper_unittest.cc
+++ b/src/client/linux/minidump_writer/linux_dumper_unittest.cc
@@ -108,16 +108,16 @@ TEST(LinuxDumperTest, VerifyStackReadWithMultipleThreads) {
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.
+ // In the helper program, we stored a pointer to the thread id in a
+ // specific register. Check that we can recover its value.
#if defined(__ARM_EABI__)
- void* process_tid_location = (void *)(one_thread.regs.uregs[11] - 8);
+ pid_t *process_tid_location = (pid_t *)(one_thread.regs.uregs[3]);
#elif defined(__i386)
- void* process_tid_location = (void *)(one_thread.regs.ebp - 4);
+ pid_t *process_tid_location = (pid_t *)(one_thread.regs.ecx);
#elif defined(__x86_64)
- void* process_tid_location = (void *)(one_thread.regs.rbp - 4);
+ pid_t *process_tid_location = (pid_t *)(one_thread.regs.rcx);
#else
-#error Platform not supported!
+#error This test has not been ported to this platform.
#endif
pid_t one_thread_id;
dumper.CopyFromProcess(&one_thread_id,
diff --git a/src/client/linux/minidump_writer/linux_dumper_unittest_helper.cc b/src/client/linux/minidump_writer/linux_dumper_unittest_helper.cc
index f744d72c..388a6580 100644
--- a/src/client/linux/minidump_writer/linux_dumper_unittest_helper.cc
+++ b/src/client/linux/minidump_writer/linux_dumper_unittest_helper.cc
@@ -37,13 +37,22 @@
#include <sys/syscall.h>
#include <unistd.h>
-#pragma GCC optimize ("O0")
-void *thread_function(void *data) __attribute__((noinline, optimize("O2")));
+#if defined(__ARM_EABI__)
+#define TID_PTR_REGISTER "r3"
+#elif defined(__i386)
+#define TID_PTR_REGISTER "ecx"
+#elif defined(__x86_64)
+#define TID_PTR_REGISTER "rcx"
+#else
+#error This test has not been ported to this platform.
+#endif
void *thread_function(void *data) {
pid_t thread_id = syscall(SYS_gettid);
- while (true) ;
- asm("");
+ register pid_t *thread_id_ptr asm(TID_PTR_REGISTER) = &thread_id;
+ while (true)
+ asm("" : : "r" (thread_id_ptr));
+ return NULL;
}
int main(int argc, char *argv[]) {