This is the mail archive of the gdb@sources.redhat.com mailing list for the GDB 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]

[RFA]: Patch for regression with huge integer


Jeff Johnston wrote:
Andrew Cagney wrote:


(gdb) print /x int256var
$2 = 0x0000002a0000002b0000002c0000002d0000002d0000002c0000002b0000002a


But with the recent simplification to print_scalar_formatted, gdb HEAD says:

(gdb) print int256var
$1 = 0x0000002a0000002b0000002c0000002d0000002d0000002c0000002b0000002a
(gdb) print /x int256var
$2 = That operation is not available on integers of more than 8 bytes.


This causes a regression in the test results.




Jeff and I looked at the problem.

Given some sort of very large scalar _and_ a scalar format, I think GDB can correctly print it. Looking at the old 60 code, this:

  if (len > sizeof (LONGEST)
      && (format == 't'
          || format == 'c'
          || format == 'o'
          || format == 'u'
          || format == 'd'
          || format == 'x'))
    {
      if (!TYPE_UNSIGNED (type)
          || !extract_long_unsigned_integer (valaddr, len, &val_long))
        {
          /* We can't print it normally, but we can print it in hex.
             Printing it in the wrong radix is more useful than saying
             "use /x, you dummy".  */
          /* FIXME:  we could also do octal or binary if that was the
             desired format.  */
          /* FIXME:  we should be using the size field to give us a
             minimum field width to print.  */

          if (format == 'o')
            print_octal_chars (stream, valaddr, len);
          else if (format == 'd')
            print_decimal_chars (stream, valaddr, len);
          else if (format == 't')
            print_binary_chars (stream, valaddr, len);
          else
            /* replace with call to print_hex_chars? Looks
               like val_print_type_code_int is redoing
               work.  - edie */

val_print_type_code_int (type, valaddr, stream);

would just need to be seriously reduced to something like:

    if (len > sizeof (LONGEST)
        && some sort of scalar (TYPE)
        && some sort of scalar (FORMAT))
      if (format == ..)           print_FORMAT_chars (...);
      ...
      else if (format == 'x')
         print_hex_chars (...);
          else
        we've botched it -- don't call val_print_type_code_int

where each format is explicitly handled. ...

The only one that appears to be missing is 'c', and there something very similar to print_hex_chars would do the trick (using LA_EMIT_CHAR).

It might even, eventually, be possible to simplify this code to the point where all scalar formatted scalars are always printed directly from their byte buffer (no unpack longest call).

Andrew




I'll start working on a patch and submit it for review.


-- Jeff J.



Ok to commit? I added a function to print out the char format. It does not print out leading zero bytes. Thus, if you set some large integer value to 'a', it would print out just 'a'.


I have verified this fixes the regression in gdb.stabs/weird.exp

2004-02-26 Jeff Johnston <jjohnstn@redhat.com>

        * valprint.h (print_hex_chars, print_char_chars): New prototypes.
        * valprint.c (print_hex_chars): Change from static to external.
        (print_char_chars): New function.
        * printcmd.c (print_scalar_formatted): For integer and enum types
        that are longer than LONGEST, perform processing via appropriate
        print_*_chars routines.


Index: valprint.h
===================================================================
RCS file: /cvs/src/src/gdb/valprint.h,v
retrieving revision 1.4
diff -u -p -r1.4 valprint.h
--- valprint.h	6 Apr 2003 19:25:04 -0000	1.4
+++ valprint.h	26 Feb 2004 22:07:15 -0000
@@ -63,4 +63,10 @@ extern void print_octal_chars (struct ui
 
 extern void print_decimal_chars (struct ui_file *, unsigned char *,
 				 unsigned int);
+
+extern void print_hex_chars (struct ui_file *, unsigned char *,
+			     unsigned int);
+
+extern void print_char_chars (struct ui_file *, unsigned char *,
+			      unsigned int);
 #endif
Index: valprint.c
===================================================================
RCS file: /cvs/src/src/gdb/valprint.c,v
retrieving revision 1.31
diff -u -p -r1.31 valprint.c
--- valprint.c	21 Sep 2003 01:26:45 -0000	1.31
+++ valprint.c	26 Feb 2004 22:07:15 -0000
@@ -42,9 +42,6 @@
 static int partial_memory_read (CORE_ADDR memaddr, char *myaddr,
 				int len, int *errnoptr);
 
-static void print_hex_chars (struct ui_file *, unsigned char *,
-			     unsigned int);
-
 static void show_print (char *, int);
 
 static void set_print (char *, int);
@@ -846,7 +843,7 @@ print_decimal_chars (struct ui_file *str
 
 /* VALADDR points to an integer of LEN bytes.  Print it in hex on stream.  */
 
-static void
+void
 print_hex_chars (struct ui_file *stream, unsigned char *valaddr, unsigned len)
 {
   unsigned char *p;
@@ -873,6 +870,40 @@ print_hex_chars (struct ui_file *stream,
 	}
     }
   fputs_filtered (local_hex_format_suffix (), stream);
+}
+
+/* VALADDR points to a char integer of LEN bytes.  Print it out in appropriate language form on stream.  
+   Omit any leading zero chars.  */
+
+void
+print_char_chars (struct ui_file *stream, unsigned char *valaddr, unsigned len)
+{
+  unsigned char *p;
+
+  if (TARGET_BYTE_ORDER == BFD_ENDIAN_BIG)
+    {
+      p = valaddr;
+      while (p < valaddr + len - 1 && *p == 0)
+	++p;
+
+      while (p < valaddr + len)
+	{
+	  LA_EMIT_CHAR (*p, stream, '\'');
+	  ++p;
+	}
+    }
+  else
+    {
+      p = valaddr + len - 1;
+      while (p > valaddr && *p == 0)
+	--p;
+
+      while (p >= valaddr)
+	{
+	  LA_EMIT_CHAR (*p, stream, '\'');
+	  --p;
+	}
+    }
 }
 
 /*  Called by various <lang>_val_print routines to print elements of an
Index: printcmd.c
===================================================================
RCS file: /cvs/src/src/gdb/printcmd.c,v
retrieving revision 1.76
diff -u -p -r1.76 printcmd.c
--- printcmd.c	23 Feb 2004 19:41:47 -0000	1.76
+++ printcmd.c	26 Feb 2004 22:07:15 -0000
@@ -350,6 +350,33 @@ print_scalar_formatted (void *valaddr, s
   LONGEST val_long = 0;
   unsigned int len = TYPE_LENGTH (type);
 
+  if (len > sizeof(LONGEST) &&
+      (TYPE_CODE (type) == TYPE_CODE_INT ||
+       TYPE_CODE (type) == TYPE_CODE_ENUM))
+    {
+      switch (format)
+	{
+	case 'o':
+	  print_octal_chars (stream, valaddr, len);
+	  return;
+	case 'u':
+	case 'd':
+	  print_decimal_chars (stream, valaddr, len);
+	  return;
+	case 't':
+	  print_binary_chars (stream, valaddr, len);
+	  return;
+	case 'x':
+	  print_hex_chars (stream, valaddr, len);
+	  return;
+	case 'c':
+	  print_char_chars (stream, valaddr, len);
+	  return;
+	default:
+	  break;
+	};
+    }
+
   if (format != 'f')
     val_long = unpack_long (type, valaddr);
 

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