Re: Discussion about why GNU/Linux system upgrades cause old programs to break

Arsen Arsenović <[email protected]>
Newsgroups gmane.emacs.devel
Message-ID <[email protected]>
Richard Stallman <[email protected]> writes:

>   > Again, as an example, it's enough for a pointer to be used as a return
>   > value on a 64-bit platforms, which are not at all uncommon, or for a
>   > 'long long' to be used as a return value on any platform, for *visible*
>   > breakage when such a function is called through an implicit function
>   > declaration even in the most forgiving of conditions.
>
> Would you please show an example for the pointer on a 64-bit platform?
> And one for `long long'?  I'd like to see what sort of usage would
> have this problem.

The earlier reallocarray example was one such example.

But, sure:

  test.c:
    #include <stdio.h>

    int
    main (void)
    {
      /* Cast present due to third subtle issue implicit declarations
         cause: wrong types being used for vararg arguments.  */
      printf ("%llu\n", (long long) foo ());
      printf ("%s\n", bar ());
    }

  test2.c:
    #include <string.h>

    long long
    foo (void)
    {
      return ((long long) -1U) + 1;
    }

    const char *
    bar (void)
    {
      return strdup ("hello, world");
    }

Compile with: gcc -fpermissive test{,2}.c

In practice, 999 times out of a thousand, there's a test2.h, that
declares:

  long long foo (void);
  const char *bar (void);

... that the developer merely forgot to include.

On my x86_64 GNU/Linux machine, this manifests as:

  /tmp$ ./a.out 
  0
  Segmentation fault         (core dumped) ./a.out

... where the correct result is:

  /tmp$ ./a.out 
  4294967296
  hello, world

The former failure mode - the wrongful zero extension and thus
truncation of the value passed to printf - is significantly more
insidious than the latter - a loud crash, because it can be quite
difficult to discover and debug.  The crash is quite obvious on the
other hand.

Though note that I only got the crash because I got lucky (the malloc
pool could've been below the 4G mark and I wouldn't have been able to
get it, and it may even have "worked").

The comment in test.c also alludes to a third issue: implicit function
declarations and similar can lead to vararg functions being called
incorrectly.

This is a special case of wrongful argument promotion, which can also
happen if the function being called (rather than a call subexpression of
one of its arguments; in the example above printf is 'the function being
called', and foo and bar are in the 'call subexpressions' of printf's
arguments) is implicitly declared, as in the following:

  test.c:
    int
    main ()
    {
      foo (-1);
    }

  test2.c:
    #include <stdio.h>

    void
    foo (long long x)
    {
      printf ("%lld\n", x);
    }

(in this particular example, this is a missing argument promotion, from
int to long long)

On that same machine, the program above prints 4294967295.

Incidentally, this gets worse on 32-bit x86, where arguments are passed
on the stack, as one argument being pushed wrong shifts all other
arguments (on 64-bit x86, since the first few arguments are in
registers, this is a less likely - but not impossible - eventuality; not
that this property of the x86 64-bit ABI should be relied on for this
purpose).

Bugs caused by these mistakes can sneak into builds of programs - old
and new - and hide for a really long time, and manifest as very hard to
catch miscompilation and, thus, as strange runtime errors.

Obviously, all of the above are dumb, constructed examples, but the real
world insidious cases boil down to unintentionally instantiating a
pattern like those above.

Cases of such mistakes far outnumber the cases of intentional use of
these features, in my experience.
-- 
Arsen Arsenović
signature.asc (application/pgp-signature, 288 B)
-----BEGIN PGP SIGNATURE-----

iKIEARYKAEoWIQT+4rPRE/wAoxYtYGFSwpQwHqLEkwUCapTD4xsUgAAAAAAEAA5t
YW51MiwyLjUrMS4xMiwyLDIQHGFyc2VuQGFhcnNlbi5tZQAKCRBSwpQwHqLEkzgX
AP924Ij/k3bOOGAmCAAJojVnXIbFwCwO1vmEbchToCFrqQD/Wzi1OOLTzeko2/7m
hH84y4uX7uazZlkrfG3OJr4g6A4=
=uV3o
-----END PGP SIGNATURE-----
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.