issue-481: Replaced test mechanism for distinct address spaces with a more reliable mechanism

Rather than using sys_ptrace+PTRACE_PEEK_DATA to determine whether address spaces are distinct, we now use sys_waitpid+__WCLONE. See issue-481 for a more detailed rationale.


git-svn-id: http://gperftools.googlecode.com/svn/trunk@167 6b5cf1ce-ec42-a296-1ba9-69fdba395a50
This commit is contained in:
chappedm@gmail.com 2012-11-03 14:52:42 +00:00
parent 6c43620352
commit 5dd53ab6cb
1 changed files with 20 additions and 20 deletions

View File

@ -408,7 +408,7 @@ static void ListerThread(struct ListerParams *args) {
/* Check if the marker is identical to the one we created */
if (sys_stat(fname, &tmp_sb) >= 0 &&
marker_sb.st_ino == tmp_sb.st_ino) {
long i, j;
long i;
/* Found one of our threads, make sure it is no duplicate */
for (i = 0; i < num_threads; i++) {
@ -444,28 +444,28 @@ static void ListerThread(struct ListerParams *args) {
sig_num_threads = num_threads;
goto next_entry;
}
while (sys_waitpid(pid, (int *)0, __WALL) < 0) {
/* Attaching to a process doesn't guarantee it'll stop before
* ptrace returns; you have to wait on it. Specifying __WCLONE
* means it will only wait for clone children (i.e. threads,
* not processes).
*/
while (sys_waitpid(pid, (int *)0, __WCLONE) < 0) {
if (errno != EINTR) {
sys_ptrace_detach(pid);
num_threads--;
sig_num_threads = num_threads;
goto next_entry;
/* Assumes ECHILD */
if (pid == ppid) {
/* The parent is not a clone */
found_parent = true;
break;
} else {
sys_ptrace_detach(pid);
num_threads--;
sig_num_threads = num_threads;
goto next_entry;
}
}
}
if (sys_ptrace(PTRACE_PEEKDATA, pid, &i, &j) || i++ != j ||
sys_ptrace(PTRACE_PEEKDATA, pid, &i, &j) || i != j) {
/* Address spaces are distinct, even though both
* processes show the "marker". This is probably
* a forked child process rather than a thread.
*/
sys_ptrace_detach(pid);
num_threads--;
sig_num_threads = num_threads;
} else {
found_parent |= pid == ppid;
added_entries++;
}
added_entries++;
}
}
}