home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 January / usenetsourcesnewsgroupsinfomagicjanuary1994.iso / sources / sun / volume3 / strace / part03 / process.c < prev    next >
Encoding:
C/C++ Source or Header  |  1992-03-02  |  12.4 KB  |  579 lines

  1. /*
  2.  * @(#)process.c    2.3 92/01/10
  3.  */
  4.  
  5. #include <stdio.h>
  6. #include <string.h>
  7. #include <stdlib.h>
  8. #include <sys/types.h>
  9. #include <sys/ptrace.h>
  10. #include <sys/file.h>
  11. #include <sys/stat.h>
  12. #include <sys/time.h>
  13. #include <sys/wait.h>
  14. #include <sys/resource.h>
  15. #include <sys/utsname.h>
  16. #include <sys/ptrace.h>
  17. #include <sys/user.h>
  18. #include <machine/reg.h>
  19.  
  20. #include "defs.h"
  21.  
  22. int
  23. sys_gethostid(tcp)
  24. struct tcb *tcp;
  25. {
  26.     if (exiting(tcp)) {
  27.         return RVAL_HEX;
  28.     }
  29.     return 0;
  30. }
  31.  
  32. int
  33. sys_sethostname(tcp)
  34. struct tcb *tcp;
  35. {
  36.     if (entering(tcp)) {
  37.         (void)printstr(tcp->pid, tcp->u_args[0], -1);
  38.         tprintf(", %u", tcp->u_args[1]);
  39.     }
  40.     return 0;
  41. }
  42.  
  43. int
  44. sys_gethostname(tcp)
  45. struct tcb *tcp;
  46. {
  47.     if (exiting(tcp)) {
  48.         if (syserror(tcp))
  49.             tprintf("%#x", tcp->u_args[0]);
  50.         else
  51.             (void)printstr(tcp->pid, tcp->u_args[0], -1);
  52.         tprintf(", %u", tcp->u_args[1]);
  53.     }
  54.     return 0;
  55. }
  56.  
  57. int
  58. sys_getpid(tcp)
  59. struct tcb *tcp;
  60. {
  61.     static char ppid[16];
  62.  
  63.     if (exiting(tcp)) {
  64.         (void)sprintf(ppid, "[ppid: %u]", getrval2(tcp->pid));
  65.         tcp->auxstr = ppid;
  66.         return RVAL_STR;
  67.     }
  68.     return 0;
  69. }
  70.  
  71. int
  72. sys_setdomainname(tcp)
  73. struct tcb *tcp;
  74. {
  75.     if (entering(tcp)) {
  76.         (void)printstr(tcp->pid, tcp->u_args[0], -1);
  77.         tprintf(", %u", tcp->u_args[1]);
  78.     }
  79.     return 0;
  80. }
  81.  
  82. int
  83. sys_getdomainname(tcp)
  84. struct tcb *tcp;
  85. {
  86.     if (exiting(tcp)) {
  87.         if (syserror(tcp))
  88.             tprintf("%#x", tcp->u_args[0]);
  89.         else
  90.             (void)printstr(tcp->pid, tcp->u_args[0], -1);
  91.         tprintf(", %u", tcp->u_args[1]);
  92.     }
  93.     return 0;
  94. }
  95.  
  96. int
  97. sys_rexit(tcp)
  98. struct tcb *tcp;
  99. {
  100.     if (exiting(tcp)) {
  101.         (void)fprintf(stderr, "rexit returned!!\n");
  102.         return -1;
  103.     }
  104.     /* special case: we stop tracing this process, finish line now */
  105.     tprintf("%d) = ?\n", tcp->u_args[0]);
  106.     tcp->flags |= TCB_EXITING;
  107.     return 0;
  108. }
  109.  
  110. static int vforking;
  111.  
  112. int
  113. sys_fork(tcp)
  114. struct tcb *tcp;
  115. {
  116.     int pid;
  117.     struct tcb *tcpchild;
  118.  
  119.     if (entering(tcp)) {
  120.         if (!followfork || vforking)
  121.             return 0;
  122.         if (setbpt(tcp) < 0)
  123.             return 0;
  124.     } else {
  125.         int bpt = tcp->flags & TCB_BPTSET;
  126.  
  127.         if (!followfork)
  128.             return 0;
  129.         if (bpt)
  130.             (void)clearbpt(tcp);
  131.  
  132.         if (syserror(tcp))
  133.             return 0;
  134.  
  135.         pid = tcp->u_rval;
  136.         if ((tcpchild = alloctcb(pid)) == NULLTCB) {
  137.             (void)fprintf(stderr, " [tcb table full]\n");
  138.             (void)kill(pid, SIGKILL);
  139.             return -1;
  140.         }
  141.         if (ptrace(PTRACE_ATTACH, pid, (char *)1, 0) < 0) {
  142.             perror("PTRACE_ATTACH");
  143.             (void)fprintf(stderr, " - Too late?\n");
  144.             droptcb(tcpchild);
  145.             return 0;
  146.         }
  147.         tcpchild->flags |= TCB_ATTACHED;
  148.         /* Child has BPT too, must be removed on first occasion */
  149.         if (bpt) {
  150.             tcpchild->flags |= TCB_BPTSET;
  151.             tcpchild->baddr = tcp->baddr;
  152.             bcopy((char *)tcp->inst, (char *)tcpchild->inst,
  153.                             sizeof tcpchild->inst);
  154.         }
  155.         newoutf(tcpchild);
  156.         tcpchild->parent = tcp;
  157.         tcp->nchildren++;
  158.         (void)fprintf(stderr, "Process %u attached\n", pid);
  159.     }
  160.     return 0;
  161. }
  162.  
  163. int
  164. sys_vfork(tcp)
  165. struct tcb *tcp;
  166. {
  167.     /* XXX - cannot use the same trick for vfork */
  168.     int res;
  169.  
  170.     vforking = 1;
  171.     res = sys_fork(tcp);
  172.     vforking = 0;
  173.     return res;
  174. }
  175.  
  176. static char eid[16];
  177.  
  178. int
  179. sys_getuid(tcp)
  180. struct tcb *tcp;
  181. {
  182.     if (exiting(tcp)) {
  183.         (void)sprintf(eid, "[euid %u]", getrval2(tcp->pid));
  184.         tcp->auxstr = eid;
  185.         return RVAL_STR;
  186.     }
  187.     return 0;
  188. }
  189.  
  190. int
  191. sys_getgid(tcp)
  192. struct tcb *tcp;
  193. {
  194.     if (exiting(tcp)) {
  195.         (void)sprintf(eid, "[egid %u]", getrval2(tcp->pid));
  196.         tcp->auxstr = eid;
  197.         return RVAL_STR;
  198.     }
  199.     return 0;
  200. }
  201.  
  202. int
  203. sys_setreuid(tcp)
  204. struct tcb *tcp;
  205. {
  206.     if (entering(tcp)) {
  207.         tprintf("%u, %u", tcp->u_args[0], tcp->u_args[1]);
  208.     }
  209.     return 0;
  210. }
  211.  
  212. int
  213. sys_setregid(tcp)
  214. struct tcb *tcp;
  215. {
  216.     if (entering(tcp)) {
  217.         tprintf("%u, %u", tcp->u_args[0], tcp->u_args[1]);
  218.     }
  219.     return 0;
  220. }
  221.  
  222. int
  223. sys_setgroups(tcp)
  224. struct tcb *tcp;
  225. {
  226.     int i, len, *gidset;
  227.  
  228.     if (entering(tcp)) {
  229.         len = tcp->u_args[0];
  230.         tprintf("%u, ", len);
  231.         if ((gidset = (int *)malloc((unsigned)len * sizeof(int))) == NULL) {
  232.             (void)fprintf(stderr, " [Out of memory]\n");
  233.             return -1;
  234.         }
  235.         if (umove(tcp->pid, tcp->u_args[1],
  236.                 len * sizeof(int), (char *)gidset) < 0) {
  237.             tprintf("%#x", tcp->u_args[1]);
  238.         } else {
  239.             tprintf("[");
  240.             for (i = 0; i < len; i++)
  241.                 tprintf(" %u", gidset[i]);
  242.             tprintf("]", gidset[i]);
  243.         }
  244.         free((char *)gidset);
  245.     }
  246.     return 0;
  247. }
  248.  
  249. int
  250. sys_getgroups(tcp)
  251. struct tcb *tcp;
  252. {
  253.     int i, len, *gidset;
  254.  
  255.     if (entering(tcp)) {
  256.         len = tcp->u_args[0];
  257.         tprintf("%u, ", len);
  258.     } else {
  259.         len = tcp->u_rval;
  260.         if ((gidset = (int *)malloc((unsigned)len * sizeof(int))) == NULL) {
  261.             (void)fprintf(stderr, " [Out of memory]\n");
  262.             return -1;
  263.         }
  264.         if (umove(tcp->pid, tcp->u_args[1],
  265.                 len * sizeof(int), (char *)gidset) < 0) {
  266.             tprintf("%#x", tcp->u_args[1]);
  267.         } else {
  268.             tprintf("[");
  269.             for (i = 0; i < len; i++)
  270.                 tprintf(" %u", gidset[i]);
  271.             tprintf("]", gidset[i]);
  272.         }
  273.         free((char *)gidset);
  274.     }
  275.     return 0;
  276. }
  277.  
  278. int
  279. sys_setpgrp(tcp)
  280. struct tcb *tcp;
  281. {
  282.     if (entering(tcp)) {
  283.         tprintf("%u, %u", tcp->u_args[0], tcp->u_args[1]);
  284.     }
  285.     return 0;
  286. }
  287.  
  288. int
  289. sys_getpgrp(tcp)
  290. struct tcb *tcp;
  291. {
  292.     if (entering(tcp)) {
  293.         tprintf("%u", tcp->u_args[0]);
  294.     }
  295.     return 0;
  296. }
  297.  
  298. int
  299. sys_setpgid(tcp)
  300. struct tcb *tcp;
  301. {
  302.     if (entering(tcp)) {
  303.         tprintf("%u, %u", tcp->u_args[0], tcp->u_args[1]);
  304.     }
  305.     return 0;
  306. }
  307.  
  308. static
  309. printargv(pid, addr)
  310. {
  311.     int cp;
  312.  
  313.     while(1) {
  314.         if (umove(pid, addr, sizeof(char *), (char *)&cp) < 0)
  315.             return -1;
  316.         if (cp == 0)
  317.             break;
  318.         if (printstr(pid, cp, -1) < 0)
  319.             return -1;
  320.         addr += sizeof(char *);
  321.     }
  322.     return 0;
  323. }
  324.  
  325. int
  326. sys_execv(tcp)
  327. struct tcb *tcp;
  328. {
  329.     if (entering(tcp)) {
  330.         (void)printstr(tcp->pid, tcp->u_args[0], -1);
  331.         tprintf(", ");
  332.         (void)printargv(tcp->pid, tcp->u_args[1]);
  333.     } else {
  334.         if (!syserror(tcp) && followfork)
  335.             (void)fixvfork(tcp->pid);
  336.     }
  337.     return 0;
  338. }
  339.  
  340. int
  341. sys_execve(tcp)
  342. struct tcb *tcp;
  343. {
  344.     if (entering(tcp)) {
  345.         (void)printstr(tcp->pid, tcp->u_args[0], -1);
  346.         (void)tprintf(", ");
  347.         (void)printargv(tcp->pid, tcp->u_args[1]);
  348.         tprintf(", env: [");
  349.         if (verbose)
  350.             (void)printargv(tcp->pid, tcp->u_args[2]);
  351.         else
  352.             tprintf("%#x", tcp->u_args[2]);
  353.         tprintf("]");
  354.     } else {
  355.         if (!syserror(tcp) && followfork)
  356.             (void)fixvfork(tcp->pid);
  357.     }
  358.     return 0;
  359. }
  360.  
  361. static Xlat wait4_options[] = {
  362.     WNOHANG,    "NOHANG",
  363.     WUNTRACED,    "UNTRACED",
  364.     0,        NULL,
  365. };
  366.  
  367. int
  368. sys_wait4(tcp)
  369. struct tcb *tcp;
  370. {
  371.     int status;
  372.     struct rusage rusage;
  373.  
  374.     if (entering(tcp)) {
  375.         tprintf("%d, ", tcp->u_args[0]);
  376.         if (tcp->nchildren > 0) /* There are traced children */ {
  377.             tcp->flags |= TCB_SUSPENDED;
  378.             tcp->waitpid = tcp->u_args[0];
  379.         }
  380.     } else {
  381.         if (syserror(tcp) || tcp->u_rval == 0) {
  382.             tprintf("%x, ", tcp->u_args[1]);
  383.             if (!printflags(wait4_options, tcp->u_args[2]))
  384.                 tprintf("0");
  385.             tprintf(", %x", tcp->u_args[3]);
  386.             return 0;
  387.         }
  388.         /* status */
  389.         if (tcp->u_args[1] == 0 ||
  390.                 umove(tcp->pid, tcp->u_args[1],
  391.                     sizeof status, (char *)&status) < 0)
  392.             tprintf("(struct int *)0, ");
  393.         else {
  394.             if (WIFSTOPPED(status))
  395.                 tprintf("STOPPED(%s), ",
  396.                     signals[WSTOPSIG(status)]+3);
  397.             else if WIFSIGNALED(status)
  398.                 tprintf("SIGNALED(%s), ",
  399.                     signals[WTERMSIG(status)]+3);
  400.             else if WIFEXITED(status)
  401.                 tprintf("EXITED(%d), ",
  402.                     WEXITSTATUS(status));
  403.         }
  404.         /* options */
  405.         if (!printflags(wait4_options, tcp->u_args[2]))
  406.             tprintf("0");
  407.         /* usage */
  408.         if (tcp->u_args[3] == 0 ||
  409.             umove(tcp->pid, tcp->u_args[3],
  410.                     sizeof rusage, (char *)&rusage) < 0)
  411.             tprintf(", (struct rusage *)0");
  412.         else
  413.             tprintf(", {stime %u,%u utime %u,%u ...}",
  414.                 rusage.ru_stime.tv_sec, rusage.ru_stime.tv_usec,
  415.                 rusage.ru_utime.tv_sec, rusage.ru_utime.tv_usec);
  416.     }
  417.     return 0;
  418. }
  419.  
  420. int
  421. sys_uname(tcp)
  422. struct tcb *tcp;
  423. {
  424.     struct utsname uname;
  425.  
  426.     if (exiting(tcp)) {
  427.         if (umove(tcp->pid, tcp->u_args[0],
  428.                 sizeof uname, (char *)&uname) < 0)
  429.             tprintf("%#x", tcp->u_args[0]);
  430.         else
  431.             tprintf("{%s, %s, %s, %s, %s, %s}",
  432.                 uname.sysname, uname.nodename,
  433.                 uname.nodeext, uname.release,
  434.                 uname.version, uname.machine);
  435.     }
  436.     return 0;
  437. }
  438.  
  439. static Xlat ptrace_cmds[] = {
  440.     (int)PTRACE_TRACEME,"TRACEME",    /* 0, by tracee to begin tracing */
  441.     (int)PTRACE_PEEKTEXT,"PEEKTEXT",/* 1, read word from text segment */
  442.     (int)PTRACE_PEEKDATA,"PEEKDATA",/* 2, read word from data segment */
  443.     (int)PTRACE_PEEKUSER,"PEEKUSER",/* 3, read word from user struct */
  444.     (int)PTRACE_POKETEXT,"POKETEXT",/* 4, write word into text segment */
  445.     (int)PTRACE_POKEDATA,"POKEDATA",    /* 5, write word into data segment */
  446.     (int)PTRACE_POKEUSER,"POKEUSER",    /* 6, write word into user struct */
  447.     (int)PTRACE_CONT,    "CONT",        /* 7, continue process */
  448.     (int)PTRACE_KILL,    "KILL",        /* 8, terminate process */
  449.     (int)PTRACE_SINGLESTEP,    "SINGLESTEP",    /* 9, single step process */
  450.     (int)PTRACE_ATTACH,    "ATTACH",    /* 10, attach to an existing process */
  451.     (int)PTRACE_DETACH,    "DETACH",    /* 11, detach from a process */
  452.     (int)PTRACE_GETREGS,    "GETREGS",    /* 12, get all registers */
  453.     (int)PTRACE_SETREGS,    "SETREGS",    /* 13, set all registers */
  454.     (int)PTRACE_GETFPREGS,"GETFPREGS",    /* 14, get all floating point regs */
  455.     (int)PTRACE_SETFPREGS,"SETFPREGS",    /* 15, set all floating point regs */
  456.     (int)PTRACE_READDATA,    "READDATA",    /* 16, read data segment */
  457.     (int)PTRACE_WRITEDATA,    "WRITEDATA",    /* 17, write data segment */
  458.     (int)PTRACE_READTEXT,    "READTEXT",    /* 18, read text segment */
  459.     (int)PTRACE_WRITETEXT,    "WRITETEXT",    /* 19, write text segment */
  460.     (int)PTRACE_GETFPAREGS,    "GETFPAREGS",    /* 20, get all fpa regs */
  461.     (int)PTRACE_SETFPAREGS,    "SETFPAREGS",    /* 21, set all fpa regs */
  462. #ifdef    sparc
  463.     /*    currently unimplemented */
  464.     (int)PTRACE_GETWINDOW,    "GETWINDOW",    /* 22, get register window n */
  465.     (int)PTRACE_SETWINDOW,    "SETWINDOW",    /* 23, set register window n */
  466. #else    !sparc
  467.     (int)PTRACE_22,    "PTRACE_22",            /* 22, filler */
  468.     (int)PTRACE_23,    "PTRACE_23",            /* 23, filler */
  469. #endif    !sparc
  470.     (int)PTRACE_SYSCALL,    "SYSCALL",    /* 24, trap next sys call */
  471.     (int)PTRACE_DUMPCORE,    "DUMPCORE",    /* 25, dump process core */
  472. #ifdef    i386
  473.     (int)PTRACE_SETWRBKPT,    "SETWRBKPT",    /* 26, set write breakpoint */
  474.     (int)PTRACE_SETACBKPT,    "SETACBKPT",    /* 27, set access breakpoint */
  475.     (int)PTRACE_CLRDR7,    "CLRDR7",        /* 28, clear debug register 7 */
  476. #else
  477.     (int)PTRACE_26,    "PTRACE_26",            /* 26, filler */
  478.     (int)PTRACE_27,    "PTRACE_27",            /* 27, filler */
  479.     (int)PTRACE_28,    "PTRACE_28",            /* 28, filler */
  480. #endif
  481.     (int)PTRACE_GETUCODE,    "PTRACE_GETUCODE",    /* 29, get u.u_code */
  482.     0,        NULL,
  483. };
  484.  
  485.  
  486. static Xlat u[] = {
  487.     uoff(u_pcb),    "u_pcb",
  488.     uoff(u_procp),    "u_procp",
  489.     uoff(u_ar0),    "u_ar0",
  490.     uoff(u_comm[0]),    "u_comm",
  491.     uoff(u_arg[0]),    "u_arg",
  492.     uoff(u_ap),    "u_ap",
  493.     uoff(u_qsave),    "u_qsave",
  494.     uoff(u_rval1),    "u_rval1",
  495.     uoff(u_rval2),    "u_rval2",
  496.     uoff(u_error),    "u_error",
  497.     uoff(u_eosys),    "u_eosys",
  498.     uoff(u_ssave),    "u_ssave",
  499.     uoff(u_signal[0]),    "u_signal",
  500.     uoff(u_sigmask[0]),    "u_sigmask",
  501.     uoff(u_sigonstack),    "u_sigonstack",
  502.     uoff(u_sigintr),    "u_sigintr",
  503.     uoff(u_sigreset),    "u_sigreset",
  504.     uoff(u_oldmask),    "u_oldmask",
  505.     uoff(u_code),    "u_code",
  506.     uoff(u_addr),    "u_addr",
  507.     uoff(u_sigstack),    "u_sigstack",
  508.     uoff(u_ofile),    "u_ofile",
  509.     uoff(u_pofile),    "u_pofile",
  510.     uoff(u_ofile_arr[0]),    "u_ofile_arr",
  511.     uoff(u_pofile_arr[0]),    "u_pofile_arr",
  512.     uoff(u_lastfile),    "u_lastfile",
  513.     uoff(u_cwd),    "u_cwd",
  514.     uoff(u_cdir),    "u_cdir",
  515.     uoff(u_rdir),    "u_rdir",
  516.     uoff(u_cmask),    "u_cmask",
  517.     uoff(u_ru),    "u_ru",
  518.     uoff(u_cru),    "u_cru",
  519.     uoff(u_timer[0]),    "u_timer",
  520.     uoff(u_XXX[0]),    "u_XXX",
  521.     uoff(u_ioch),    "u_ioch",
  522.     uoff(u_start),    "u_start",
  523.     uoff(u_acflag),    "u_acflag",
  524.     uoff(u_prof.pr_base),    "u_prof.pr_base",
  525.     uoff(u_prof.pr_size),    "u_prof.pr_size",
  526.     uoff(u_prof.pr_off),    "u_prof.pr_off",
  527.     uoff(u_prof.pr_scale),    "u_prof.pr_scale",
  528.     uoff(u_rlimit[0]),    "u_rlimit",
  529.     uoff(u_exdata.Ux_A),    "u_exdata.Ux_A",
  530.     uoff(u_exdata.ux_shell[0]),    "u_exdata.ux_shell",
  531.     uoff(u_lofault),    "u_lofault",
  532.     0,            NULL,
  533. };
  534.  
  535. int
  536. sys_ptrace(tcp)
  537. struct tcb *tcp;
  538. {
  539.     Xlat *x;
  540.     int addr;
  541.  
  542.     if (entering(tcp)) {
  543.         printxval(ptrace_cmds, tcp->u_args[0], "PTRACE_???");
  544.         tprintf(", %u, ", tcp->u_args[1]);
  545.         addr = tcp->u_args[2];
  546.         if (tcp->u_args[0] == (int)PTRACE_PEEKUSER) {
  547.             for (x = u; x->str; x++) {
  548.                 if (x->val >= addr)
  549.                     break;
  550.             }
  551.             if (x->val > addr && x != u) {
  552.                 x--;
  553.                 tprintf("%s[%x], ",
  554.                     x->str, addr - x->val);
  555.             } else {
  556.                 tprintf("%s, ", x->str);
  557.             }
  558.         } else {
  559.             tprintf("%#x, ", tcp->u_args[2]);
  560.         }
  561.         if (tcp->u_args[0] == (int)PTRACE_WRITEDATA ||
  562.             tcp->u_args[0] == (int)PTRACE_WRITETEXT) {
  563.             tprintf("%u, ", tcp->u_args[3]);
  564.             (void)printstr(tcp->pid, tcp->u_args[4], tcp->u_args[3]);
  565.         } else if (tcp->u_args[0] != (int)PTRACE_READDATA &&
  566.                 tcp->u_args[0] != (int)PTRACE_READTEXT) {
  567.             tprintf("%#x", tcp->u_args[3]);
  568.         }
  569.     } else {
  570.         if (tcp->u_args[0] == (int)PTRACE_READDATA ||
  571.             tcp->u_args[0] == (int)PTRACE_READTEXT) {
  572.             tprintf("%u, ", tcp->u_args[3]);
  573.             (void)printstr(tcp->pid, tcp->u_args[4], tcp->u_args[3]);
  574.         }
  575.     }
  576.     return 0;
  577. }
  578.  
  579.