From: asami@cs.berkeley.edu
Subject: Re: ptrace(20, pid...) doesn't work
Originator: asami@adder.cs.Berkeley.EDU
Reply-To: asami@snake.cs.berkeley.edu
Organization: University of California, at Berkeley
	<ASAMI.92Nov10230226@moccasin.cs.Berkeley.EDU>
	<1992Nov11.143423.23743@prl.dec.com>
Date: Thu, 12 Nov 1992 01:51:27 GMT

In article <1992Nov11.143423.23743@prl.dec.com>
        boyd@prl.dec.com (Boyd Roberts) writes:

 * >  * Um, how about a ptrace(0, ...) call in the child?
 * > 
 * > Hmmm....it worked!  Thanks.  By the way, was I missing something, or
 * > is it just an undocumented feature (read: bug :).
 * > 
 * 
 * No it's always worked that.  Slight case of RTM.

Err, sorry.  I was trying to ask to why ptrace(20, ...) doesn't work---
I know that ptrace(0, ...) is in the manual.  I guess I have to improve
my Englisch.

By the way, on a side note, it seems to me that requests larger than
or equal to 20 don't work at all.  Is this a disabled feature or
something?  Following is an example of 28 (detach child).  According
to the manual, EIO means (probably) the request code is invalid.

--
                                                   o o   Satoshi Asami
  Form follows Function.                            ^
                                               (asami@CS.Berkeley.EDU)
  Tel: (510)643-2730 (home)       Computer Science Div., Dept. of EECS
       (510)643-6228 (office)     University of California at Berkeley
---
Sample run:
---
% ptrace xeyes
stopped child...
detaching child....
error: ptrace 28, 28352, 1, 0 => -1 5 ("I/O error")
%
---
Source file:
---
/* ptrace.c: ptrace test program */

#include <stdio.h>
#include <signal.h>
#include <sys/ptrace.h>
#include <sys/wait.h>
#include <sys/types.h>
#include <unistd.h>
#include <errno.h>
#include <string.h>

#define OK      0

#define DEBUG   0

int ptrace(int, int, int *, int) ;
int xptrace(int, int, int *, int) ;

void causeandinfo(int) ;

#define P_C (PC)
#define TRAP_CAUSE (TRAPCAUSE)
#define TRAP_INFO (TRAPINFO)

int debug = DEBUG ;

int main(int argc, char **argv)
{
    pid_t       pid ;

    if (argc < 2)       {
        fprintf(stderr, "usage: %s prog [args...]\n", argv[0]) ;
        exit(1) ;
    }

    if (!strncmp(argv[1], "-d", 2))     {
        debug = 1 ;
        argv++ ;
        argc-- ;
    }

    if ((pid = fork()) == -1)   {
        fprintf(stderr, "panic: can't fork()\n") ;
        exit(2) ;
    }

    if (pid == 0)       {
        argv++ ;
        if (xptrace(PT_TRACE_ME, 0, NULL, 0) == -1)
            exit(4) ;
        printf("stopped child...\n") ;
        execvp(argv[0], argv) ;
        fprintf(stderr, "panic: can't exec()\n") ;
        exit(3) ;
    }

    sleep(5) ;

    printf("detaching child....\n") ;
    xptrace(28, pid, (int *)1, 0) ;

    sleep(5) ;

    return (OK) ;
}

int     xptrace(int request, int pid, int *addr, int data)
{
    int retval ;

    retval = ptrace(request, pid, addr, data) ;
    if (retval == -1)
        fprintf(stderr, "error: ptrace %d, %d, %x, %d => %d %d (\"%s\")\n",
                request, pid, (unsigned int)addr, data, retval, errno,
                strerror(errno)) ;
    else if (debug)
        fprintf(stderr, "debug: ptrace %d, %d, %x, %d\n",
                request, pid, (unsigned int)addr, data) ;

    return (retval) ;
}