Subject: Re: Bug#86356: analog: analog segfaults

From: "Kevin B. Hendricks" <[email-masked]>
Date: Fri, 23 Feb 2001 16:29:23 -0500

Hi,

I think the second double value is confusing the compiler into skipping a
stack slot when it really shouldn't be doing that at all!!!!!

This is wierd.

Here is a quick and dirty way to test.  Move both double parameters to the
beginning of the function and caller and the problem should go away.

Another solution is to include a "dummy" int variable in both the caller
and the function right before the double parameter "unit".  That dummy will
fill a stack slot and force any messed up double alignment issue to become
moot.

If either of those workarounds work, then please pass all of this info to
Franz Sirl's attention on the [email-masked] site and he can use it to
track down the messed up code. It the workarounds fix things, this is a
definite bug

Okay, here is what should be where:

gpr registers
r3   outf
r4   rep
r5   outstyle
r6   multibyte
r7   tree
r8   requests
r9   date
r10  badp

floating point registers
f1  totb
f2  unit
f3
f4
f5
f6
f7
f8

overflow stack (starts aligned to 8 at the previous frame pointer + 8
offset  0: badn
offset  4: level
offset  8: partname
offset  c: aliashead
offset 10: linkhead
offset 14: baseurl
offset 18: totr
offset 1c: totp
offset 20: width
offset 24: possrightalign
offset 28: bmult
 <================== (if passed on the stack the double would have
                      been here but there were enough floating point
                      registers so it should not be on the stack.)
                      (However, if it was on the stack, the compiler should
                       have skipped a stack slot since doubles must be
                       passed aligned to 8)
offset 2c: sepchar
offset 30: rsepchar
offset 34: decpt
offset 38: compsep
offset 3c: rawbytes
offset 40: cols
offset 44: colhead
offset 48: colheadp
offset 4c: gender
offset 50: html
offset 54: monthname
offset 58: dayname
offset 5c: monthlen
offset 60: daylen
offset 64: plainmonthend
offset 68: plaindaylen
offset 6c: lngstr

Please let me know if the workaround  "fixes" things.  We will then have a
bug.

Thanks,

Kevin

On Friday 23 February 2001 15:46, Stephen Turner wrote:
> Thanks for your help with this, Kevin (I'm the upstream author).
>
> > To see if it is indeed a parameter passing issue, I need to know what the
> > types are for each parameter passed below (specifically if any are long
> > long int or float or double types and what the return type is of that
> > function so that I can tell is any structures are returned.
> >
>
> The definition:
>
> typedef unsigned char logical;
> typedef signed char choice;
> /* and Strlist, Alias, Include are typedefs to structs */
> void printtree(FILE *outf, choice rep, choice outstyle, logical multibyte,
>        Hashtable *tree, choice requests, choice date, Hashentry *badp,
>        unsigned long badn, unsigned int level, Strlist *partname,
>        Alias *aliashead, Include *linkhead, char *baseurl,
>        unsigned long totr, unsigned long totp, double totb,
>        unsigned int width[], logical possrightalign,
>        unsigned int bmult, double unit, char sepchar, char repsepchar,
>        char decpt, char *compsep, logical rawbytes, choice *cols,
>        char *colhead, char *colheadp, char gender, logical *html,
>        char **monthname, char **dayname, unsigned int monthlen,
>        unsigned int daylen, unsigned int plainmonthlen,
>        unsigned int plaindaylen, char **lngstr) {
>
> The call:
>
> printtree(outf, rep, outstyle, multibyte, tree, requests, date, badp, badn,
>     0, NULL, aliashead, linkhead, baseurl, totr, totp, totb, width,
>     possrightalign, bmult, unit, sepchar, repsepchar, decpt, compsep,
>     rawbytes, cols, colhead, colheadp, gender, html, monthname,
>     dayname, monthlen, daylen, plainmonthlen, plaindaylen, lngstr);
>
> I've double-checked that all arguments in the call have the correct types.
>
> However, notice that printtree() has 38 arguments. The C standard (Section
> 5.2.4.1) only requires implementations to accept 31 arguments. Does gcc have
> this limit?
>
> > Another (easier solution) is to modify each routine to print the values
of
> > all parameters just before the call and just inside the called routine.
>
> I've done this. fprintf'ing the values of all the parameters immediately
> before the call and immediately on entry to the function gives:
>
> BEFORE:
> 0x100f3f48 9 0 0 0x1007f550 0 4 0xffe859c
> 268919984 0 (nil) (nil) 0x100e8498 (nil)
> 1 0 88140.000000 0x7ffff8f8 0 0
> 1.000000 44 0 46 0x1007e498 0 0x100654de
> 0x100e9eb8 0x100e9ec8 n 0x1006543f 0x1006592c 0x10065910
> 3 3 3 3 0x100e98b0
>
> AFTER:
> 0x100f3f48 9 0 0 0x1007f550 0 4 0xffe859c
> 268919984 0 (nil) (nil) 0x100e8498 (nil)
> 1 0 88140.000000 0x7ffff8f8 0 0
> 1.000000 0 46 152 (nil) 222 0x100e9eb8
> 0x100e9ec8 0x6e ? 0x1006592c 0x10065910 0x3
> 3 3 3 269392048 0x100f3f48
> Segmentation fault
>
> Notice how the second half of the arguments appear to have been shifted up
> one. Compare with the same code on an i386/potato machine:
>
> BEFORE:
> 0x8115a80 9 0 0 0x80a1260 0 4 0x80980b0
> 1 0 (nil) (nil) 0x8109fc8 (nil)
> 1 0 88140.000000 0xbffff884 0 1
> 1.000000 44 0 46 0x80a01a8 0 0x808711e
> 0x810b9f0 0x810ba00 n 0x808707f 0x80874b0 0x8087494
> 3 3 3 3 0x810b318
>
> AFTER:
> 0x8115a80 9 0 0 0x80a1260 0 4 0x80980b0
> 1 0 (nil) (nil) 0x8109fc8 (nil)
> 1 0 88140.000000 0xbffff884 0 1
> 1.000000 44 0 46 0x80a01a8 0 0x808711e
> 0x810b9f0 0x810ba00 n 0x808707f 0x80874b0 0x8087494
> 3 3 3 3 0x810b318
>
> Thanks again,
>
> --
> Stephen Turner               http://www.statslab.cam.ac.uk/~sret1/
>   Statistical Laboratory, Wilberforce Road, Cambridge, CB3 0WB, England
>   "Your account can only be used for a single internet session at any one
>    time and for no more than 24 hours in any one day." (NTL terms of use)

** Sent via the linuxppc-dev mail list. See http://lists.linuxppc.org/