bug-bison
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: Testsuite summary for GNU Bison 3.8.2 : FAIL 2


From: Dennis Clarke
Subject: Re: Testsuite summary for GNU Bison 3.8.2 : FAIL 2
Date: Thu, 14 Oct 2021 19:01:17 -0400
User-agent: Mozilla/5.0 (X11; Linux x86_64; rv:94.0) Gecko/20100101 Thunderbird/94.0

On 10/14/21 01:28, Akim Demaille wrote:
> Hi Dennis,
> 
>> Le 14 oct. 2021 à 03:40, Dennis Clarke <dclarke@blastwave.org> a écrit :
>>
>> *res = {
>>    name  = 0x105c30 "<bad address 0x0000000000105c30>"
>>    type  = 0
>>    value = {
>>        var = 0.0
>>        fun = (nil)
>>    }
>>    next  = (nil)
>> }
> 
> Really???  So it seems that strdup on this machine is dead broken.

This will be really silly long but strdup seems to work just fine :

beta $ cat /tmp/foo.c
/*********************************************************************
 * The Open Group Base Specifications Issue 6
 * IEEE Std 1003.1, 2004 Edition
 *
 *    An XSI-conforming application should ensure that the feature
 *    test macro _XOPEN_SOURCE is defined with the value 600 before
 *    inclusion of any header. This is needed to enable the
 *    functionality described in The _POSIX_C_SOURCE Feature Test
 *    Macro and in addition to enable the XSI extension.
 *
 *********************************************************************/
#define _XOPEN_SOURCE 600

#include <errno.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>

int main(int argc, char **argv)
{
   char barf[] = "please do strdup";
   errno = 0;
   char *puke = NULL;

   /* Any decent compiler will likely combine the above line
    * with this next line. Unless all optimizations are disabled. */
   puke = strdup(barf);

   /* check for malloc problems or errno however the
    * manpage says :
    *
    *     If the new string can not be created, a null pointer is
    *     returned and errno may be set to ENOMEM to indicate that
    *     the storage space available is insufficient.
    *
    * Note the use of the word "may".
    */

   if ( ( errno == ENOMEM ) || ( puke == NULL ) ) {
       fprintf(stderr,"FAIL : strdup()\n");
       return EXIT_FAILURE;
   }

   printf("barf is at %p\n",&barf);
   printf("puke is at %p\n",&puke);
   printf("puke value %p is the memory address on the heap\n", puke);
   printf("barf is \"%s\"\n", barf);
   printf("puke is \"%s\"\n", puke);
   free(puke);
   puke = NULL;

   return EXIT_SUCCESS;

}

beta $
beta $ $CC $CFLAGS $CPPFLAGS -o /tmp/foo /tmp/foo.c
beta $
beta $ /tmp/foo
barf is at ffffffff7ffff65b
puke is at ffffffff7ffff650
puke value 100101330 is the memory address on the heap
barf is "please do strdup"
puke is "please do strdup"
beta $


If strdup does not work then someone needs to get on the phone to
Larry Ellison and let him know that those pretty big red machines in
the Marvel comics movies are full of nose demons.  :)


> And... strdup is also used in examples/c/glr/c++-types...
> 

yep.


> Please try the attached version.
> 

Sure thing ....

beta $
beta $ cat ./test-suite.log
=======================================
   GNU Bison 3.8.2: ./test-suite.log
=======================================

# TOTAL: 8
# PASS:  4
# SKIP:  2
# XFAIL: 0
# FAIL:  2
# XPASS: 0
# ERROR: 0

.. contents:: :depth: 2

FAIL: examples/c/mfcalc/mfcalc
==============================

checking for diff --strip-trailing-cr...
diff: illegal option -- strip-trailing-cr
usage: diff [-bitw] [-c | -e | -f | -h | -n | -u] file1 file2
       diff [-bitw] [-C number | -U number] file1 file2
       diff [-bitw] [-D string] file1 file2
       diff [-bitw] [-c | -e | -f | -h | -n | -u] [-l] [-r] [-s] [-S
name] directory1 directory2
checking for diff --strip-trailing-cr...
mfcalc: FAIL: 1
mfcalc: input:
  1+2*3
mfcalc: expected output:
  7
mfcalc: effective output:
  7
  err: putsym: atan (100003c92) => atan (100105d50)
  err: putsym: cos (100003c98) => cos (100105d70)
  err: putsym: exp (100003ae4) => exp (100105d90)
  err: putsym: ln (100003c9c) => ln (100105db0)
  err: putsym: sin (100003ca0) => sin (100105dd0)
  err: putsym: sqrt (100003ca4) => sqrt (100105df0)
mfcalc: diff:
  --- exp       Thu Oct 14 20:58:57 2021
  +++ eff       Thu Oct 14 20:58:57 2021
  @@ -1,1 +1,7 @@
   7
  +err: putsym: atan (100003c92) => atan (100105d50)
  +err: putsym: cos (100003c98) => cos (100105d70)
  +err: putsym: exp (100003ae4) => exp (100105d90)
  +err: putsym: ln (100003c9c) => ln (100105db0)
  +err: putsym: sin (100003ca0) => sin (100105dd0)
  +err: putsym: sqrt (100003ca4) => sqrt (100105df0)
mfcalc: FAIL: 2
mfcalc: input:
  (1+2) * 3
mfcalc: expected output:
  9
mfcalc: effective output:
  9
  err: putsym: atan (100003c92) => atan (100105d50)
  err: putsym: cos (100003c98) => cos (100105d70)
  err: putsym: exp (100003ae4) => exp (100105d90)
  err: putsym: ln (100003c9c) => ln (100105db0)
  err: putsym: sin (100003ca0) => sin (100105dd0)
  err: putsym: sqrt (100003ca4) => sqrt (100105df0)
mfcalc: diff:
  --- exp       Thu Oct 14 20:58:57 2021
  +++ eff       Thu Oct 14 20:58:57 2021
  @@ -1,1 +1,7 @@
   9
  +err: putsym: atan (100003c92) => atan (100105d50)
  +err: putsym: cos (100003c98) => cos (100105d70)
  +err: putsym: exp (100003ae4) => exp (100105d90)
  +err: putsym: ln (100003c9c) => ln (100105db0)
  +err: putsym: sin (100003ca0) => sin (100105dd0)
  +err: putsym: sqrt (100003ca4) => sqrt (100105df0)
mfcalc: PASS: 3
mfcalc: FAIL: 4
mfcalc: input:
  a = 256
  sqrt (a)
mfcalc: expected output:
  256
  16
mfcalc: effective output:
  256
  16
  err: putsym: atan (100003c92) => atan (100105d50)
  err: putsym: cos (100003c98) => cos (100105d70)
  err: putsym: exp (100003ae4) => exp (100105d90)
  err: putsym: ln (100003c9c) => ln (100105db0)
  err: putsym: sin (100003ca0) => sin (100105dd0)
  err: putsym: sqrt (100003ca4) => sqrt (100105df0)
  err: getsym: a (100106f80) against sqrt (100105df0)
  err: getsym: a (100106f80) against sin (100105dd0)
  err: getsym: a (100106f80) against ln (100105db0)
  err: getsym: a (100106f80) against exp (100105d90)
  err: getsym: a (100106f80) against cos (100105d70)
  err: getsym: a (100106f80) against atan (100105d50)
  err: putsym: a (100106f80) => a (100105e10)
  err: getsym: sqrt (100106f80) against a (100105e10)
  err: getsym: sqrt (100106f80) against sqrt (100105df0)
  err: getsym: a (100106f80) against a (100105e10)
mfcalc: diff:
  --- exp       Thu Oct 14 20:58:57 2021
  +++ eff       Thu Oct 14 20:58:57 2021
  @@ -1,2 +1,18 @@
   256
   16
  +err: putsym: atan (100003c92) => atan (100105d50)
  +err: putsym: cos (100003c98) => cos (100105d70)
  +err: putsym: exp (100003ae4) => exp (100105d90)
  +err: putsym: ln (100003c9c) => ln (100105db0)
  +err: putsym: sin (100003ca0) => sin (100105dd0)
  +err: putsym: sqrt (100003ca4) => sqrt (100105df0)
  +err: getsym: a (100106f80) against sqrt (100105df0)
  +err: getsym: a (100106f80) against sin (100105dd0)
  +err: getsym: a (100106f80) against ln (100105db0)
  +err: getsym: a (100106f80) against exp (100105d90)
  +err: getsym: a (100106f80) against cos (100105d70)
  +err: getsym: a (100106f80) against atan (100105d50)
  +err: putsym: a (100106f80) => a (100105e10)
  +err: getsym: sqrt (100106f80) against a (100105e10)
  +err: getsym: sqrt (100106f80) against sqrt (100105df0)
  +err: getsym: a (100106f80) against a (100105e10)
mfcalc: FAIL: 5
mfcalc: input:
  16 == 12
mfcalc: expected output:
  err: syntax error
mfcalc: effective output:
  err: putsym: atan (100003c92) => atan (100105d50)
  err: putsym: cos (100003c98) => cos (100105d70)
  err: putsym: exp (100003ae4) => exp (100105d90)
  err: putsym: ln (100003c9c) => ln (100105db0)
  err: putsym: sin (100003ca0) => sin (100105dd0)
  err: putsym: sqrt (100003ca4) => sqrt (100105df0)
  err: syntax error
mfcalc: diff:
  --- exp       Thu Oct 14 20:58:57 2021
  +++ eff       Thu Oct 14 20:58:57 2021
  @@ -1,1 +1,7 @@
  +err: putsym: atan (100003c92) => atan (100105d50)
  +err: putsym: cos (100003c98) => cos (100105d70)
  +err: putsym: exp (100003ae4) => exp (100105d90)
  +err: putsym: ln (100003c9c) => ln (100105db0)
  +err: putsym: sin (100003ca0) => sin (100105dd0)
  +err: putsym: sqrt (100003ca4) => sqrt (100105df0)
   err: syntax error
FAIL examples/c/mfcalc/mfcalc.test (exit status: 1)

SKIP: examples/c/bistromathic/bistromathic
==========================================

checking for diff --strip-trailing-cr...
diff: illegal option -- strip-trailing-cr
usage: diff [-bitw] [-c | -e | -f | -h | -n | -u] file1 file2
       diff [-bitw] [-C number | -U number] file1 file2
       diff [-bitw] [-D string] file1 file2
       diff [-bitw] [-c | -e | -f | -h | -n | -u] [-l] [-r] [-s] [-S
name] directory1 directory2
checking for diff --strip-trailing-cr...
./examples/test: line 50: 13654 Segmentation Fault      (core dumped)
"$abs_medir/$me" "$@"
checking for readline output...
1,3d0
< > 0
< 0
< >
1d0
< 0
SKIP: this is not the GNU Readline we expect
SKIP examples/c/bistromathic/bistromathic.test (exit status: 77)

FAIL: examples/c/glr/c++-types
==============================

checking for diff --strip-trailing-cr...
diff: illegal option -- strip-trailing-cr
usage: diff [-bitw] [-c | -e | -f | -h | -n | -u] file1 file2
       diff [-bitw] [-C number | -U number] file1 file2
       diff [-bitw] [-D string] file1 file2
       diff [-bitw] [-c | -e | -f | -h | -n | -u] [-l] [-r] [-s] [-S
name] directory1 directory2
checking for diff --strip-trailing-cr...
c++-types: FAIL: 1 (expected status: 0, effective: 139)
./examples/test: line 50: 13755 Segmentation Fault      (core dumped)
"$abs_medir/$me" "$@"
FAIL examples/c/glr/c++-types.test (exit status: 1)

SKIP: examples/c/reccalc/reccalc
================================

checking for diff --strip-trailing-cr...
diff: illegal option -- strip-trailing-cr
usage: diff [-bitw] [-c | -e | -f | -h | -n | -u] file1 file2
       diff [-bitw] [-C number | -U number] file1 file2
       diff [-bitw] [-D string] file1 file2
       diff [-bitw] [-c | -e | -f | -h | -n | -u] [-l] [-r] [-s] [-S
name] directory1 directory2
checking for diff --strip-trailing-cr...
SKIP: gimme one seq
SKIP examples/c/reccalc/reccalc.test (exit status: 77)

beta $


That actually looks pretty good given that the mfcalc output seems
correct and we have a bucket of debug printout stuff in there as noise.
However the results look correct.

Funny thing, the exact same code blows up in a spectacular fashion on
Debian Linux sid on ppc64.  However that is a whole other kettle of
rotten fish and I just looked there for a comparison.



-- 
Dennis Clarke
RISC-V/SPARC/PPC/ARM/CISC
UNIX and Linux spoken
GreyBeard and suspenders optional


ps: here comes the assembly for that foo.c wherein we really do
    get separate instructions to initialize the NULL pointer and
    then call strdup() :

beta $
beta $ $CC $CFLAGS $CPPFLAGS -S -o /tmp/foo.s /tmp/foo.c
beta $
beta $ wc -l /tmp/foo.s
     925 /tmp/foo.s
beta $

Let's just skip over some of that to get to where we really do get
separate instructions for the "*puke = NULL" and the strdup() call :


beta $ cat /tmp/foo.s

        .section        ".text",#alloc,#execinstr,#progbits
        .file   "foo.c"

        .section        ".data",#alloc,#write,#progbits

Ddata.data:

        .section        ".rodata",#alloc,#progbits
!
! CONSTANT POOL
!

Drodata.rodata:
        .align  8
!
! CONSTANT POOL
!
.
.  a bunch of constants such as the strings
.
! SUBROUTINE main
!
! OFFSET    SOURCE LINE LABEL   INSTRUCTION

                        .global main


                        main:

! predecessor blocks: main

.
.
.  startup stuff
.
                        .L15:

!   21                !   char barf[] = "please do strdup";


! predecessor blocks: .L15

.
.  this is fun .. moving the char bytes from the static string
.  into the "barf" variable byte after byte for 16 bytes and
.  then stuff a zero value ( hardwired in %g0 ) as the last
.  byte to give us a nul terminated nice string in memory
.  at [%fp+2010]
.
                        .L18:
/* 0x0028         21 */         mov     112,%o0
/* 0x002c            */         stb     %o0,[%fp+2010]
/* 0x0030            */         mov     108,%o0
/* 0x0034            */         stb     %o0,[%fp+2011]
/* 0x0038            */         mov     101,%o0
/* 0x003c            */         stb     %o0,[%fp+2012]
/* 0x0040            */         mov     97,%o0
/* 0x0044            */         stb     %o0,[%fp+2013]
/* 0x0048            */         mov     115,%o0
/* 0x004c            */         stb     %o0,[%fp+2014]
/* 0x0050            */         mov     101,%o0
/* 0x0054            */         stb     %o0,[%fp+2015]
/* 0x0058            */         mov     32,%o0
/* 0x005c            */         stb     %o0,[%fp+2016]
/* 0x0060            */         mov     100,%o0
/* 0x0064            */         stb     %o0,[%fp+2017]
/* 0x0068            */         mov     111,%o0
/* 0x006c            */         stb     %o0,[%fp+2018]
/* 0x0070            */         mov     32,%o0
/* 0x0074            */         stb     %o0,[%fp+2019]
/* 0x0078            */         mov     115,%o0
/* 0x007c            */         stb     %o0,[%fp+2020]
/* 0x0080            */         mov     116,%o0
/* 0x0084            */         stb     %o0,[%fp+2021]
/* 0x0088            */         mov     114,%o0
/* 0x008c            */         stb     %o0,[%fp+2022]
/* 0x0090            */         mov     100,%o0
/* 0x0094            */         stb     %o0,[%fp+2023]
/* 0x0098            */         mov     117,%o0
/* 0x009c            */         stb     %o0,[%fp+2024]
/* 0x00a0            */         mov     112,%o0
/* 0x00a4            */         stb     %o0,[%fp+2025]
/* 0x00a8            */         stb     %g0,[%fp+2026]

!   22                !   errno = 0;


! predecessor blocks: .L18

                        .L19:
/* 0x00ac         22 */         call    ___errno        !params=
!result=  %o0
/* 0x00b0            */         nop
/* 0x00b4            */         mov     %o0,%o1
/* 0x00b8            */         st      %g0,[%o1] ! volatile

!   23                !   char *puke = NULL;


! predecessor blocks: .L19

.
.
.   stuff a zero value into memory at [%fp+1999] and tada we have a NULL
.   pointer value for "puke".
.
                        .L20:
/* 0x00bc         23 */         stx     %g0,[%fp+1999]

!   25                !   /* Any decent compiler will likely combine the
above line
!   26                !    * with this next line. Unless all
optimizations are disabled. */
!   27                !   puke = strdup(barf);


! predecessor blocks: .L20

                        .L21:
/* 0x00c0         27 */         add     %fp,2010,%o0
/* 0x00c4            */         call    strdup  !params=  %o0   !result=
 %o0
/* 0x00c8            */         nop
/* 0x00cc            */         mov     %o0,%o1
/* 0x00d0            */         stx     %o1,[%fp+1999]

! predecessor blocks: .L21

.
.  since all optimizations in disabled and I did ask for nice to
.  debug code we see the actual strfup call is made above.
.
.  The register %o0 ends up containing the frame pointer plus an
.  offset 2010 which we know points to the input string.
.
.  The result gets stuffed into [%fp+1999] which we saw above was
.  preset to NULL but now it gets the resultant address after
.  strdup did the malloc.
.


************************** c++-types **************************

Yet another thing slightly off topic looking at the core dump from
c++-types I see :

Reading c++-types
core file header read successfully
Reading ld.so.1
Reading libc.so.1
Reading libc_psr.so.1
program terminated by signal SEGV (no mapping at the fault address)
0xffffffff7ed3c890: strlen+0x0050:      ld       [%o2], %o1
Current function is node_to_string
 3122                       + strlen (child1) + strlen (child2) + 1);
(dbx) where
  [1] strlen(0x10eac0, 0x9, 0x10eac0, 0x80808080, 0x0, 0x80808080), at
0xffffffff7ed3c890
=>[2] node_to_string(node = 0x10010fd10), line 3122 in "c++-types.c"
  [3] node_print(out = 0xffffffff7ef496c0, n = 0x10010fd10), line 3136
in "c++-types.c"
  [4] yyuserAction(yyrule = 3, yyrhslen = 2, yyvsp = 0x10010be60,
yystackp = 0xffffffff7fffee80, yyk = 0, yyvalp = 0xffffffff7fffec90,
yylocp = 0xffffffff7fffec80), line 1142 in "c++-types.c"
  [5] yydoAction(yystackp = 0xffffffff7fffee80, yyk = 0, yyrule = 3,
yyvalp = 0xffffffff7fffec90, yylocp = 0xffffffff7fffec80), line 1727 in
"c++-types.c"
  [6] yyglrReduce(yystackp = 0xffffffff7fffee80, yyk = 0, yyrule = 3,
yyforceEval = '\001'), line 1772 in "c++-types.c"
  [7] yyparse(), line 2715 in "c++-types.c"
  [8] process(file = 0xffffffff7ffff5d1 "-"), line 3157 in "c++-types.c"
  [9] main(argc = 2, argv = 0xffffffff7ffff278), line 3176 in "c++-types.c"
(dbx) list
 3122                       + strlen (child1) + strlen (child2) + 1);
 3123         sprintf (res, node->nterm.form, child0, child1, child2);
 3124         free (child2);
 3125         free (child1);
 3126         free (child0);
 3127       }
 3128     else
 3129       res = strdup (node->term.text);
 3130     return res;
 3131   }
(dbx) print &node
&node = 0xffffffff7fffe688
(dbx) print node
node = 0x10010fd10
(dbx) print *node
*node = {
    nodeInfo = {
        isNterm = 1
        parents = 0
    }
    nterm    = {
        isNterm  = 1
        parents  = 0
        form     = 0x10000af68 "+(%s, %s)"
        children = (0x10010fc90, 0x10010fcd0, (nil))
    }
    term     = {
        isNterm = 1
        parents = 0
        text    = 0x10000af68 "+(%s, %s)"
    }
}
(dbx)

There we see that children[2] is a NULL. So looking at the function :


  3107  static char *
  3108  node_to_string (const Node *node)
  3109  {
  3110    char *res;
  3111    if (!node)
  3112      {
  3113        res = malloc (1);
  3114        res[0] = 0;
  3115      }
  3116    else if (node->nodeInfo.isNterm == 1)
  3117      {
  3118        char *child0 = node_to_string (node->nterm.children[0]);
  3119        char *child1 = node_to_string (node->nterm.children[1]);
  3120        char *child2 = node_to_string (node->nterm.children[2]);
  3121        res = malloc (strlen (node->nterm.form) + strlen (child0)
  3122                      + strlen (child1) + strlen (child2) + 1);
  3123        sprintf (res, node->nterm.form, child0, child1, child2);
  3124        free (child2);
  3125        free (child1);
  3126        free (child0);
  3127      }
  3128    else
  3129      res = strdup (node->term.text);
  3130    return res;
  3131  }
  3132

For the sake of curiosity the other two strings are both zero length :

(dbx) x 0x10010fc90/8x
0x000000010010fc90:      0x0000 0x0000 0x0000 0x0001 0x0000 0x0001
0x0010 0xea80
(dbx) x 0x10010fcd0/8x
0x000000010010fcd0:      0x0000 0x0000 0x0000 0x0001 0x0000 0x0001
0x0010 0xeaa0
(dbx)

So that is recursive fun and strlen(child2) should be zero? Given that
it is NULL we end up at the res = malloc (1) with no checks anywhere
that the malloc even works but anyways maybe it is best to just look at
the mfcalc stuff for now.



reply via email to

[Prev in Thread] Current Thread [Next in Thread]