l i n u x - u s e r s - g r o u p - o f - d a v i s
L U G O D
 
Next Meeting:
October 20: Web Application Hacking: How to Make and Break Security on the Web
Next Installfest:
TBD
Latest News:
Oct. 10: LUGOD Installfests coming again soon
Page last updated:
2002 Sep 19 21:31

The following is an archive of a post made to our 'vox-tech mailing list' by one of its subscribers.

Report this post as spam:

(Enter your email address)
[vox-tech] bug in gcc?
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[vox-tech] bug in gcc?



with gcc version 2.96 20000731 (Red Hat Linux 7.3 2.96-112)

norm.c:

   int z;
   
   int main(void)
   {  z = 3;
      z = z + 1;
      return 0;
   }


pete.c:

   int z;
   
   int main(void)
   {
      z = 3;
      z = z + 1;
      return 0;
   }


compile the programs:

   lifshitz.ucdavis.edu% gcc -g -W -Wall -o pete pete.c
   lifshitz.ucdavis.edu% gcc -g -W -Wall -o norm norm.c


debug pete:

   lifshitz.ucdavis.edu% gdb -quiet pete
   (gdb) break main
   Breakpoint 1 at 0x80483d3: file pete.c, line 5.
   (gdb) l
   1       int z;
   2
   3       int main(void)
   4       {
   5               z = 3;      <--- break main
   6               z = z + 1;
   7               return 0;
   8       }


debug norm:

   lifshitz.ucdavis.edu% gdb -quiet norm
   (gdb) break main
   Breakpoint 1 at 0x80483dd: file norm.c, line 5.
   (gdb) l
   1       int z;
   2
   3       int main(void)
   4       {       z = 3;
   5          z = z + 1;     <--- break main
   6          return 0;
   7       }


gcc recognizes the first line of the function to be the line AFTER the
opening curly brace, whether or not there happens to be a C statement on
that line.

at first i thought maybe the compiler was optimizing the "z=3" line out
of existence.  after all, z is fully deterministic in this code, and the
compiler can easily see that in such a simplistic program.

so i wrote another function and used something that gcc can't ignore: a
function call (to printf()):


elmo.c:

   #include <stdio.h>
   int z =3;
   
   int main(void)
   {  printf("z is %d\n", z);
   
      return 0;
   }

compile elmo:

   lifshitz.ucdavis.edu% gcc -g -W -Wall -o elmo elmo.c


debug elmo:

   lifshitz.ucdavis.edu% gdb elmo
   (gdb) b main
   Breakpoint 1 at 0x804841c: file elmo.c, line 7.
   (gdb) l
   1       #include <stdio.h>
   2       int z =3;
   3
   4       int main(void)
   5       {       printf("z is %d\n", z);
   6
   7          return 0;     <--- break main
   8       }


this happens with locals too (when i first wrote this email, i thought
it didn't.  apparently, this bug doesn't exist on debian sarge's gcc
2.95).

oscar.c:

   int main(void)
   {  int z = 3;
      z = z + 1;
      return 0;
   }


compile oscar:

   lifshitz.ucdavis.edu% gcc -g -W -Wall -o oscar oscar.c 

debug oscar:

   (gdb) break main
   Breakpoint 1 at 0x80483dd: file oscar.c, line 3.
   (gdb) l
   1       int main(void)
   2       {       int z = 3;
   3          z = z + 1;            <--- break main
   4          return 0;
   5       }


looking at the assembly code:

   lifshitz.ucdavis.edu% gcc -g -S norm.c 
   lifshitz.ucdavis.edu% gcc -g -S pete.c 

norm.s:                             pete.s:

.globl main                         .globl main
   .type  main,@function               .type  main,@function
main:                               main:
   .stabn 68,0,4,.LM1-main             .stabn 68,0,4,.LM1-main
.LM1:                               .LM1:
   pushl %ebp                          pushl %ebp
   movl  %esp, %ebp                    movl  %esp, %ebp
   movl  $3, z                         .stabn 68,0,5,.LM2-main
   .stabn 68,0,5,.LM2-main          .LM2:
.LM2:                                  movl  $3, z
   incl  z                             .stabn 68,0,6,.LM3-main
   .stabn 68,0,6,.LM3-main          .LM3:
.LM3:                                  incl  z
   movl  $0, %eax                      .stabn 68,0,7,.LM4-main
   .stabn 68,0,7,.LM4-main          .LM4:
.LM4:                                  movl  $0, %eax
   popl  %ebp                          .stabn 68,0,8,.LM5-main
   ret                              .LM5:
                                       popl  %ebp
                                       ret

this shows that although the instructions are the same between norm and
pete, the debugging info is definitely different.

norm thinks that this is related to the following.  consider the
following program.  call is "ernie.s":


# sample program; does a (not very efficient) sort of the array x, using
# the algorithm (expressed in pseudo-C code notation):

# for each element x[i]
#    find the smallest element x[j] among x[i+1], x[i+2], ...
#    swap x[i] and x[j]

.equ xlength, 7

.data
x:
      .long   1
      .long   5
      .long   2
      .long   18
      .long   25
      .long   22
      .long   4

.text
.globl _start
_start:
callinit:
      call init  # initialize needed registers
      # register usage:
      #    EAX points to next place in sorted array to be determined
      #    ECX is the value currently in that spot
      #    EBX is our loop counter (number of remaining iterations)
      #    ESI points to the smallest element found via findmin
      #    EDI contains the value of that element
top:  call findmin
      mov (%eax), %ecx
      # need to swap?
      cmpl %ecx, %edi
      jge nexti
      call swap
nexti:
      decl %ebx
      jz done
      addl $4, %eax
      jmp top

done: movl %eax, %eax  # dummy, just for running in debugger

init:
      movl $x, %eax
      movl $xlength, %ebx
      decl %ebx
      ret

findmin:
      # register usage:
      #    EDX points to the current element to be compared
      #    EBP serves as our loop counter (number of remaining
      #    iterations)
      #    ECX used as scratch register (no conflict with "main")
      movl $999999, %edi
      movl %eax, %edx
      addl $4, %edx
      movl %ebx, %ebp
findminloop:
      movl (%edx), %ecx
      cmpl %ecx, %edi
      js nextj
      # we've found a new minimum
      movl %edx, %esi
      movl %ecx, %edi
nextj:
      decl %ebp
      jz donefindmin
      addl $4, %edx
      jmp findminloop
donefindmin:
      # restore old EAX value
      ret

swap:
      movl %edi, (%eax)
      movl %ecx, (%esi)
      ret

assemble and link this program with:

p@satan% as --gstabs -o ernie.o ernie.s
p@satan% ld -o ernie ernie.o


oops!!  last night, gcc and a bunch of other compiler related packages
got updated on sarge.

before last night, setting a breakpoint on _start or callinit resulted
in either a segfault for gdb or a breakpoint assigned the number "-1"
(instead of 1).

today, when i just checked, it seems to work.  of course.  i should've
posted this email last night.  :)


anyway, i'm not sure what to make of all this.  in the worst case
scenario, it seems like a minor sort of thing.   but i'm curious whether
people think this is a bug or not.

pete



-- 
Fingerprint: B9F1 6CF3 47C4 7CD8 D33E 70A9 A3B9 1945 67EA 951D
_______________________________________________
vox-tech mailing list
vox-tech@lists.lugod.org
http://lists.lugod.org/mailman/listinfo/vox-tech



LinkedIn
LUGOD Group on LinkedIn
Sign up for LUGOD event announcements
Your email address:
facebook
LUGOD Group on Facebook
'Like' LUGOD on Facebook:

Hosting provided by:
Sunset Systems
Sunset Systems offers preconfigured Linux systems, remote system administration and custom software development.

LUGOD: Linux Users' Group of Davis
PO Box 2082, Davis, CA 95617
Contact Us

LUGOD is a 501(c)7 non-profit organization
based in Davis, California
and serving the Sacramento area.
"Linux" is a trademark of Linus Torvalds.

Sponsored in part by:
Sunset Systems
Who graciously hosts our website & mailing lists!