1: /*
   2:  * Rewritten to look like the more modern versions of gcore on other systems.
   3:  * The -s option for stopping the process was added, the ability to name
   4:  * the core file was added, and to follow changes to the kernel the default
   5:  * corefile name was changed to be 'pid.core' rather than simply 'core'.
   6:  * Only one process may be gcore'd at a time now however.  4/15/94 - sms.
   7:  *
   8:  * Originally written for V7 Unix, later changed to handle 2.9BSD, later
   9:  * still brought up on 2.10BSD.  Pretty close the 4.XBSD except for
  10:  * handling swapped out processes (it doesn't). - sms
  11:  */
  12: 
  13: #include <sys/param.h>
  14: #include <sys/user.h>
  15: #include <sys/proc.h>
  16: #include <sys/file.h>
  17: #include <stdio.h>
  18: #include <nlist.h>
  19: #include <varargs.h>
  20: 
  21: #define NLIST   "/vmunix"
  22: #define MEM "/dev/mem"
  23: 
  24: struct nlist nl[] = {
  25:     { "_proc" },
  26: #define X_PROC  0
  27:     { "_nproc" },
  28: #define X_NPROC 1
  29:     { 0 },
  30: };
  31: 
  32:     int mem, cor, nproc, sflag;
  33:     struct  proc    *pbuf;
  34:     char    *corefile, *program_name;
  35: 
  36: extern  int optind, opterr;
  37: extern  char    *optarg, *rindex();
  38: extern  off_t   lseek();
  39: 
  40: main(argc, argv)
  41:     int argc;
  42:     char    **argv;
  43: {
  44:     register int    pid, c;
  45:     char    fname[32];
  46: 
  47:     if  (program_name = rindex(argv[0], '/'))
  48:         program_name++;
  49:     else
  50:         program_name = argv[0];
  51: 
  52:     opterr = 0;
  53:     while   ((c = getopt(argc, argv, "c:s")) != EOF)
  54:         {
  55:         switch  (c)
  56:             {
  57:             case    'c':
  58:                 corefile = optarg;
  59:                 break;
  60:             case    's':
  61:                 sflag++;
  62:                 break;
  63:             default:
  64:                 usage();
  65:                 break;
  66:             }
  67:         }
  68:     argv += optind;
  69:     argc -= optind;
  70:     if  (argc != 1)
  71:         usage();
  72:     pid = atoi(argv[0]);
  73:     if  (corefile == 0)
  74:         {
  75:         sprintf(fname, "%d.core", pid);
  76:         corefile = fname;
  77:         }
  78: 
  79:     openfiles();
  80:     getkvars();
  81:     (void)lseek(mem, (long)nl[X_NPROC].n_value, L_SET);
  82:     (void)read(mem, &nproc, sizeof nproc);
  83:     pbuf = (struct proc *)calloc(nproc, sizeof (struct proc));
  84:     if (pbuf == NULL)
  85:         error("not enough core");
  86:     (void)lseek(mem, (long)nl[X_PROC].n_value, L_SET);
  87:     (void)read(mem, pbuf, nproc * sizeof (struct proc));
  88: 
  89:     core(pid);
  90:     exit(0);
  91: }
  92: 
  93: void
  94: core(pid)
  95:     register int    pid;
  96: {
  97:     register int i;
  98:     register struct proc *pp;
  99:     uid_t uid, getuid();
 100:     char ubuf[USIZE*64];
 101: 
 102:     for (i = 0, pp = pbuf;; pp++) {
 103:         if (pp->p_pid == pid)
 104:             break;
 105:         if (i++ == nproc)
 106:             error("%d: not found", pid);
 107:     }
 108:     if (pp->p_uid != (uid = getuid()) && uid != 0)
 109:         error("%d: not owner", pid);
 110:     if ((pp->p_flag & SLOAD) == 0)
 111:         error("%d: swapped out", pid);
 112:     if (pp->p_stat == SZOMB)
 113:         error("%d: zombie", pid);
 114:     if (pp->p_flag & SSYS)
 115:         error("%d: system process", pid);
 116:     if (sflag && kill(pid, SIGSTOP) < 0)
 117:         warning("%d: could not send stop signal", pid);
 118:     if (lseek(mem, (long)pp->p_addr << 6, L_SET) < 0)
 119:         error("bad mem seek");
 120:     if (read(mem, &ubuf, sizeof ubuf) != sizeof ubuf)
 121:         error("bad mem read");
 122:     if ((cor = open(corefile, O_RDWR|O_CREAT|O_TRUNC, 0666)) < 0) {
 123:         perror(corefile);
 124:         exit(1);
 125:     }
 126:     (void)write(cor, &ubuf, sizeof ubuf);
 127:     (void)lseek(mem, (long)pp->p_daddr << 6, L_SET);
 128:     dump(pp->p_dsize);
 129:     (void)lseek(mem, (long)pp->p_saddr << 6, L_SET);
 130:     dump(pp->p_ssize);
 131: 
 132:     if (sflag && kill(pid, SIGCONT) < 0)
 133:         warning("%d: could not send continue signal", pid);
 134:     (void)close(cor);
 135: }
 136: 
 137: void
 138: dump(size)
 139:     register u_int size;
 140: {
 141:     register int blocks, i;
 142:     int bytes;
 143:     char buffer[BUFSIZ * 2];
 144: 
 145:     size <<= 6;
 146:     blocks = size / sizeof (buffer);
 147:     bytes = size % sizeof (buffer);
 148: 
 149:     for (i = 0; i < blocks; i++) {
 150:         (void)read(mem, buffer, sizeof (buffer));
 151:         (void)write(cor, buffer, sizeof (buffer));
 152:     }
 153:     if (bytes) {
 154:         (void)read(mem, buffer, bytes);
 155:         (void)write(cor, buffer, bytes);
 156:     }
 157: }
 158: 
 159: void
 160: openfiles()
 161: {
 162:     mem = open(MEM, 0);
 163:     if (mem < 0) {
 164:         perror(MEM);
 165:         exit(1);
 166:     }
 167: }
 168: 
 169: void
 170: getkvars()
 171: {
 172:     nlist(NLIST, nl);
 173:     if (nl[0].n_type == 0)
 174:         error("%s: no namelist\n", NLIST);
 175: }
 176: 
 177: void
 178: usage()
 179:     {
 180:     fprintf(stderr, "usage: %s [ -s ] [ -c core ] pid\n", program_name);
 181:     exit(1);
 182:     }
 183: 
 184: /* VARARGS */
 185: void
 186: error(va_alist)
 187:     va_dcl
 188:     {
 189:     va_list ap;
 190:     register char   *cp;
 191: 
 192:     (void)fprintf(stderr, "%s: ", program_name);
 193: 
 194:     va_start(ap);
 195:     cp = va_arg(ap, char *);
 196:     (void)vfprintf(stderr, cp, ap);
 197:     va_end(ap);
 198:     if  (*cp)
 199:         {
 200:         cp += strlen(cp);
 201:         if  (cp[-1] != '\n')
 202:             (void)fputc('\n', stderr);
 203:         }
 204:     exit(1);
 205:     /* NOTREACHED */
 206:     }
 207: 
 208: /* VARARGS */
 209: void
 210: warning(va_alist)
 211:     va_dcl
 212:     {
 213:     va_list ap;
 214:     register char *cp;
 215: 
 216:     (void)fprintf(stderr, "%s: warning: ", program_name);
 217: 
 218:     va_start(ap);
 219:     cp = va_arg(ap, char *);
 220:     (void)vfprintf(stderr, cp, ap);
 221:     va_end(ap);
 222:     if  (*cp)
 223:         {
 224:         cp += strlen(cp);
 225:         if  (cp[-1] != '\n')
 226:             (void)fputc('\n', stderr);
 227:         }
 228:     }

Defined functions

core defined in line 93; used 1 times
  • in line 89
dump defined in line 137; used 2 times
error defined in line 185; used 9 times
getkvars defined in line 169; used 1 times
  • in line 80
main defined in line 40; never used
openfiles defined in line 159; used 1 times
  • in line 79
usage defined in line 177; used 2 times
warning defined in line 209; used 2 times

Defined variables

cor defined in line 32; used 5 times
corefile defined in line 34; used 5 times
mem defined in line 32; used 12 times
nl defined in line 24; used 4 times
nproc defined in line 32; used 5 times
pbuf defined in line 33; used 4 times
program_name defined in line 34; used 6 times
sflag defined in line 32; used 3 times

Defined macros

MEM defined in line 22; used 2 times
NLIST defined in line 21; used 2 times
X_NPROC defined in line 28; used 1 times
  • in line 81
X_PROC defined in line 26; used 1 times
  • in line 86
Last modified: 1994-04-16
Generated: 2016-12-26
Generated by src2html V0.67
page hit count: 3280
Valid CSS Valid XHTML 1.0 Strict