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]

Re: Displaying structs


Ben Elliston <bje@redhat.com> writes:

Try this patch.

set print follow-pointers to the max depth you want to follow, it defaults to 0.

Then print *ptr, should follow the pointers in the structures up to
that depth.

11        dans=new dan;
(gdb) n
12        dans->next=new dan;
(gdb) p dans
$1 = (dan *) 0x8049760
(gdb) n
13        dans->prev=NULL;
(gdb) p dans
$2 = (dan *) 0x8049760
(gdb) set print follow-pointers 1
(gdb) p dans
$3 = (dan *) 0x8049760
(gdb) p dans[0]
$4 = {next = {next = 0x0, prev = 0x0}, prev = 0x0}          
(gdb) set print pretty on
(gdb) p dans[0]
$5 = {
  next = {
      next = 0x0,
      prev = 0x0
    },
  prev = 0x0
}          

Howzat for ya?
I didn't have it print the type of the pointer it's following, it
seemed like it would just waste space.

Is this useful to people?
Should i clean it up and submit it to gdb-patches?
--Dan

> Often, when debugging, I like to examine pointers to structures.  When
> examining the struct instance that the pointer is addressing, I might use:
> 
> (gdb) print/x *ptr
> 
> If the struct has fields which are further pointers to structs, I have to
> manually follow these pointers:
> 
> (gdb) print/x *ptr->next
> or
> (gdb) print/x *ptr->prev
> 
> Is there a way that GDB can recursively follow these (to some level)?  I am
> guessing that there is enough debugging information for it to know that the
> pointers are to meaningful types.
> 
> Ben
Index: c-valprint.c
===================================================================
RCS file: /cvs/src/src/gdb/c-valprint.c,v
retrieving revision 1.5
diff -c -3 -w -B -b -p -r1.5 c-valprint.c
*** c-valprint.c	2000/07/30 01:48:24	1.5
--- c-valprint.c	2000/10/07 18:32:44
***************
*** 29,34 ****
--- 29,35 ----
  #include "language.h"
  #include "c-lang.h"
  
+ extern int follow_pointers_print;
  
  /* Print data of type TYPE located at VALADDR (within GDB), which came from
     the inferior at address ADDRESS, onto stdio stream STREAM according to
*************** c_val_print (struct type *type, char *va
*** 157,166 ****
  	      return (0);
  	    }
  
! 	  if (addressprint && format != 's')
  	    {
  	      print_address_numeric (addr, 1, stream);
  	    }
  
  	  /* For a pointer to char or unsigned char, also print the string
  	     pointed to, unless pointer is null.  */
--- 158,200 ----
  	      return (0);
  	    }
  	  
! 	  if (follow_pointers_print <= recurse && follow_pointers_print != 0)
  	    {
+ 	      elttype = check_typedef (TYPE_TARGET_TYPE (type));
+ 	      if (TYPE_CODE (elttype) != TYPE_CODE_UNDEF)
+ 		{
+ 		  CORE_ADDR deref_addr =
+ 		    unpack_pointer (lookup_pointer_type (builtin_type_void),
+ 				    valaddr + embedded_offset);
+ 		  if (deref_addr == 0x0)
+ 		    fputs_filtered("0x0",stream);
+ 		  else
+ 		    { 
+ 		      value_ptr deref_val =
+ 			value_at
+ 			(TYPE_TARGET_TYPE (type),
+ 			 unpack_pointer (lookup_pointer_type (builtin_type_void),
+ 					 valaddr + embedded_offset),
+ 			 NULL);
+ 		      val_print (VALUE_TYPE (deref_val),
+ 				 VALUE_CONTENTS (deref_val),
+ 				 0,
+ 				 VALUE_ADDRESS (deref_val),
+ 				 stream,
+ 				 format,
+ 				 deref_ref,
+ 				 recurse + 1,
+ 				 pretty);
+ 		    }
+ 		}
+ 	    }
+ 	  
+ 	  else if ((addressprint && format != 's') || (follow_pointers_print >= recurse))
+ 	    {
  	      print_address_numeric (addr, 1, stream);
  	    }
+ 	  else
+ 	    fputs_filtered ("???", stream);
  	  
  	  /* For a pointer to char or unsigned char, also print the string
  	     pointed to, unless pointer is null.  */
*************** c_val_print (struct type *type, char *va
*** 254,259 ****
--- 288,300 ----
  	{
  	  if (TYPE_CODE (elttype) != TYPE_CODE_UNDEF)
  	    {
+ 	      CORE_ADDR deref_addr = unpack_pointer (lookup_pointer_type 
+ 						     (builtin_type_void), 
+ 						     valaddr + embedded_offset); 
+ 	      if (deref_addr == 0)
+ 		fputs_filtered( "NULL reference", stream);
+ 	      else
+ 		{
  		  value_ptr deref_val =
  		    value_at
  		    (TYPE_TARGET_TYPE (type),
*************** c_val_print (struct type *type, char *va
*** 269,274 ****
--- 310,316 ----
  			     deref_ref,
  			     recurse,
  			     pretty);
+ 		}
  	    }
  	  else
  	    fputs_filtered ("???", stream);
Index: cp-valprint.c
===================================================================
RCS file: /cvs/src/src/gdb/cp-valprint.c,v
retrieving revision 1.5
diff -c -3 -w -B -b -p -r1.5 cp-valprint.c
*** cp-valprint.c	2000/09/01 23:43:26	1.5
--- cp-valprint.c	2000/10/07 18:32:44
***************
*** 36,42 ****
  /* Indication of presence of HP-compiled object files */
  extern int hp_som_som_object_present;	/* defined in symtab.c */
  
! 
  int vtblprint;			/* Controls printing of vtbl's */
  int objectprint;		/* Controls looking up an object's derived type
  				   using what we find in its vtables.  */
--- 36,43 ----
  /* Indication of presence of HP-compiled object files */
  extern int hp_som_som_object_present;	/* defined in symtab.c */
  
! int follow_pointers_print;      /* Controls following of pointers
! 				   during print */  
  int vtblprint;			/* Controls printing of vtbl's */
  int objectprint;		/* Controls looking up an object's derived type
  				   using what we find in its vtables.  */
*************** _initialize_cp_valprint (void)
*** 774,779 ****
--- 775,786 ----
       &showprintlist);
    /* Turn on printing of static fields.  */
    static_field_print = 1;
+   
+   add_show_from_set
+     (add_set_cmd ("follow-pointers", class_support, var_zinteger, 
+ 		  &follow_pointers_print, 
+ 		  "Set following of pointers when printing.", &setprintlist),
+      &showprintlist);
  
    add_show_from_set
      (add_set_cmd ("vtbl", class_support, var_boolean, (char *) &vtblprint,

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