From b68b800189e8b05d9332bcd265f7b75b53863587 Mon Sep 17 00:00:00 2001 From: jimblandy Date: Mon, 29 Mar 2010 18:23:42 +0000 Subject: 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 --- .../linux/minidump_writer/linux_dumper_unittest.cc | 12 ++++++------ .../minidump_writer/linux_dumper_unittest_helper.cc | 17 +++++++++++++---- 2 files changed, 19 insertions(+), 10 deletions(-) (limited to 'src') 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 #include -#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[]) { -- cgit v1.2.1