mirror of
https://github.com/yuzu-emu/breakpad.git
synced 2024-11-24 07:55:41 +01:00
Fix race in VerifyStackReadWithMultipleThreads
Patch by Chris Dearman <chris@mips.com> R=ted at http://breakpad.appspot.com/377002 git-svn-id: http://google-breakpad.googlecode.com/svn/trunk@959 4c0a9323-5329-0410-9bdc-e9ce6186880e
This commit is contained in:
parent
e8dbecb42c
commit
e6e778f635
@ -51,7 +51,14 @@
|
||||
#endif
|
||||
|
||||
void *thread_function(void *data) {
|
||||
int pipefd = *static_cast<int *>(data);
|
||||
volatile pid_t thread_id = syscall(__NR_gettid);
|
||||
// Signal parent that a thread has started.
|
||||
uint8_t byte = 1;
|
||||
if (write(pipefd, &byte, sizeof(byte)) != sizeof(byte)) {
|
||||
perror("ERROR: parent notification failed");
|
||||
return NULL;
|
||||
}
|
||||
register volatile pid_t *thread_id_ptr asm(TID_PTR_REGISTER) = &thread_id;
|
||||
while (true)
|
||||
asm volatile ("" : : "r" (thread_id_ptr));
|
||||
@ -75,14 +82,8 @@ int main(int argc, char *argv[]) {
|
||||
pthread_attr_init(&thread_attributes);
|
||||
pthread_attr_setdetachstate(&thread_attributes, PTHREAD_CREATE_DETACHED);
|
||||
for (int i = 1; i < num_threads; i++) {
|
||||
pthread_create(&threads[i], &thread_attributes, &thread_function, NULL);
|
||||
pthread_create(&threads[i], &thread_attributes, &thread_function, &pipefd);
|
||||
}
|
||||
// Signal parent that this process has started all threads.
|
||||
uint8_t byte = 1;
|
||||
if (write(pipefd, &byte, sizeof(byte)) != sizeof(byte)) {
|
||||
perror("ERROR: parent notification failed");
|
||||
return 1;
|
||||
}
|
||||
thread_function(NULL);
|
||||
thread_function(&pipefd);
|
||||
return 0;
|
||||
}
|
||||
|
@ -212,7 +212,9 @@ TEST(LinuxPtraceDumperTest, VerifyStackReadWithMultipleThreads) {
|
||||
exit(0);
|
||||
}
|
||||
close(fds[1]);
|
||||
// Wait for the child process to signal that it's ready.
|
||||
|
||||
// Wait for all child threads to indicate that they have started
|
||||
for (int threads = 0; threads < kNumberOfThreadsInHelperProgram; threads++) {
|
||||
struct pollfd pfd;
|
||||
memset(&pfd, 0, sizeof(pfd));
|
||||
pfd.fd = fds[0];
|
||||
@ -222,10 +224,16 @@ TEST(LinuxPtraceDumperTest, VerifyStackReadWithMultipleThreads) {
|
||||
ASSERT_EQ(1, r);
|
||||
ASSERT_TRUE(pfd.revents & POLLIN);
|
||||
uint8_t junk;
|
||||
read(fds[0], &junk, sizeof(junk));
|
||||
ASSERT_EQ(read(fds[0], &junk, sizeof(junk)), sizeof(junk));
|
||||
}
|
||||
close(fds[0]);
|
||||
|
||||
// Child is ready now.
|
||||
// There is a race here because we may stop a child thread before
|
||||
// it is actually running the busy loop. Empirically this sleep
|
||||
// is sufficient to avoid the race.
|
||||
usleep(100000);
|
||||
|
||||
// Children are ready now.
|
||||
LinuxPtraceDumper dumper(child_pid);
|
||||
ASSERT_TRUE(dumper.Init());
|
||||
EXPECT_EQ((size_t)kNumberOfThreadsInHelperProgram, dumper.threads().size());
|
||||
|
Loading…
Reference in New Issue
Block a user