ptrace: SIGTRAP and EXIT race

Robert Ayrapetyan robert.ayrapetyan at gmail.com
Fri Feb 22 23:58:27 UTC 2019


Hi, thanks for a prompt reply. Here are the instructions of how to
reproduce (sorry for inconvenient way of specifying BP address when running
app):

uname -a
FreeBSD XXX 12.0-RELEASE-p3 FreeBSD 12.0-RELEASE-p3 GENERIC  amd64

cd /tmp
git clone https://github.com/rayrapetyan/ptrace_bug_poc.git
cd ptrace_bug_poc
mkdir build
cd build
cmake ..
make

Run ~20 times:

/tmp/ptrace_bug_poc/build/src/ptrace_test/ptrace_test
/tmp/ptrace_bug_poc/build/src/mt_example/mt_example 0x201385

-------
Note: make sure 0x201385 is a call to <printf at plt> in
"/tmp/ptrace_bug_poc/build/src/mt_example/mt_example":
gdb /tmp/ptrace_bug_poc/build/src/mt_example/mt_example
disassemble foo
-------

Wait fo appearance of:
"BOOM! Invalid BP hits counter (hits: 1, tid: XXXX)"
at the end of the output (most of the times it will be "SUCCESS")

Thanks.


On Fri, Feb 22, 2019 at 2:10 AM Konstantin Belousov <kostikbel at gmail.com>
wrote:

> On Thu, Feb 21, 2019 at 08:43:20PM -0800, Robert Ayrapetyan wrote:
> > Hello.
> >
> > Before creating a bug and providing some test code, would ask a community
> > here.
> > When tracing a process using ptrace and there are multiple threads in the
> > tracing process hitting the same breakpoint, sometimes main thread exits
> > (WIFEXITED(status) is TRUE) before last queued TRAP_BKPT signal(s) have
> > been delivered to the tracing process. So a final breakpoint hits counter
> > is less than it should be.
> >
> > So in the example below:
> >
> > #include <iostream>
> > #include <thread>
> >
> > #include <pthread_np.h>
> >
> > static const int num_threads = 2;
> >
> > void foo() {
> >     for (int i = 0; i < 2; ++i) {
> >         printf("hi: %d (tid: %d)\n", i, pthread_getthreadid_np());
> >     }
> > }
> >
> > int main() {
> >     std::thread t[num_threads];
> >
> >     for (int i = 0; i < num_threads; ++i) {
> >         t[i] = std::thread(foo);
> >     }
> >
> >     for (int i = 0; i < num_threads; ++i) {
> >         t[i].join();
> >     }
> >
> >     return 0;
> > }
> >
> > If we set breakpoint to printf, it should be triggered 4 times (tracing
> > process should receive TRAP_BKPT 4 times). However, in ~1 of 5 runs, it
> > receives TRAP_BKPT just 2 or 3 times.
> >
> > Is this expected? Thanks.
>
> I indeed would expect that all four breakpoints triggered before the
> main thread exits, assuming that the breakpoints were installed before
> the threads are created.  Please provide the stand-alone (and preferrably
> non-interactive) test to reproduce the issue.
>


More information about the freebsd-hackers mailing list