This is the mail archive of the gdb-patches@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: gdb 5.0 cannot print contents of 'string'



First off, take this patch, apply it to current CVS.
It should make your memory usage under dwarf2 less than stabs.

Without it, it takes 116 megs, 0 shared just to load in the
executable.
With it, it takes 83 megs, 76 shared to load it in.

This is a combination of using a bfd function that knows how to mmap
files when mmap is available, rather than allocating a buffer to read
the entire darn dwarf2 section in, and having gdb remove duplicate
debug info on read in for psymbols and symbols as well (it used to do
just types).

You need to configure bfd with --with-mmap for this patch to work
properly.

Does anyone know why USE_MMAP isn't the default when we have mmap in
bfd?

Is it acceptable to #if USE_MMAP the file_window stuff from bfd i'm
using in dwarf2read.c (I know it's the right test, since that's what
BFD uses), and fall back to allocating a huge chunk of memory if
USE_MMAP isn't defined?

It makes a huge difference when you have large executables.

I've attached the patch in case anyone else wants to try it, i'll
formally submit it when i get the chance to clean it up a little.


I'll have an update on the string problem when i get a little free
time.

--Dan

Index: dwarf2read.c
===================================================================
RCS file: /cvs/src/src/gdb/dwarf2read.c,v
retrieving revision 1.16
diff -c -3 -p -r1.16 dwarf2read.c
*** dwarf2read.c	2000/08/04 16:51:47	1.16
--- dwarf2read.c	2000/09/14 04:49:25
*************** struct dwarf_block
*** 260,266 ****
  /* We only hold one compilation unit's abbrevs in
     memory at any one time.  */
  #ifndef ABBREV_HASH_SIZE
! #define ABBREV_HASH_SIZE 121
  #endif
  #ifndef ATTR_ALLOC_CHUNK
  #define ATTR_ALLOC_CHUNK 4
--- 260,266 ----
  /* We only hold one compilation unit's abbrevs in
     memory at any one time.  */
  #ifndef ABBREV_HASH_SIZE
! #define ABBREV_HASH_SIZE 1024
  #endif
  #ifndef ATTR_ALLOC_CHUNK
  #define ATTR_ALLOC_CHUNK 4
*************** static struct abbrev_info *dwarf2_abbrev
*** 270,282 ****
  
  /* A hash table of die offsets for following references.  */
  #ifndef REF_HASH_SIZE
! #define REF_HASH_SIZE 1021
  #endif
  
  static struct die_info *die_ref_table[REF_HASH_SIZE];
  
  #ifndef TYPE_HASH_SIZE
! #define TYPE_HASH_SIZE 4096
  #endif
  static struct type *dwarf2_cached_types[TYPE_HASH_SIZE];
  
--- 270,296 ----
  
  /* A hash table of die offsets for following references.  */
  #ifndef REF_HASH_SIZE
! #define REF_HASH_SIZE 10240
  #endif
  
  static struct die_info *die_ref_table[REF_HASH_SIZE];
+ /* BFD window table */
+ #ifndef WINDOW_TABLE_SIZE
+ #define WINDOW_TABLE_SIZE 10240 
+ #endif
+ static bfd_window *window_table[WINDOW_TABLE_SIZE];
+ #ifndef PSYMBOL_HASH_SIZE
+ #define PSYMBOL_HASH_SIZE 10240
+ #endif
+ static struct partial_die_info *dwarf2_cached_psymbols[PSYMBOL_HASH_SIZE];
+ 
+ #ifndef SYMBOL_HASH_SIZE
+ #define SYMBOL_HASH_SIZE 10240
+ #endif
+ static struct symbol *dwarf2_cached_symbols[SYMBOL_HASH_SIZE];
  
  #ifndef TYPE_HASH_SIZE
! #define TYPE_HASH_SIZE 10240
  #endif
  static struct type *dwarf2_cached_types[TYPE_HASH_SIZE];
  
*************** add_partial_symbol (struct partial_die_i
*** 1181,1187 ****
  		    const struct comp_unit_head *cu_header)
  {
    CORE_ADDR addr = 0;
! 
    switch (pdi->tag)
      {
      case DW_TAG_subprogram:
--- 1195,1215 ----
  		    const struct comp_unit_head *cu_header)
  {
    CORE_ADDR addr = 0;
!   if (pdi->name != NULL)
!   {
! 	  /* This will be wrong for C++ if this routine starts processing things
! 	     besides top level symbols. 
! 	   */
! 	  if (cu_language == language_cplus)
! 	  {
! 		  unsigned long hashval = hash(pdi->name, strlen(pdi->name)) % PSYMBOL_HASH_SIZE;
! 		  if (dwarf2_cached_psymbols[hashval] != NULL)
! 			  if (!strcmp(dwarf2_cached_psymbols[hashval]->name, 
! 						  pdi->name))
! 				  return;
! 		  dwarf2_cached_psymbols[hashval]=pdi;
! 	  }
!   }
    switch (pdi->tag)
      {
      case DW_TAG_subprogram:
*************** dwarf2_read_section (struct objfile *obj
*** 2978,2987 ****
  {
    bfd *abfd = objfile->obfd;
    char *buf;
! 
    if (size == 0)
      return NULL;
  
    buf = (char *) obstack_alloc (&objfile->psymbol_obstack, size);
    if ((bfd_seek (abfd, offset, SEEK_SET) != 0) ||
        (bfd_read (buf, size, 1, abfd) != size))
--- 3006,3029 ----
  {
    bfd *abfd = objfile->obfd;
    char *buf;
!   bfd_window *file_window;
!   unsigned long hashval;
    if (size == 0)
      return NULL;
+   hashval = hash(objfile, sizeof (struct objfile)) % WINDOW_TABLE_SIZE;
+   if (window_table[hashval] == NULL)
+   {
+ 	  window_table[hashval]=obstack_alloc(&objfile->psymbol_obstack, sizeof( bfd_window));
+ 	  bfd_init_window(window_table[hashval]);
+   }
+   file_window=window_table[hashval];
+   if (bfd_get_file_window(abfd, offset, size, file_window, false) == false)
+ 	  error("Dwarf Error: Can't read DWARF data from '%s'", 
+ 			  bfd_get_filename(abfd));
+   buf=file_window->data;
  
+ /* Try using the file window functions, which lets bfd use mmap */
+ #if 0
    buf = (char *) obstack_alloc (&objfile->psymbol_obstack, size);
    if ((bfd_seek (abfd, offset, SEEK_SET) != 0) ||
        (bfd_read (buf, size, 1, abfd) != size))
*************** dwarf2_read_section (struct objfile *obj
*** 2990,2995 ****
--- 3032,3038 ----
        error ("Dwarf Error: Can't read DWARF data from '%s'",
  	     bfd_get_filename (abfd));
      }
+ #endif
    return buf;
  }
  
*************** new_symbol (struct die_info *die, struct
*** 4089,4100 ****
    struct attribute *attr = NULL;
    struct attribute *attr2 = NULL;
    CORE_ADDR addr;
! 
    name = dwarf2_linkage_name (die);
    if (name)
      {
        sym = (struct symbol *) obstack_alloc (&objfile->symbol_obstack,
  					     sizeof (struct symbol));
        OBJSTAT (objfile, n_syms++);
        memset (sym, 0, sizeof (struct symbol));
        SYMBOL_NAME (sym) = obsavestring (name, strlen (name),
--- 4132,4155 ----
    struct attribute *attr = NULL;
    struct attribute *attr2 = NULL;
    CORE_ADDR addr;
!   unsigned long hashval;
    name = dwarf2_linkage_name (die);
    if (name)
      {
+ 	    /* This works for C++, because SYMBOL_NAME will give us the mangled identifier, which must always represent the same thing in a given program, otherwise you have violated the one definition rule.*/
+ 	 if (cu_language == language_cplus)
+ 	 {
+ 		 hashval=hash(name, strlen(name)) % SYMBOL_HASH_SIZE;
+ 		 if (dwarf2_cached_symbols[hashval] != NULL)
+ 		 {
+ 			 if (!strcmp(SYMBOL_NAME(dwarf2_cached_symbols[hashval]), name))
+ 				 return dwarf2_cached_symbols[hashval];
+ 		 }
+ 	 }
        sym = (struct symbol *) obstack_alloc (&objfile->symbol_obstack,
  					     sizeof (struct symbol));
+       if (current_language->la_language == language_cplus)
+ 	      dwarf2_cached_symbols[hashval]=sym;
        OBJSTAT (objfile, n_syms++);
        memset (sym, 0, sizeof (struct symbol));
        SYMBOL_NAME (sym) = obsavestring (name, strlen (name),
*************** dwarf2_empty_hash_tables (void)
*** 5601,5606 ****
--- 5656,5663 ----
  {
    memset (die_ref_table, 0, sizeof (die_ref_table));
    memset (dwarf2_cached_types, 0, sizeof(dwarf2_cached_types));
+   memset (dwarf2_cached_symbols, 0, sizeof(dwarf2_cached_symbols));
+   memset (dwarf2_cached_psymbols, 0, sizeof(dwarf2_cached_psymbols));
  }
  
  static unsigned int


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