From: farrell@fjord.reo.dec.com (John M. Farrell)
Subject: Re: Emacs runs slower under GDB 4.6
Organization: Digital Equipment Corporation - UK Engineering
Distribution: gnu
Date: Fri, 4 Sep 1992 09:57:06 GMT

>>>>> On 2 Sep 92 22:57:51 GMT, jimb@occs.cs.oberlin.edu (Jim Blandy) said:

In article <9209030657.AA19781@occs.cs.oberlin.edu> jimb@occs.cs.oberlin.edu (Jim Blandy) writes:

Jim> I am debugging FSF Emacs 18.58 under GDB 4.6 on a DECstation running
Jim> Ultrix 4.2a.

Jim> Emacs 18.58 runs *much* slower under GDB 4.6 than under GDB 4.5.  I can
Jim> outtype Emacs running under GDB 4.6, but it runs at a normal speed under
Jim> GDB 4.5.

This may be related to a problem which I reported with single stepping being
very slow due to demangling of (presumed) C++ names during PC frame lookups.

Having tried to debug emacs under X myself on occasions, I know that there are
lots of SIGIO signals flying around. If gdb is intercepting these and doing PC
frame lookups before continuing the target, it may be a similar problem.

I never saw my original posting appear, so here it is again, with fix:

--- Start forwarded message ---
Newsgroups: gnu.gdb.bug
Subject: GDB 4.6 fix for slow stepping on mips
Distribution: gnu

I'm running GDB 4.6 on a DECstation and have noticed that the step and next
commands run very slowly on large programs.

The problem turns out to be that the mips symbol table routines generate a
static label with the name ".gdbinfo." in every function, and uses it to store
information such as number of arguments and frame offsets.

During single stepping, a lookup is done on this symbol name after every
instruction in order to obtain information about the frame in which the target
has stopped. Unfortunately, when lookup_symbol() sees the character '.' in a
symbol, it thinks it must be demangled C++ symbol and invokes the
expensive_mangler() on it. As the name of the routine suggests, this is not a
good thing to do for every instruction!

The following patch fixes the problem by using the name "__gdbinfo__" rather
than ".gdbinfo." for the special entry.


-- start cut --
*** 4.6-mipsread.c	Mon Jul  6 18:10:58 1992
--- mipsread.c	Wed Jul 29 19:13:33 1992
***************
*** 1253,1259 ****
  
  		    /* Make up special symbol to contain procedure specific
  		       info */
! 		    s = new_symbol(".gdbinfo.");
  		    SYMBOL_NAMESPACE(s) = LABEL_NAMESPACE;
  		    SYMBOL_CLASS(s) = LOC_CONST;
  		    SYMBOL_TYPE(s) = builtin_type_void;
--- 1253,1259 ----
  
  		    /* Make up special symbol to contain procedure specific
  		       info */
! 		    s = new_symbol("__gdbinfo__");
  		    SYMBOL_NAMESPACE(s) = LABEL_NAMESPACE;
  		    SYMBOL_CLASS(s) = LOC_CONST;
  		    SYMBOL_TYPE(s) = builtin_type_void;
***************
*** 1622,1628 ****
  
  /* Parse a procedure descriptor record PR.  Note that the procedure
     is parsed _after_ the local symbols, now we just insert the extra
!    information we need into a special ".gdbinfo." symbol that has already
     been placed in the procedure's main block.  Note also that images that
     have been partially stripped (ld -x) have been deprived
     of local symbols, and we have to cope with them here.
--- 1622,1628 ----
  
  /* Parse a procedure descriptor record PR.  Note that the procedure
     is parsed _after_ the local symbols, now we just insert the extra
!    information we need into a special "__gdbinfo__" symbol that has already
     been placed in the procedure's main block.  Note also that images that
     have been partially stripped (ld -x) have been deprived
     of local symbols, and we have to cope with them here.
***************
*** 1677,1683 ****
  #endif
      }
  
!     i = mylookup_symbol(".gdbinfo.", b, LABEL_NAMESPACE, LOC_CONST);
  
      if (i)
        {
--- 1677,1683 ----
  #endif
      }
  
!     i = mylookup_symbol("__gdbinfo__", b, LABEL_NAMESPACE, LOC_CONST);
  
      if (i)
        {
***************
*** 2377,2383 ****
  		      (struct mips_extra_func_info *)
  			obstack_alloc(&current_objfile->symbol_obstack,
  				      sizeof(struct mips_extra_func_info));
! 		    struct symbol *s = new_symbol(".gdbinfo.");
  		    SYMBOL_NAMESPACE(s) = LABEL_NAMESPACE;
  		    SYMBOL_CLASS(s) = LOC_CONST;
  		    SYMBOL_TYPE(s) = builtin_type_void;
--- 2377,2383 ----
  		      (struct mips_extra_func_info *)
  			obstack_alloc(&current_objfile->symbol_obstack,
  				      sizeof(struct mips_extra_func_info));
! 		    struct symbol *s = new_symbol("__gdbinfo__");
  		    SYMBOL_NAMESPACE(s) = LABEL_NAMESPACE;
  		    SYMBOL_CLASS(s) = LOC_CONST;
  		    SYMBOL_TYPE(s) = builtin_type_void;
***************
*** 3005,3011 ****
  				   (struct objfile *) NULL);
  	TYPE_TARGET_TYPE(SYMBOL_TYPE(s)) = builtin_type_void;
  
! 	/* Need a block to allocate .gdbinfo. in */
  	b = new_block(1);
  	SYMBOL_BLOCK_VALUE(s) = b;
  	BLOCK_START(b) = sigtramp_address;
--- 3005,3011 ----
  				   (struct objfile *) NULL);
  	TYPE_TARGET_TYPE(SYMBOL_TYPE(s)) = builtin_type_void;
  
! 	/* Need a block to allocate __gdbinfo__ in */
  	b = new_block(1);
  	SYMBOL_BLOCK_VALUE(s) = b;
  	BLOCK_START(b) = sigtramp_address;
***************
*** 3015,3021 ****
  	add_block(b, st);
  	sort_blocks(st);
  
! 	/* Make a .gdbinfo. for it */
  	{
  		struct mips_extra_func_info *e =
  			(struct mips_extra_func_info *)
--- 3015,3021 ----
  	add_block(b, st);
  	sort_blocks(st);
  
! 	/* Make a __gdbinfo__ for it */
  	{
  		struct mips_extra_func_info *e =
  			(struct mips_extra_func_info *)
***************
*** 3033,3039 ****
  		e->pdr.isym = (long)s;
  
  		current_objfile = st->objfile; /* Keep new_symbol happy */
! 		s = new_symbol(".gdbinfo.");
  		SYMBOL_VALUE(s) = (int) e;
  		SYMBOL_NAMESPACE(s) = LABEL_NAMESPACE;
  		SYMBOL_CLASS(s) = LOC_CONST;
--- 3033,3039 ----
  		e->pdr.isym = (long)s;
  
  		current_objfile = st->objfile; /* Keep new_symbol happy */
! 		s = new_symbol("__gdbinfo__");
  		SYMBOL_VALUE(s) = (int) e;
  		SYMBOL_NAMESPACE(s) = LABEL_NAMESPACE;
  		SYMBOL_CLASS(s) = LOC_CONST;
*** 4.6-mips-tdep.c	Tue Jul 14 08:35:46 1992
--- mips-tdep.c	Wed Jul 29 19:13:35 1992
***************
*** 231,237 ****
    mips_extra_func_info_t proc_desc;
    struct block *b = block_for_pc(pc);
    struct symbol *sym =
!       b ? lookup_symbol(".gdbinfo.", b, LABEL_NAMESPACE, 0, NULL) : NULL;
  
    if (sym)
      {
--- 231,237 ----
    mips_extra_func_info_t proc_desc;
    struct block *b = block_for_pc(pc);
    struct symbol *sym =
!       b ? lookup_symbol("__gdbinfo__", b, LABEL_NAMESPACE, 0, NULL) : NULL;
  
    if (sym)
      {
***************
*** 789,795 ****
      b = block_for_pc(pc);
      if (!b) return pc;
  
!     f = lookup_symbol(".gdbinfo.", b, LABEL_NAMESPACE, 0, NULL);
      if (!f) return pc;
      /* Ideally, I would like to use the adjusted info
         from mips_frame_info(), but for all practical
--- 789,795 ----
      b = block_for_pc(pc);
      if (!b) return pc;
  
!     f = lookup_symbol("__gdbinfo__", b, LABEL_NAMESPACE, 0, NULL);
      if (!f) return pc;
      /* Ideally, I would like to use the adjusted info
         from mips_frame_info(), but for all practical

-- end cut --

--- End forwarded message ---
--
John M. Farrell                 | Internet: farrell@fjord.reo.dec.com
Digital Equipment Corporation   | 
P.O. Box 121                    | "One foot in the grave, 
Reading, RG1 0TU, UK.           |  and one foot on the pedal", TP     

Newsgroups: gnu.gdb.bug