guy@rlgvax.UUCP (Guy Harris) (07/26/83)
Here are the sources to the "sdb" enhancements. The files called "*.e" are edit scripts for the files in question (*.c or *.h). "bio.c" and "bio.h" are what "old.c" and "old.h" were originally called; stick these versions in and get rid of "old.c" and "old.h" - no guarantees, but they should make this version of "sdb" work on a non-VM system. Also, you can get rid of the file "rdwr.c" in the original source, as it's just a copy of "fio.c". Guy Harris {seismo,mcnc,we13,brl-bmd,allegra}!rlgvax!guy # The rest of this file is a shell script which will extract: # Makefile.e access.c.e bio.c bio.h decode.c.e display.c.e docomm.c.e fio.c.e head.h.e main.c.e prvar.c.e runpcs.c.e sub.c.e symt.c.e version.c.e xeq.c.e echo x - Makefile.e cat >Makefile.e <<'!Funky!Stuff!' 57c # DO NOT DELETE THIS LINE (or its two succesors) -- make depend uses it # IF YOU PUT STUFF HERE IT WILL GO AWAY # see make depend above access.o: head.h bio.o: bio.h decode.o: head.h display.o: head.h display.o: cdefs.h docomm.o: head.h fio.o: head.h main.o: head.h message.o: mac.h message.o: mode.h opset.o: head.h optab.o: defs.h optab.o: ../as/instrs pcs.o: defs.h prvar.o: head.h prvar.o: cdefs.h re.o: head.h runpcs.o: head.h setup.o: head.h sub.o: head.h sub.o: cdefs.h symt.o: head.h xeq.o: head.h . 53,55d 47c echo '/^# DO NOT DELETE THIS LINE/+3,$$d' >eddep . 21c HDRS= cdefs.h defs.h head.h mac.h machine.h mode.h bio.h . 19c bio.o opset.o optab.o pcs.o prvar.o re.o runpcs.o \ . 16c bio.c opset.c optab.c pcs.c prvar.c re.c runpcs.c \ . 10,12d !Funky!Stuff! echo x - access.c.e cat >access.c.e <<'!Funky!Stuff!' 48a } /* get data in named register using descriptor format d */ getreg(reg, d) ADDR reg; char d; { register long val; val = *(ADDR *)(((ADDR)&u)+R0+WORDSIZE*reg); val &= dmask[dtol(d)]; return(val); . 6a * Revision history: * * 10/1/82 G. Harris * "getreg" routine added to get value of a register. * . !Funky!Stuff! echo x - bio.c cat >bio.c <<'!Funky!Stuff!' #ifndef VMUNIX static char sccsid[] = "@(#)bio.c 4.1 10/9/80"; #include "bio.h" /* * NAMES: bread(), brseek(), blseek() * * DESCRIPTION: * This is a buffered read package. * * Bread may be called with a negative nbytes which causes it to * read backwards. In this case, buffer should point to the first * byte following the buffer. If only a partial read is possible * (due to beginning of file), only the last bytes of the buffer * will be filled. * * 9/27/82 G. Harris * Resurrected and renamed bio.c 1) for compatibility with non-virtual * memory versions of sdb and 2) to keep the Makefile happy. */ /* * These routines are used only if the system * doesn't have virtual memory. They * are used only to read the symbol table, which * is simply kept in VM on VMUNIX. */ bread(brs, buff, nbytes) struct brbuf *brs; char *buff; { register int k, nb; if (nbytes > 0) { for (nb=nbytes; nb>0; nb--) { if (brs->nr == 0) { brs->nr = read(brs->fd, brs->next=brs->b, BSIZE); brs->nl = 0; if (brs->nr < 0) return(-1); if (brs->nr == 0) return(nbytes-nb); } *buff++ = *brs->next++; brs->nr--; brs->nl++; } } else { nbytes = -nbytes; for (nb=nbytes; nb>0; nb--) { if (brs->nl == 0) { if ((k=tell(brs->fd)) >= BSIZE + brs->nr) { lseek(brs->fd, (long) -(BSIZE + brs->nr), 1); brs->nl = read(brs->fd, brs->b, BSIZE); } else { lseek(brs->fd, 0L, 0); k = k - brs->nr; if (k < 0) k = 0; brs->nl = read(brs->fd, brs->b, k); } if (brs->nl == 0) return(nbytes-nb); brs->next = brs->b + brs->nl; brs->nr = 0; } *--buff = *--brs->next; brs->nr++; brs->nl--; } } return(nbytes); } blseek(brs, offset, flag) struct brbuf *brs; long offset; { brs->nl = 0; brs->nr = 0; return(lseek(brs->fd,offset,flag)); } binit(brs) struct brbuf *brs; { brs->nl = brs->nr = 0; } long tell(fildes) { return(lseek(fildes, 0L, 1)); } #endif !Funky!Stuff! echo x - bio.h cat >bio.h <<'!Funky!Stuff!' /* "@(#)bio.h 4.1 10/9/80" */ /* * 9/27/82 G. Harris * Resurrected and renamed bio.h 1) for compatibility with non-virtual * memory versions of sdb and 2) to keep the Makefile happy. */ #ifndef VMUNIX struct brbuf { int nl, nr; char *next; char b[BSIZE]; int fd; }; long lseek(); #endif !Funky!Stuff! echo x - decode.c.e cat >decode.c.e <<'!Funky!Stuff!' 117c if (cmd == '\0') { while(*p == ' ') p++; cmd = *p ? *p : '/'; } . 31a if (*p == '<') { /* start reading a command file */ if (infile != stdin) { error("Cannot nest command files"); return(1); } p++; /* * Gather up file name. */ r = filename; while ((c = *p++) != '\n' && c != ' ') *r++ = c; *r = '\0'; /* * Now gather up to 9 parameters. */ paramp = ¶m[0]; r = &parmbuf[0]; while (c != '\n' && paramp < ¶m[9]) { *paramp++ = r; while (c == ' ') c = *p++; while (c != '\n' && c != ' ') { *r++ = c; c = *p++; } *r++ = '\0'; } r--; /* point to a null string */ while (paramp < ¶m[9]) *paramp++ = r; /* * Now try to open the command file. */ if ((infile = fopen(filename, "r")) == (FILE *)NULL) { infile = stdin; /* restore */ error("Can't open command file"); return(1); } return(1); } . 30c return(1); . 9a register char **paramp, *r; char filename[128]; . 4a /* * Revision history: * * 10/1/82 G. Harris * Modified so that if it encounters a token followed by a blank, it * does NOT interpret the blank as a command, but scans until it finds * a non-blank character and interprets that as the command. This way, * the command "i m" can be typed and interpreted as a "m" command * to monitor the variable "i". * Also modified to support '<' command to read from a command file. * Also modified to return 1 if "decode" executes the command itself, * to keep "main" from passing the command to "docommand". */ . !Funky!Stuff! echo x - display.c.e cat >display.c.e <<'!Funky!Stuff!' 417c register unsigned char class; . 84,85c stackreg(reg) int reg; { register ADDR curframe; register int regfl, mask, i; . 71c unsigned char class; . 51c return(stackreg((int)addr)); . 47c register unsigned char class; . 26a /* step to the next frame in the call stack */ /* MACHINE DEPENDENT */ . 1a /* * Revision history: * * 7/25/83 G. Harris * Changed variable "class" wherever it occurred from "char" to * "unsigned char", because in Berkeley's "a.out.h" file "n_type" is * an "unsigned char", not a "char". */ . !Funky!Stuff! echo x - docomm.c.e cat >docomm.c.e <<'!Funky!Stuff!' 476a break; default: error("Unknown command"); . 383,386c if (integ && (var[0] == '\0')) addr = (ADDR) integ; else addr = varaddr(proc, var); if (addr == -1) error("Unknown variable"); else { monex(addr, args); printf("stopped with value "); if (integ && (var[0] == '\0')) { dispf((ADDR) integ, args, N_GSYM, 0, 0, 0, DSP); oaddr = integ; cpstr(odesc, args); oclass = N_GSYM; otype = 0; } else dispvar(proc, var, args); setcur(1); lastcom = NOCOM; } . 379c printf("All breakpoints deleted\n"); . 332c printf("Procedure killed\n"); . 303a case 'i': signo = 0; case 'I': integ = atoi(args); singinstr(integ ? integ : 1, cmd); if (signo) printf("\n"); setcur(1); lastcom = NOCOM; break; . 280c if (debug) printf("exiting dopcs\n"); . 277c f1: if (debug) printf("calling dopcs\n"); . 258c if (debug) printf("exiting dopcs\n"); . 250c if (debug) printf("calling dopcs\n"); . 246c if (args[0] == '\0') { cpstr(args, oldargs); printf("%s %s\n", symfil, args); } . 144c if ((i = finit(args)) > 0) ffind(i); . 1a /* * Revision history: * * 10/1/82 G. Harris * Fixed to complain about an unknown command, instead of just * ignoring it. * The 'm' command changed to take an optional display format, and to * display the monitored variable as with a '/' command. * Also fixed the 'm' code so that it relies on varaddr to fill in the * default procedure, instead of doing it itself; the old way, if you * wanted to monitor a global variable you couldn't. Added code to * permit an absolute address to be monitored. * Miscellaneous calls to "error" which weren't really errors changed * to calls to "printf", so as not to revert input from command file * to terminal. * * 10/10/82 G. Harris * "docommand" modified to copy the last arguments to an r/R command * from oldargs in case an r command with no arguments is given, instead * of calling "getargs" to poke through the stack. See the comments * in "xeq.c" for an explanation. * * 10/13/82 G. Harris * Fixed 'm' command to complain if a non-existent variable is given. * * 10/18/82 G. Harris * Modified 'e' command so that, if given a file name as an argument, * it makes the last line of the file the current line (like "ed"). * Previously, it did not do anything to the current line, which left * it as "line 0"; this meant that if you did a regular expression * search of the file, if no line matched the regular expression the * search would never return to the starting line, causing an infinite * loop. * * 11/13/82 G. Harris * "i" and "I" commands added; for a boring exposition on them, see the * revision history of xeq.c. */ . !Funky!Stuff! echo x - fio.c.e cat >fio.c.e <<'!Funky!Stuff!' 117a return(cfile->nlines); . 107c return(0); . 84c return(cfile->nlines); . 74a /* IT WOULD BE BETTER TO HAVE A COUPLE OF FILE DESCRIPTORS, LRU */ if (FIO) fclose(FIO); FIO = newFIO; . 73c return(0); /* can't find the file */ . 70c if ((newFIO = fopen(filework, "r")) == NULL) { . 59,64c return(cfile->nlines); /* its already current, do nothing */ . 56a register FILE *newFIO; . 3a * * Revision history: * * 10/1/82 G. Harris * Fixed so that "finit" does not close FIO before opening the new file. * Instead, it opens the file with a new stream and only closes the old * one if the new open succeeds. It used to close the stdio stream * referring to the current file, but leave "cfile" pointing to whatever * it used to point to. Then, if the fopen of the new file failed, sdb * thought that the previous current file was still current, except that * the stdio stream FIO no longer referred to it. Now, if the fopen * fails, the old FIO is not destroyed and the previous current file * remains current. * * 10/18/82 G. Harris * Modified "finit" to return the line number of the last line in the * file (which is the line that "ed" would position the user to). . !Funky!Stuff! echo x - head.h.e cat >head.h.e <<'!Funky!Stuff!' 87c #define COMMANDS "\004\"+-=!/BCDIMQRSTabcdegiklmpqrstwxzVXY" . 75c char oldargs[256]; . 73a struct tchars sdbtc, usertc; int sdbld, userld; #ifdef TIOCLGET int sdblm, userlm; struct ltchars sdblt, userlt; #endif . 71c unsigned char oclass; /* class of last displayed variable */ . 44c unsigned char sl_class; . 15c char args[256]; /* arguments */ . 9a /* indirect command file processing */ FILE *infile; /* current input stream */ char *param[9]; /* pointers to parameter values */ char parmbuf[256]; /* holds value strings */ . 7c #include "bio.h" . 1a /* * Revision history: * * 8/13/82 G. Harris * Fixed to save and restor ALL the tty modes. * * 9/27/82 G. Harris * "old.h" renamed back to "bio.h". * * 10/1/82 G. Harris * Modified to support command to read from a command file. * Various line and string buffers increased from 128 bytes to 256 bytes. * * 7/25/83 G. Harris * Changed variables "sl_class" and "oclass" from "char" to * "unsigned char", because in Berkeley's "a.out.h" file "n_type" is * an "unsigned char", not a "char". */ . !Funky!Stuff! echo x - main.c.e cat >main.c.e <<'!Funky!Stuff!' 133c error(""); . 114a if (decode(p) == 1) continue; . 110,112c if (infile == stdin) printf("*"); if ((p = readline(infile)) == (char *)NULL) { if (infile != stdin) { fclose(infile); infile = stdin; } . 104a ioctl(2, TIOCSETC, &sdbtc); ioctl(2, TIOCSETD, &sdbld); #ifdef TIOCLGET ioctl(2, TIOCLSET, &sdblm); ioctl(2, TIOCSLTC, &sdblt); #endif } . 103c ioctl(2, TIOCGETC, &usertc); ioctl(2, TIOCGETD, &userld); #ifdef TIOCLGET ioctl(2, TIOCLGET, &userlm); ioctl(2, TIOCGLTC, &userlt); #endif if (sdbttym.sg_flags != userttym.sg_flags) { . 93a ioctl(2, TIOCGETC, &sdbtc); ioctl(2, TIOCGETD, &sdbld); #ifdef TIOCLGET ioctl(2, TIOCLGET, &sdblm); ioctl(2, TIOCGLTC, &sdblt); #endif . 87a if (fsym<0) exit(4); . 56a infile = stdin; /* start reading from the terminal */ . 36a INT fsym; . 15a FILE *infile; . 6a * Revision history: * * 8/13/82 G. Harris * Fixed to save and restor ALL the tty modes. * * 10/1/82 G. Harris * Modified to permit reading commands from a file. * Also modified not to print an error message when "decode" returned * 1. The error message was superfluous, because "decode" already * gave an error message. This way, if "decode" returns 1 it merely * means not to try executing the command; this is useful for those * commands, like '!' and '<', that are executed from within "decode". * "fault" changed to call "error" in order to reset input to the * terminal. * * 10/18/82 G. Harris * Fixed to exit if the executable program file cannot be opened. * . !Funky!Stuff! echo x - prvar.c.e cat >prvar.c.e <<'!Funky!Stuff!' 439a } /* * Scan a descriptor to extract the format, length, and size. */ descscan(desc, dfmtp, dlenp, sizep) char *desc; char *dfmtp; char *dlenp; int *sizep; { char *p; *dfmtp = 'd'; *dlenp = '\0'; for (p = desc; *p; p++) { if (*p>= '0' && *p<'9') { *sizep = readint(&p); p--; } else switch (*p) { case 'l': case 'h': case 'b': *dlenp = *p; break; case 'a': case 'c': case 'd': case 'f': case 'g': case 'i': case 'I': case 'o': case 'p': case 's': case 'u': case 'x': *dfmtp = *p; break; default: printf("Illegal descriptor: %c\n", *p); return(1); } } return(0); . 428a dot = addr; . 314c value = getreg(addr, dfmt == 'g' ? 'd' : dfmt); . 285,305d 272,283c pd[1] = dfmt; . 270a if (descscan(desc, &dfmt, &dlen, &size)) return(1); . 247d 1a /* * Revision history: * * 9/27/82 G. Harris * Fixed to set "dot" to "addr" before disassembling an instruction in a * print with the "i" format. * * 10/1/82 G. Harris * Code to parse a descriptor split from routine "dispx" to make it * accessible to other routines. * "dispx" modified to use "getreg". */ . !Funky!Stuff! echo x - runpcs.c.e cat >runpcs.c.e <<'!Funky!Stuff!' 293c THEN printf(" - core dumped\n"); . 6a * Revision history: * * 10/2/82 G. Harris * Miscellaneous calls to "error" which weren't really errors changed * to calls to "printf" so as not to revert input from command file to * terminal. * . !Funky!Stuff! echo x - sub.c.e cat >sub.c.e <<'!Funky!Stuff!' 328c printf("%-12d ", v); . 314,318c if (v >= -9 && v <= 9) . 56a if (infile != stdin) { fclose(infile); infile = stdin; /* this is usually an error, so revert the input to the terminal */ } . 25a p = linebuf; q = buff; while ((i = *p++) != '\n') { if (q >= &buff[256]) { error("Line too long"); return((char *)NULL); } if (i == '$') { if ((i = *p++) == '\n') { *q++ = '$'; break; } if (i >= '0' && i <= '9') { r = param[(i - '0') - 1]; while ((i = *r++) != '\0') { if (q >= &buff[256]) { error("Line too long"); return((char *)NULL); } *q++ = i; } } else { *q++ = '$'; if (q >= &buff[256]) { error("Line too long"); return((char *)NULL); } *q++ = i; } } else *q++ = i; } *q = '\n'; . 23,24c } while (i != '\n'); if (p > &linebuf[256]) { error("Line too long"); return((char *)NULL); } . 20,21c if (f == stdin) { *p++ = '\004'; *p++ = i = '\n'; } else return((char *)NULL); } else { if (p < &linebuf[256]) *p++ = i; . 17c p = linebuf; . 14c register char *p, *q, *r; . 12c static char buff[258]; /* allow extra for newline and EOT */ char linebuf[258]; . 1a /* * Revision history: * * 9/27/82 G. Harris * Fixed "prhex12" to print out numbers between -9 and 9 in a field of * length 14 (because all other numbers print in a field of 12 in hex, * with a "0x" before them, which is really a field of length 14). * * 10/1/82 G. Harris * Modified "readline" to return NULL on an EOF if it is not reading * from the standard input. * Also modified to perform substitution of parameters to a command * file ($1 = first parameter, $9 = last) if not reading from the * standard input. * Various line buffers increased from 128 bytes to 256 bytes. * Checks added to make sure the line buffers do not overflow. * "error" changed to revert input to terminal if called. * * 10/10/82 G. Harris * Fixed "prhex" to use the same algorithm as "prhex12", because * otherwise 0x80000000 looks real funny. */ . !Funky!Stuff! echo x - symt.c.e cat >symt.c.e <<'!Funky!Stuff!' 842,843c unsigned char class; { unsigned char *p; . 839c unsigned char pctypes[] = {N_GSYM, N_STSYM, N_LCSYM, N_RSYM, N_SSYM, N_LSYM, . 302c unsigned char class; . 61c unsigned char class; . 1a /* * Revision history: * * 7/25/83 G. Harris * Changed variable "class" wherever it occurred from "char" to * "unsigned char", because in Berkeley's "a.out.h" file "n_type" is * an "unsigned char", not a "char". */ . !Funky!Stuff! echo x - version.c.e cat >version.c.e <<'!Funky!Stuff!' 3c printf("Version 2.6 - February 1, 1980\n"); . 1a /* * Revision history: * * 10/2/82 G. Harris * Changed to call "printf" instead of "error", as we don't really want * to stop executing a command file just because there was a V command * in the command file. */ . !Funky!Stuff! echo x - xeq.c.e cat >xeq.c.e <<'!Funky!Stuff!' 282a ioctl(2, TIOCSETC, &sdbtc); ioctl(2, TIOCSETD, &sdbld); #ifdef TIOCLGET ioctl(2, TIOCLSET, &sdblm); ioctl(2, TIOCSLTC, &sdblt); #endif } . 281c ioctl(2, TIOCGETC, &usertc); ioctl(2, TIOCGETD, &userld); #ifdef TIOCLGET ioctl(2, TIOCLGET, &userlm); ioctl(2, TIOCGLTC, &userlt); #endif if (sdbttym.sg_flags != userttym.sg_flags) { . 278a ioctl(2, TIOCSETC, &usertc); ioctl(2, TIOCSETD, &userld); #ifdef TIOCLGET ioctl(2, TIOCLSET, &userlm); ioctl(2, TIOCSLTC, &userlt); #endif } . 277c if (c != 'r' && c != 'R' && sdbttym.sg_flags != userttym.sg_flags) { . 225,274d 83a /* single step count instructions */ singinstr(count, cmd) char cmd; { if (sdbttym.sg_flags != userttym.sg_flags) { stty(2, &userttym); ioctl(2, TIOCSETC, &usertc); ioctl(2, TIOCSETD, &userld); #ifdef TIOCLGET ioctl(2, TIOCLSET, &userlm); ioctl(2, TIOCSLTC, &userlt); #endif } dot = *(ADDR *) (((ADDR) &u) + PC); if (count == 0) count = 1; for(; count; count--) { subpcs('s'); dot = *(ADDR *) (((ADDR) &u) + PC); gtty(2, &userttym); ioctl(2, TIOCGETC, &usertc); ioctl(2, TIOCGETD, &userld); #ifdef TIOCLGET ioctl(2, TIOCLGET, &userlm); ioctl(2, TIOCGLTC, &userlt); #endif if (sdbttym.sg_flags != userttym.sg_flags) { stty(2, &sdbttym); ioctl(2, TIOCSETC, &sdbtc); ioctl(2, TIOCSETD, &sdbld); #ifdef TIOCLGET ioctl(2, TIOCLSET, &sdblm); ioctl(2, TIOCSLTC, &sdblt); #endif } if (signo) return; } } . 79a ioctl(2, TIOCSETC, &sdbtc); ioctl(2, TIOCSETD, &sdbld); #ifdef TIOCLGET ioctl(2, TIOCLSET, &sdblm); ioctl(2, TIOCSLTC, &sdblt); #endif } . 78c ioctl(2, TIOCGETC, &usertc); ioctl(2, TIOCGETD, &userld); #ifdef TIOCLGET ioctl(2, TIOCLGET, &userlm); ioctl(2, TIOCGLTC, &userlt); #endif if (sdbttym.sg_flags != userttym.sg_flags) { . 66a curline = adrtolineno(dot); . 63a ioctl(2, TIOCSETC, &sdbtc); ioctl(2, TIOCSETD, &sdbld); #ifdef TIOCLGET ioctl(2, TIOCLSET, &sdblm); ioctl(2, TIOCSLTC, &sdblt); #endif } . 62c userttym.sg_flags) { . 60a ioctl(2, TIOCGETC, &usertc); ioctl(2, TIOCGETD, &userld); #ifdef TIOCLGET ioctl(2, TIOCLGET, &userlm); ioctl(2, TIOCGLTC, &userlt); #endif . 53a argsp = ""; /* no commands on this temporary breakpoint */ . 39a ioctl(2, TIOCSETC, &usertc); ioctl(2, TIOCSETD, &userld); #ifdef TIOCLGET ioctl(2, TIOCLSET, &userlm); ioctl(2, TIOCSLTC, &userlt); #endif } . 38c if (sdbttym.sg_flags != userttym.sg_flags) { . 28,29c if (sl_class == N_RSYM && loc < 16) newval = getreg(loc, dlen); else newval = getval(loc, dlen, DSP); } while (oldval == newval); . 25c /* if only as a global, not a sdb, symbol: printit(metaflag, prvar, addr, fmt[0] ? fmt : "d", ...); */ if (fmt[0] == '\0') fmt = typetodesc(sl_type, subflag); descscan(fmt, &dfmt, &dlen, &size); if (dfmt == 'g') dfmt = 'd'; /* only look at first half of double */ if (dlen == '\0') dlen = dfmt; if (sl_class == N_RSYM && loc < 16) oldval = getreg(loc, dlen); else oldval = getval(loc, dlen, DSP); . 23a register ADDR newval; char dfmt, dlen; int size; . 21,22c monex(loc, fmt) ADDR loc; char *fmt; { . 18c * single step until loc with descriptor format fmt is modified . 1a /* * Revision history: * * 8/13/82 G. Harris * Fixed to save and restore ALL the tty modes. * * 8/26/82 G. Harris * Fixed so that "temporary" breakpoints set by the S command do not * have a garbage command associated with them. * * 10/1/82 G. Harris * Fixed so that "monex" gets a full format as its argument rather than * just a format character. "monex" also no longer need return the * new value. Also fixed to properly handle register variables. * * 10/10/82 G. Harris * If the process had already been run, and the u area had been read * (for example, because the process had hit a breakpoint), and then an * r command with no arguments was given, "getargs" would find that * there was a stack, so it would search back for the original arguments * to "main" and stick them into "args", otherwise it would just use * the ones in "oldargs". This was a problem, because sometimes it would * fail to find "main" or somesuch other problem, and "errflg" would get * set. Then "setup" would see "errflg" set, think it had run into some * problem trying to execute the program, and quit. Furthermore, it * is completely unclear why it bothers getting the arguments out of the * process' stack anyway. If the program didn't tamper with them, the * copy in "oldargs" will do quite well, and if it did tamper with them, * you probably want to pass the untampered-with arguments anyway. So * "getargs" was sent to the great Code Bin in the Sky. * * 11/13/82 G. Harris * Routine "singinstr" added to implement "i" and "I" commands. It * seems that 4.1BSD comes with a version of "sdb" later than Release 3 * of UNIX, but earlier than Release 4's version; i.e., most of the nice * stuff that was added by 4 showed up here, albeit with a pile of bugs, * but the "i" and "I" (single step by one instruction) commands didn't. * Unfortunately, the meaning of "I" from Bell is of indeterminate merit. * "c" means ignore the signal that stopped the process, "C" means * continue with the signal. On the other hand, "s" means step into * subroutines and "S" means step over them; the signal is always ignored. * For the instruction step, Bell decided to make "i/I" analogous to * "c/C" instead of "s/S". First of all, a "I" analogous to "S" would * be EXTREMELY useful; users of "ddb" will certainly testify to that. * Second, it's not clear why continuing with the signal is more useful * for single-instruction stepping than for single-line stepping. And * third, the whole command language should be redesigned ANYWAY, and * one of the things would be to make step into/over subroutines and * continue with/ignoring the signal orthogonal. The VAX/VMS DEBUG * idea of having a flag saying whether to step into or over subroutines * might be the way to do that; then "c/C", "s/S", and "i/I" (or their * equivalents in the new syntax) would mean ignore/continue with the * signal, respectively. On the other hand, "dbg" or whatever it will * be called will have to wait for later, and I'm loath to tamper with * existing commands, especially one as useful as "S". * * 7/25/83 G. Harris * Fixed "singstep" to get the current line number after stepping over * a subroutine call, as well as after stepping over a single instruction. */ . !Funky!Stuff!