diff options
author | Aliaksey Kandratsenka <alk@tut.by> | 2013-08-04 20:44:06 +0300 |
---|---|---|
committer | Aliaksey Kandratsenka <alk@tut.by> | 2013-08-17 19:17:27 +0300 |
commit | 313e08b5a1a951f710b0323b3ca4e1e8d869520e (patch) | |
tree | b31eb11129f413d40b6385b87fb732d7cf6ccceb | |
parent | 6d00cbce92c5576b4bcf07a2b5634b4dcfa14f8a (diff) | |
download | gperftools-313e08b5a1a951f710b0323b3ca4e1e8d869520e.tar.gz |
issue-560: Revert "issue-481: ...
...Replaced test mechanism for distinct address spaces with a more
reliable mechanism"
This reverts commit 5dd53ab6cbf9d98f2d60546835e84785a104da46 (svn
revision 167)
With this commit rhel 6.2 fails heap-checker-death_unittest and
without it passes.
Ticket refers to 2 things and both are invalid:
* that ptrace PEEKDATA ignores data argument. I've checked kernel
source and found it to be wrong
* something about distinct address spaces
And in addition to all that original ticket admits that it doesn't fix
anything.
It looks like, compared to original code that "fix" is not succesfully
wait-ing on parent's ptrace request. I.e. by adding some additional
diagnostics I'm seeing this sys_waitpid returning ECHILD.
-rw-r--r-- | src/base/linuxthreads.cc | 38 |
1 files changed, 19 insertions, 19 deletions
diff --git a/src/base/linuxthreads.cc b/src/base/linuxthreads.cc index ba4d1c8..47bb011 100644 --- a/src/base/linuxthreads.cc +++ b/src/base/linuxthreads.cc @@ -416,7 +416,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; + long i, j; /* Found one of our threads, make sure it is no duplicate */ for (i = 0; i < num_threads; i++) { @@ -452,28 +452,28 @@ static void ListerThread(struct ListerParams *args) { sig_num_threads = num_threads; goto next_entry; } - /* 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) { + while (sys_waitpid(pid, (int *)0, __WALL) < 0) { if (errno != EINTR) { - /* 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; - } + sys_ptrace_detach(pid); + num_threads--; + sig_num_threads = num_threads; + goto next_entry; } } - added_entries++; + 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++; + } } } } |