Skip site navigation (1)Skip section navigation (2)
Date:      Sat, 23 Feb 2019 08:02:07 -0800
From:      Robert Ayrapetyan <robert.ayrapetyan@gmail.com>
To:        Konstantin Belousov <kostikbel@gmail.com>
Cc:        FreeBSD <freebsd-hackers@freebsd.org>
Subject:   Re: ptrace: SIGTRAP and EXIT race
Message-ID:  <CAAboi9up6FFB-MpTayPCnRczkbqrxqhUi9JONtH6S_hmXeVkOA@mail.gmail.com>
In-Reply-To: <20190223113246.GH2420@kib.kiev.ua>
References:  <CAAboi9tT==FFXdqq9XG2v8Lxf8RBuTMx5ns4puZ-hjD5KecFsA@mail.gmail.com> <20190222101026.GX2420@kib.kiev.ua> <CAAboi9sXhagXE5RTOHiGB9Gs7G1Ruc8CN6VQq5%2BRWJ1VQfJp9Q@mail.gmail.com> <20190223113246.GH2420@kib.kiev.ua>

next in thread | previous in thread | raw e-mail | index | archive | help
raise(SIGSTOP) is not necessary - child stops by itself on the first
instruction after execve.

Let's see what's in these 700 lines of code:

Read\Write memory (this is for Add\Remove breakpoints);
TrapWait (main debugger cycle, handles threads born\destroy);
Init\Launch\Attach - this is all necessary to bootstrap;
GetNumLwps\GetLwpList - misc, you can't work with threads without these;
Step\Continue - self explanatory, you can't reproduce BP issue without
these functions;
GetRegs\SetRegs\GetEip\SetEip - all are needed for handling logic around
BPs.

That's it! There is one more function - EntryPoint, it just retrieves the
entry point from executable, you can ignore it.

If you can do the same using less amount of code (with all error checks in
place) - perfect, but I'm afraid it will not be less than 500 lines. So if
you don't like - just don't do that, no one can force you to lol.

Thanks!

On Sat, Feb 23, 2019 at 3:32 AM Konstantin Belousov <kostikbel@gmail.com>
wrote:

> On Fri, Feb 22, 2019 at 03:57:49PM -0800, Robert Ayrapetyan wrote:
> > 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@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")
> >
>
> ~700 lines of C++ code definitely do not fall under the 'minimal repro'
> spec.  I do not to read all of it.
>
> From looking at Debugger::Launch(), it seems that you missed the
> required debugger/child synchronization for PT_TRACE_ME. Typically child
> does
>         raise(SIGSTOP);
> immediately after PT_TRACE_ME, and the tracer must consume this signal.
> Otherwise the child continues the execution and might just execute the
> place where you intend to set a breakpoint. I may missed the sync (or it
> might be done by other means in your code), because as I said, I do not
> want to read 700 lines of C++.
>
>



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?CAAboi9up6FFB-MpTayPCnRczkbqrxqhUi9JONtH6S_hmXeVkOA>