www.delorie.com/archives/browse.cgi   search  
Mail Archives: pgcc/2000/01/12/09:48:55

Sender: juan AT delorie DOT com
Message-ID: <387C5F18.D1153AB1@altmayer.com>
Disposition-Notification-To: Juan Altmayer Pizzorno <juan AT altmayer DOT com>
Date: Wed, 12 Jan 2000 12:01:44 +0100
From: Juan Altmayer Pizzorno <juan AT altmayer DOT com>
X-Mailer: Mozilla 4.7 [en] (X11; I; Linux 2.2.14 i686)
X-Accept-Language: en
MIME-Version: 1.0
To: gcc-bugs AT gcc DOT gnu DOT org, pgcc AT delorie DOT com
CC: juan AT altmayer DOT com,
"=?iso-8859-1?Q?J=FCrgen?= Christoffel"
<jc AT port25 DOT com>
Subject: Possible tail-recursion bug
Reply-To: pgcc AT delorie DOT com

This is a multi-part message in MIME format.
--------------9FD3E008FA6FC8546A631DD6
Content-Type: text/plain; charset=us-ascii
Content-Transfer-Encoding: 7bit

Hi,

I recently reported a bug to the Pentium GCC group where a pointer
calculation was changing the value of another variable within a
program that originally decoded DNS packets.  In the meantime I've
confirmed that the bug also happens on other platforms (tested:
Pentium II, Pentium Pro, Pentium, SPARC/Solaris) and with various
version of the compiler (2.91.66, 2.95.2, pgcc-2.95.2), so I'm
following up on this both to pgcc as well as to gcc-bugs.  I am
attaching the original code below, but apparently the problem is
that the parameter 'p' and the variable 'jump' are being allocated
in the same location.  For example,

//---
#include <stdio.h>

static int
ExtractName (char*& p, int n)
{
    char* jump;

printf ("p @%X, jump @%X\n", &p, &jump);

    if (n > 0)
        return ExtractName (jump, n - 1);

    return 0;
}

int
main ()
{
    char* p;

    ExtractName (p, 10);
    return 0;
}
//---

compiled with "g++ -O -o t2 t2.cxx" produces

p @BFFFFB64, jump @BFFFFB34
p @BFFFFB34, jump @BFFFFB34   <-- both allocated in the same location!
p @BFFFFB34, jump @BFFFFB34
p @BFFFFB34, jump @BFFFFB34
...

where as if compiled with "g++ -o t2 t2.cxx" it produces

p @BFFFFB64, jump @BFFFFB34
p @BFFFFB34, jump @BFFFFB04
p @BFFFFB04, jump @BFFFFAD4
...

Interestingly enough, if I replace

    if (n > 0)
        return ExtractName (jump, n - 1);

by

    if (n > 0)
    {
        int result = ExtractName (jump, n - 1);
        return result;
    }

the problem does not occur (perhaps the tail recursion is not recognized?).
While an argument could be made that in the example above neither 'jump' nor
'p' are really being used, this is not the case in the (more complicated)
original code.

Please let me know if there is any way I can help.  Thanks

.. Juan
--------------9FD3E008FA6FC8546A631DD6
Content-Type: text/plain; charset=us-ascii;
 name="t.cxx"
Content-Transfer-Encoding: 7bit
Content-Disposition: inline;
 filename="t.cxx"

// $Id: t.cxx,v 1.14 2000/01/12 09:41:23 juan Exp $

#include <stdio.h>
typedef unsigned char uchar;

/*
$ g++ --version
pgcc-2.95.2
$ g++ -O6 -o t t.cxx
p @BFFFFA58, jump @BFFFFA54
BFFFFAAB == BFFFFAAB ?
p @BFFFFA54, jump @BFFFFA54            <--- allocated in same address
BFFFFA94 == BFFFFA68 ?                 <--- changing 'jump' changes 'p'
p @BFFFFA54, jump @BFFFFA54
BFFFFA6A == C0002FCA ?
p @BFFFFA54, jump @BFFFFA54
*/

static int
ExtractName (uchar* header, uchar*& p, uchar* end)
{
    uchar* jump;
    unsigned length;

printf ("p @%X, jump @%X\n", (unsigned)&p, (unsigned)&jump);
    if (p >= end)
        return 1;

    while ((length = *p++))
    {
        if (length & 0xc0)
        {
            // compute offset in 'length', new 'p' in 'jump'
            length = ((length & 0x3F) << 8) | *p;

printf ("%X == ", (unsigned)p);

            jump = header + length;

printf ("%X ?\n", (unsigned)p);

            // advance 'p' to final position
            ++p;

            return ExtractName (header, jump, end);
        }
        else
        {
            if (p + length > end)
                return 1;

            p += length;
        }
    }

    if (p > end)
        return 1;

    return 0;
}

int
main (int argc, char* argv[])
{
    uchar buffer[] = {
        0x00,0x01,0x81,0x80,0x00,0x01,0x00,0x02,0x00,0x04,0x00,0x06,0x08,0x75,0x6E,0x69,
        0x2D,0x62,0x6F,0x6E,0x6E,0x02,0x64,0x65,0x00,0x00,0x0F,0x00,0x01,0xC0,0x0C,0x00,
        0x0F,0x00,0x01,0x00,0x00,0x03,0x84,0x00,0x10,0x00,0x0A,0x06,0x6E,0x6F,0x64,0x65,
        0x30,0x33,0x04,0x72,0x68,0x72,0x7A,0xC0,0x0C,0xC0,0x0C,0x00,0x0F,0x00,0x01,0x00,
        0x00,0x03,0x84,0x00,0x0B,0x00,0x14,0x06,0x6E,0x6F,0x64,0x65,0x30,0x35,0xC0,0x32,
        0xC0,0x0C,0x00,0x02,0x00,0x01,0x00,0x01,0x51,0x80,0x00,0x06,0x03,0x4E,0x49,0x43,
        0xC0,0x32,0xC0,0x0C,0x00,0x02,0x00,0x01,0x00,0x01,0x51,0x80,0x00,0x0D,0x0A,0x6E,
        0x6F,0x64,0x65,0x30,0x33,0x2D,0x65,0x6E,0x32,0xC0,0x32,0xC0,0x0C,0x00,0x02,0x00,
        0x01,0x00,0x01,0x51,0x80,0x00,0x09,0x06,0x6E,0x6F,0x64,0x65,0x30,0x38,0xC0,0x32,
        0xC0,0x0C,0x00,0x02,0x00,0x01,0x00,0x01,0x51,0x80,0x00,0x17,0x07,0x77,0x73,0x2D,
        0x6D,0x75,0x65,0x31,0x06,0x77,0x69,0x6E,0x2D,0x69,0x70,0x03,0x64,0x66,0x6E,0x02,
        0x64,0x65,0x00,0xC0,0x2B,0x00,0x01,0x00,0x01,0x00,0x01,0x51,0x80,0x00,0x04,0x83,
        0xDC,0x12,0x85,0xC0,0x47,0x00,0x01,0x00,0x01,0x00,0x01,0x51,0x80,0x00,0x04,0x83,
        0xDC,0x12,0x87,0xC0,0x5C,0x00,0x01,0x00,0x01,0x00,0x01,0x51,0x80,0x00,0x04,0x83,
        0xDC,0x10,0xDC,0xC0,0x6E,0x00,0x01,0x00,0x01,0x00,0x01,0x51,0x80,0x00,0x04,0x83,
        0xDC,0x0E,0xCB,0xC0,0x87,0x00,0x01,0x00,0x01,0x00,0x01,0x51,0x80,0x00,0x04,0x83,
        0xDC,0x12,0x8A,0xC0,0x9C,0x00,0x01,0x00,0x01,0x00,0x00,0xF2,0x41,0x00,0x04,0xC1,
        0xAE,0x4B,0xA6
    };

    int rc;
    uchar* end = buffer + sizeof (buffer);
    uchar* p = buffer + 0x47;

    if ((rc = ExtractName (buffer, p, end)))
        exit (1);

    return 0;
}

--------------9FD3E008FA6FC8546A631DD6--

- Raw text -


  webmaster     delorie software   privacy  
  Copyright © 2019   by DJ Delorie     Updated Jul 2019