From owner-freebsd-hackers@FreeBSD.ORG Thu Apr 29 23:49:34 2010 Return-Path: Delivered-To: freebsd-hackers@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [69.147.83.52]) by hub.freebsd.org (Postfix) with ESMTP id 40DF71065673 for ; Thu, 29 Apr 2010 23:49:34 +0000 (UTC) (envelope-from tomtinn@gmail.com) Received: from mail-ww0-f54.google.com (mail-ww0-f54.google.com [74.125.82.54]) by mx1.freebsd.org (Postfix) with ESMTP id 42A398FC0A for ; Thu, 29 Apr 2010 23:49:33 +0000 (UTC) Received: by wwb13 with SMTP id 13so971175wwb.13 for ; Thu, 29 Apr 2010 16:49:27 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=gamma; h=domainkey-signature:mime-version:received:received:in-reply-to :references:date:message-id:subject:from:to:content-type :content-transfer-encoding; bh=+ddJdL3mWG8BY0/es78ObjKflD/6syy21oxLj4XtdeI=; b=McXeeKITURjqVIxzcwXF1KV+qYbZsXfhAkzdyiXCPNjBbQCSi4v0tV4W6jRp9+7pHQ +1QlZgTOa22XTtXFZl71aINaYMd4SJo8u9wrIaYyyWQXIyL6zWgG2/GCgqCLCCeNj5Aa tnynSkl+FMrYyZtdQDGriFaWOwdjJWMvq5i2w= DomainKey-Signature: a=rsa-sha1; c=nofws; d=gmail.com; s=gamma; h=mime-version:in-reply-to:references:date:message-id:subject:from:to :content-type:content-transfer-encoding; b=suHuz4wlR+qPtJkE6gsF2jx10+TGk1mzm80mZ34YKENsWSRtmL512NJ9HWrghHutxk C0r9QcziNL92EZFjOytMw8p7HdtVcTN8YArsbjfZJmJhfDHZnp1sxjNvSYi6tSJTQju5 iLKzsGDkO2nmj1HgMcQIJH6DtI5bNlpujS6JQ= MIME-Version: 1.0 Received: by 10.216.90.69 with SMTP id d47mr742058wef.198.1272584966702; Thu, 29 Apr 2010 16:49:26 -0700 (PDT) Received: by 10.216.166.16 with HTTP; Thu, 29 Apr 2010 16:49:26 -0700 (PDT) In-Reply-To: References: <9EF83DA6-B2D3-456E-B0AF-0B4F5F458A1F@gid.co.uk> Date: Thu, 29 Apr 2010 23:49:26 +0000 Message-ID: From: Gunnar Hinriksson To: freebsd-hackers@freebsd.org Content-Type: text/plain; charset=ISO-8859-1 Content-Transfer-Encoding: quoted-printable Subject: Re: Ptrace segfault X-BeenThere: freebsd-hackers@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: Technical Discussions relating to FreeBSD List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Thu, 29 Apr 2010 23:49:34 -0000 2010/4/29 Gunnar Hinriksson : > 2010/4/29 Gunnar Hinriksson : >> 2010/4/29 Bob Bishop : >>> Hi, >>> >>> On 29 Apr 2010, at 22:37, Garrett Cooper wrote: >>> >>>> On Thu, Apr 29, 2010 at 12:06 PM, Gunnar Hinriksson wrote: >>>>> Hello >>>>> >>>>> Im having a little problem using ptrace on my system. >>>>> If I use ptrace to attach to another process the child process >>>>> segfaults once I detach. >>>>> For example using this simple program. >>>>> >>>>> #include >>>>> #include >>>>> #include >>>>> #include >>>>> #include >>>>> >>>>> int main(int argc, char *argv[]) >>>>> { >>>>> =A0 =A0 =A0 =A0int pid =3D atoi(argv[1]); >>>>> =A0 =A0 =A0 =A0ptrace(PT_ATTACH, pid, 0, 0); >>>>> =A0 =A0 =A0 =A0wait(NULL); >>>>> =A0 =A0 =A0 =A0ptrace(PT_DETACH, pid, 0, 0); >>>>> =A0 =A0 =A0 =A0return 0; >>>>> } >>>>> >>>>> Am I using ptrace incorrectly or is there perhaps a bug in ptrace tha= t >>>>> causes the child to always segfault ? >>>> >>>> =A0 =A0Nope -- it's a bug in your code. From ptrace(2): >>>> >>>> =A0 =A0 PT_CONTINUE =A0 The traced process continues execution. =A0The= addr argument >>>> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 is an address specifying the place= where execution is to be >>>> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 resumed (a new value for the progr= am counter), or >>>> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 (caddr_t)1 to indicate that execut= ion is to pick up where >>>> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 it left off. =A0The data argument = provides a signal number to >>>> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 be delivered to the traced process= as it resumes execution, >>>> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 or 0 if no signal is to be sent. >>>> >>>> [...] >>>> >>>> =A0 =A0 PT_DETACH =A0 =A0 This request is like PT_CONTINUE, except tha= t it does not >>> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0= =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 ^^^^^^^^^^^ >>>> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 allow specifying an alternate plac= e to continue execution, >>> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^= ^^^^^^^^^^^^^^^^^^^^^^ >>>> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 and after it succeeds, the traced = process is no longer >>>> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 traced and continues execution nor= mally. >>>> >>>> =A0 =A0Note very carefully the fact that PT_DETACH is like PT_CONTINUE= , >>>> and that PT_CONTINUE says that addr references the memory where the >>>> execution is going to be resumed. >>> >>> Looks to me like a bug in ptrace(PT_DETACH,...) which to agree with ptr= ace(2) ought either to >>> (a) fail (EINVAL?) if addr !=3D (caddr_t)1, or >>> (b) ignore addr entirely; it's not clear which. >>> >>> OP inferred (b) which is reasonable. >>> >>>> HTH, >>>> -Garrett >>>> _______________________________________________ >>>> freebsd-hackers@freebsd.org mailing list >>>> http://lists.freebsd.org/mailman/listinfo/freebsd-hackers >>>> To unsubscribe, send any mail to "freebsd-hackers-unsubscribe@freebsd.= org" >>>> >>>> >>> >>> >>> -- >>> Bob Bishop =A0 =A0 =A0 =A0 =A0+44 (0)118 940 1243 >>> rb@gid.co.uk =A0 =A0fax +44 (0)118 940 1295 >>> =A0 =A0 =A0 =A0 =A0 =A0 mobile +44 (0)783 626 4518 >>> >>> >>> >>> >>> >>> >> >> Hello >> >> I didn't want to make the code to big so I omitted any tests. >> About wait(), you are supposed to use wait to check if the child >> process has stopped successfully. >> I guess the correct usage would be something like this if im >> understanding the documentation correctly. >> if ( wait(WIFSTOPPED(SIGSTOP)) =3D=3D pid ) >> Im not sure if there is any posix way of describing how ptrace should >> be implemented but I know linux ptrace ignores the addr on DETACH. >> So my vote would be that ptrace ignores addr on detach to make it >> compatible with code for linux. >> >> With Regards >> >> Gunnar >> > > Hello > > I started looking around in the kernel sources and I think i've found > out how it is implemented. > in /usr/src/sys/kern/sys_process.c line 744 the following code is found. > > if (addr !=3D (void *)1) { > =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0error =3D ptrace_set_pc(td= 2, (u_long)(uintfptr_t)addr); > =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0if (error) > =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0break; > =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0} > > So it is changing the address if the addr is anything but 1. > I tested my program by passing 1 as an argument in the addr field and > the segfaults stopped. > > So the question is if this code should be removed so that PT_DETACH > ignores addr or leave it be and perhaps update the documentation to > reflect that it allows the addr to the changed. > > With Regards > > Gunnar > After reading the code more carefully the correct way would be to modify it like this. --- case PT_CONTINUE: { if (addr !=3D (void *)1) { error =3D ptrace_set_pc(td2, (u_long)(uintfptr_t)ad= dr); } } if (error) break; --- Note that im just learning programming so this might not be the correct way to do it. With Regards Gunnar