Path: utzoo!mnetor!uunet!husc6!mailrus!ames!pacbell!att-ih!ihnp4!twitch!homxb!dean From: dean@homxb.UUCP (D.JONES) Newsgroups: comp.unix.wizards Subject: sun-3 dbx, arguments, hacking, help... Message-ID: <1641@homxb.UUCP> Date: 24 Apr 88 17:50:39 GMT Organization: AT&T Bell Laboratories, Holmdel Lines: 96 Keywords: Kludge, Hack, Hack HELP!!! I need to know how `dbx' knows how many arguments are on the stack when you do the `where' command on a SUN 3. It seems that in a fit of `lazyness', our software developers became very dependent on a very very non-portable, compiler dependent, function that returns the number of arguments for the function that called it, ... got that ? It was used something like this: ... not actual code here :-) void do_something(a,b,c) int a, b, c; { int args; /* add your favorite auto's, it still works */ count(&args); switch(args){ case 1: do_another_thing(a); break; case 2: do_so_and_so(a,b); break; case 3: yea_yea_yea(a+b,c); break; default: oops(); } } function count() is pretty easy to do an a 3b, vax, or Amdahl Native compiler, but on the sun 3's, we got into some real trouble..... We had to look at the next instruction at the return point for do_something(), and hack out how much it was adding to the stack pointer after a function call. ( addqw #0x4,sp ) and divide by sizeof(int) or whatever, and voila', it worked... Yea, I know this only worked for 4 byte arguments, I am not defending the code. So the real problem is this. On our new SunOS 4.0, the optimizer kills the `final' stack adjustment for a function. Eg: go() { printf("%d\n", 1); /* in asm addqw #0x8,sp */ bla(34); /* in asm addqw #0x4,sp */ do_anything(1, 'a', 2, "help"); /* forget it, it's the last function call */ } Now, dbx KNOWS how many 4 byte arguments are there. You do not have to compile with -g, and it does not look in a symbol table and see how many are supposed to be there, it knows even for function with a variable number of arguments. Try the following program: main() { go(0); go(0,0); go(0,0,0); go(0,0,0,0); } go(a) int a; { } Compile and run under dbx, no -g, and stop at symbol go and do a `where'. Each time it gives the correct argument dump. So, how does it do it ??? We have about 100 function that use this `count()' routine to check for optional arguments. These should be easy enough to fix, but they are used from roughly 3000 places in our code, each of which will also have to fixed or supplied with the extra argument(s). We have about 1 Million lines of code, and poking through it all to find them will take us way past our release date. I am looking into ways to discontinue the use of the count() function, but I need an intermediate solution so we don't blow our schedule ... Any help would be appreciated ... Dean Jones AT&T Bell Labs. HO 1K-426 { AT&T Gateways }!homxb!dean P.S. This will probably be impossible on a SUN-4