Subject: adb incorrect prints function arguments, local variables and external symbols Index: src/bin/adb/expr.c,findfn.c,print.c,sym.c Description: 1) $c and $C do not show argc and argv for main(). 2) $C prints the wrong values for local variables and is offset by a stackframe. 3) $e displays far too much information unrelated to the names and values of external variables. Repeat-By: This has been broken almost forever. Amazing it's not been commented on before this. Compile the following program and invoke adb -------- x.c ------ main(argc, argv) int argc; char **argv; { int i = 0; foo(i); exit(0); } foo(j) int j; { j++; } --------- cc x.c adb a.out foo+4:b :r a.out: running breakpoint ~foo+04: br ~foo+016 adb>$c vernon.4-> ./adb a.out 0177342: ~foo(0) from ~main+022 0177362: ~main() from start+0104 note that main() has no arguments displayed adb> $C 0177450: ~foo(0) from ~main+022 argc: 0 argv: 0 i: 0522 0177470: ~main() from start+0104 note that argc and argv are displayed for the function foo() rather than main(). Also observe the value of 'i' local variable is given as 0522 instead of 0 adb> $e crt0.o: 0170011 x.o: 04567 ~main: 04567 argc: 04 argv: 010600 i: 036505 ~foo: 04567 j: 04 rindex.o: 016600 exit.o: 04567 fakcu.o: 04567 fakcu.o: 0170011 ~_cleanup: 04567 _exit.o: 0104401 _exit.o: 0170011 csv.o: 012700 _environ: 0177400 ___progname: 0177424 _strrchr: 016600 _exit: 04567 _main: 04567 start: 0170011 mcount: 0207 _moncontrol: 0207 csv: 010501 _foo: 04567 cret: 010502 _rindex: 016600 __cleanup: 04567 __exit: 0104401 _errno: 0 x_norm: 0103004 x_error: 010067 __ovno: 0 _etext: 0177424 ovhndlr1: 012700 ovhndlr2: 012700 ovhndlr3: 012700 ovhndlr4: 012700 ovhndlr5: 012700 ovhndlr6: 012700 ovhndlr7: 012700 ovhndlr8: 012700 ovhndlr9: 012700 ovhndlra: 012700 ovhndlrb: 012700 ovhndlrc: 012700 ovhndlrd: 012700 ovhndlre: 012700 ovhndlrf: 012700 : 0177777 data address not found AFTER applying the patch below: vernon.3-> adb a.out adb> foo+4:b adb> :r a.out: running breakpoint ~foo+04: br ~foo+016 adb> $c 0177450: ~foo(0) from ~main+022 0177470: ~main(01,0177502) from start+0104 adb> $C 0177450: ~foo(0) from ~main+022 j: 0 0177470: ~main(01,0177502) from start+0104 argc: 01 argv: 0177502 i: 0 adb> $e _environ: 0177400 ___progname: 0177424 _errno: 0 __ovno: 0 Fix: Many thanks to martin@teckelworks.com for providing the fix with this description: The $c/$C issues were that the code that tries to figure out how many arguments there was looking at the instructions that set up the call stack. In the case of main(), it was thinking there 0 arguments because crt0.s doesn't do the normal call routine it was expecting. I fixed it by hard coding 2 if the previous frame pointer is 0 as that is how crt0 sets it up. The other $c/$C issue was that the routine that was printing the caller in the call stack was resetting the symbol table pointer position which is why everything was off by one frame. There are WAY too many globals in that code! $e was printing a bunch of other stuff besides the external data and bss variables. Cut where indicated and save to a file (/tmp/486.patch). Then: cd / patch -p0 < /tmp/486.patch cd /usr/src/bin/adb make install make clean This and previous updates to 2.11BSD are available at the following locations: ftp://ftp.dfupdate.se/pub/pdp11/2.11BSD https://www.tuhs.org/Archive/Distributions/UCB/2.11BSD/Patches/ ftp://ftp.2bsd.com/2.11BSD http://www.2bsd.com/2.11BSD Most (all) Web browsers have removed ftp: URL support and will need to use the http: links. Commandline users with an ftp client (found at https://ftp.gnu.org/gnu/inetutils/) can use anonymous ftp as always. ---------------------------cut here-------------------- *** ./usr/src/bin/adb/expr.c.old Fri Jan 14 00:59:27 1994 --- ./usr/src/bin/adb/expr.c Wed Mar 19 06:16:02 2025 *************** *** 247,253 **** { register struct SYMbol *symp, *sc; ! symset(); while (symp = symget()) { if (overlay && (symp->type == ISYM)) --- 247,253 ---- { register struct SYMbol *symp, *sc; ! symset(-1); while (symp = symget()) { if (overlay && (symp->type == ISYM)) *** ./usr/src/bin/adb/print.c.old Sun Jul 25 23:10:45 1999 --- ./usr/src/bin/adb/print.c Wed Mar 19 06:16:02 2025 *************** *** 213,222 **** --- 213,230 ---- printf(") from "); { int savmaxoff = maxoff; + int save_symcnt; + /* we need to save symcnt variable as psymoff + ** is going to change it and then the local + ** symbol dump is going to be off by a frame */ + + save_symcnt = sympos(); + maxoff = ((unsigned)-1)>>1; psymoff((long)callpc,ISYM,""); maxoff = savmaxoff; + symset(save_symcnt); } printc('\n'); *************** *** 240,250 **** /*print externals*/ case 'e': case 'E': ! symset(); WHILE (symp=symget()) DO chkerr(); ! IF (symp->type == N_EXT|N_DATA) || (symp->type== N_EXT|N_BSS) ! THEN printf("%s:%12t%o\n", no_cache_sym(symp), get(leng(symp->value),DSP)); FI OD --- 248,258 ---- /*print externals*/ case 'e': case 'E': ! symset(-1); WHILE (symp=symget()) DO chkerr(); ! IF (symp->type == (N_EXT|N_DATA)) || (symp->type == (N_EXT|N_BSS)) ! THEN printf("%s:%16t%o\n", no_cache_sym(symp), get(leng(symp->value),DSP)); FI OD *** ./usr/src/bin/adb/sym.c.old Sun Jan 16 19:03:07 1994 --- ./usr/src/bin/adb/sym.c Wed Mar 19 06:16:02 2025 *************** *** 129,140 **** } /* sequential search through table */ ! symset() { ! symcnt = -1; } struct SYMbol * symget() { --- 129,145 ---- } /* sequential search through table */ ! symset(int cnt) { ! symcnt = cnt; } + int sympos() + { + return symcnt; + } + struct SYMbol * symget() { *************** *** 230,236 **** #endif if (globals_only) printf("%s: could only do global symbols\n", myname); ! symset(); return(0); } --- 235,241 ---- #endif if (globals_only) printf("%s: could only do global symbols\n", myname); ! symset(-1); return(0); } *** ./usr/src/bin/adb/findfn.c.old Wed Jan 12 21:52:31 1994 --- ./usr/src/bin/adb/findfn.c Wed Mar 19 06:16:02 2025 *************** *** 33,39 **** IF (inst=get(leng(callpc-4), ISP)) == 04737 /* jsr pc,*$... */ THEN narg = 1; ELIF (inst&~077)==04700 /* jsr pc,... */ ! THEN narg=0; v=(inst!=04767); ELIF (back2&~077)==04700 THEN narg=0; v=TRUE; ELSE errflg=NOCFN; --- 33,40 ---- IF (inst=get(leng(callpc-4), ISP)) == 04737 /* jsr pc,*$... */ THEN narg = 1; ELIF (inst&~077)==04700 /* jsr pc,... */ ! THEN narg=(get(cframe, DSP) ? 0 : 2); /* top fp? main(argc, argv)? */ ! v=(inst!=04767); ELIF (back2&~077)==04700 THEN narg=0; v=TRUE; ELSE errflg=NOCFN; *** ./VERSION.old Fri Mar 14 16:27:46 2025 --- ./VERSION Fri Mar 21 06:33:48 2025 *************** *** 1,5 **** ! Current Patch Level: 485 ! Date: March 14, 2025 2.11 BSD ============ --- 1,5 ---- ! Current Patch Level: 486 ! Date: March 21, 2025 2.11 BSD ============