mirror of
https://github.com/yuzu-emu/breakpad.git
synced 2025-08-03 21:41:01 +00:00
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
This commit is contained in:
parent
18dd9d0104
commit
b68b800189
|
@ -108,16 +108,16 @@ TEST(LinuxDumperTest, VerifyStackReadWithMultipleThreads) {
|
||||||
ThreadInfo one_thread;
|
ThreadInfo one_thread;
|
||||||
for(size_t i = 0; i < dumper.threads().size(); ++i) {
|
for(size_t i = 0; i < dumper.threads().size(); ++i) {
|
||||||
EXPECT_TRUE(dumper.ThreadInfoGet(dumper.threads()[i], &one_thread));
|
EXPECT_TRUE(dumper.ThreadInfoGet(dumper.threads()[i], &one_thread));
|
||||||
// We know the threads are in a function which has allocated exactly
|
// In the helper program, we stored a pointer to the thread id in a
|
||||||
// one word off the stack to store its thread id.
|
// specific register. Check that we can recover its value.
|
||||||
#if defined(__ARM_EABI__)
|
#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)
|
#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)
|
#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
|
#else
|
||||||
#error Platform not supported!
|
#error This test has not been ported to this platform.
|
||||||
#endif
|
#endif
|
||||||
pid_t one_thread_id;
|
pid_t one_thread_id;
|
||||||
dumper.CopyFromProcess(&one_thread_id,
|
dumper.CopyFromProcess(&one_thread_id,
|
||||||
|
|
|
@ -37,13 +37,22 @@
|
||||||
#include <sys/syscall.h>
|
#include <sys/syscall.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
|
|
||||||
#pragma GCC optimize ("O0")
|
#if defined(__ARM_EABI__)
|
||||||
void *thread_function(void *data) __attribute__((noinline, optimize("O2")));
|
#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) {
|
void *thread_function(void *data) {
|
||||||
pid_t thread_id = syscall(SYS_gettid);
|
pid_t thread_id = syscall(SYS_gettid);
|
||||||
while (true) ;
|
register pid_t *thread_id_ptr asm(TID_PTR_REGISTER) = &thread_id;
|
||||||
asm("");
|
while (true)
|
||||||
|
asm("" : : "r" (thread_id_ptr));
|
||||||
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
int main(int argc, char *argv[]) {
|
int main(int argc, char *argv[]) {
|
||||||
|
|
Loading…
Reference in a new issue