This is the mail archive of the gcc-bugs@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

c/5290: Miscompilation of GDB on i386



>Number:         5290
>Category:       c
>Synopsis:       Miscompilation of GDB on i386
>Confidential:   no
>Severity:       serious
>Priority:       medium
>Responsible:    unassigned
>State:          open
>Class:          wrong-code
>Submitter-Id:   net
>Arrival-Date:   Sun Jan 06 07:16:00 PST 2002
>Closed-Date:
>Last-Modified:
>Originator:     Mark Kettenis
>Release:        3.1 20020105 (experimental)
>Organization:
>Environment:
System: FreeBSD elgar.kettenis.dyndns.org 4.4-RELEASE FreeBSD 4.4-RELEASE #3: Thu Jan 3 09:44:07 CET 2002 kettenis@elgar.local:/usr/obj/usr/src/sys/ELGAR i386
host: i386-unknown-freebsd4.4
build: i386-unknown-freebsd4.4
target: i386-unknown-freebsd4.4
configured with: ../../src/gcc/configure --prefix=/home/kettenis/opt/gcc
>Description:

Running "gcc -g -O2 -S" on the code below produces wrong-code.  The
function partial_memory_read() is called with a bogus value for its
second argument.  Apparently the variable bufptr, which according to
the debug info lives in %ebx, isn't initialized correctly.  The
following fragment shows that indeed %ebx is passed as the second
argument:

	.loc 1 123 0
	leal	-16(%ebp), %eax
	pushl	%eax
	imull	%edi, %esi
	pushl	%esi
	pushl	%ebx
	pushl	8(%ebp)
	call	partial_memory_read

I also recognize the addition of "bufsize * width" from line 119:

	  bufptr = buffer + bufsize * width;

in the generated assembly (a few lines up from the previous fragment).

	.loc 1 119 0
	movl	-40(%ebp), %eax
	imull	%edi, %eax
	addl	%eax, %ebx

However, the code that initializes %ebx (presumably with the contents
of buffer which is allocated by xrealloc(), which lives at -32(%ebp))
is missing.

The problem disappears when compiling with -O1.  I first noted this
bug around december 28, but it may have been present a long time
before, since it's been a while since I last tried to compile GDB with
mainline GCC.
	
>How-To-Repeat:

Run "gcc -g -O2 -S" on the following preprocessor output (generated
from a trimmed down GDB source file, so it's GPL'ed):

# 1 "valprint.c"
# 1 "<built-in>"
# 1 "<command line>"
# 1 "valprint.c"





typedef unsigned int size_t;







typedef long CORE_ADDR;
typedef unsigned long long ULONGEST;
typedef void (make_cleanup_ftype) (void *);

struct cleanup;
struct ui_file;

extern void discard_cleanups (struct cleanup *);
extern ULONGEST extract_unsigned_integer (void *, int);
extern void do_cleanups (struct cleanup *);
extern void fprintf_filtered (struct ui_file *, const char *, ...);
extern void fputs_filtered (const char *, struct ui_file *);
extern void gdb_flush (struct ui_file *);
extern struct cleanup *make_cleanup (make_cleanup_ftype *, void *);
extern void null_cleanup (void *);
extern void print_address_numeric (CORE_ADDR, int, struct ui_file *);
extern void quit (void);
extern char *safe_strerror (int);
extern int target_read_memory (CORE_ADDR memaddr, char *myaddr, int len);
extern void xfree (void *);
extern void *xmalloc (size_t);
extern void *xrealloc (void *, size_t);

extern int addressprint;
extern void (*interactive_hook) (void);
unsigned int print_max;
extern int quit_flag;

static int
partial_memory_read (CORE_ADDR memaddr, char *myaddr, int len, int *errnoptr)
{
  return 0;
}

int
val_print_string (CORE_ADDR addr, int len, int width, struct ui_file *stream)
{
  int force_ellipsis = 0;
  int errcode;
  unsigned int fetchlimit;
  unsigned int nfetch;
  unsigned int chunksize;
  char *buffer = 0;
  char *bufptr;
  char *limit;
  struct cleanup *old_chain = 0;
  int found_nul;
# 70 "valprint.c"
  fetchlimit = (len == -1 ? print_max : ((len) < (print_max) ? (len) : (print_max)));
# 81 "valprint.c"
  chunksize = (len == -1 ? ((8) < (fetchlimit) ? (8) : (fetchlimit)) : fetchlimit);




  found_nul = 0;
  old_chain = make_cleanup (null_cleanup, 0);
# 103 "valprint.c"
    if (len == -1)
    {
      unsigned long bufsize = 0;
      do
        {
          nfetch = ((chunksize) < (fetchlimit - bufsize) ? (chunksize) : (fetchlimit - bufsize));

          if (buffer == 0)
            buffer = (char *) xmalloc (nfetch * width);
          else
            {
              discard_cleanups (old_chain);
              buffer = (char *) xrealloc (buffer, (nfetch + bufsize) * width);
            }

          old_chain = make_cleanup (xfree, buffer);
          bufptr = buffer + bufsize * width;
          bufsize += nfetch;


          nfetch = partial_memory_read (addr, bufptr, nfetch * width, &errcode)
            / width;







          limit = bufptr + nfetch * width;
          while (bufptr < limit)
            {
              unsigned long c;

              c = extract_unsigned_integer (bufptr, width);
              addr += width;
              bufptr += width;
              if (c == 0)
                {


                  errcode = 0;
                  found_nul = 1;
                  break;
                }
            }
        }
      while (errcode == 0
             && bufptr - buffer < fetchlimit * width
             && !found_nul);
    }
  else
    {
      buffer = bufptr = 0;
      errcode = 0;
    }
# 219 "valprint.c"
  return ((bufptr - buffer) / width);
}


>Fix:
	

>Release-Note:
>Audit-Trail:
>Unformatted:


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]