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]
Other format: [Raw text]

Re: [RFA] Runtime Dwarf2 CFI engine cleanup


Michal Ludvig writes:
 > Hi all,
 > the attached is a fix for the problem described here:
 > http://sources.redhat.com/ml/gdb/2002-12/msg00246.html
 > 
 > I've created a new function cleanup_cfi() in dwarf2cfi.c that deletes 
 > all CIEs and FDEs of objfiles removed later by objfile_purge_solibs().
 > So far it works fine but I don't know how should I correctly call it.


I have tried your function, and it does fixes some weird errors which occur
on rerun. 

I just tried by using the hack of defining GDB_TARGET_IS_X86_64, which
is definitely a bad thing.

I think that the best way is to define a gdbarch method, just like it
was done for gdbarch_dwarf2_build_frame_info.

In the patch below, you cannot use printf's. Use printf_filtered. But
maybe, better yet, using a warning here would be more appropriate.

Watch out for the non-GNU indentation and spacing.

elena

 > For now I put the call directly to run_command():
 > 
 > static void
 > run_command (char *args, int from_tty)
 > {
 >    [...]
 >    clear_breakpoint_hit_counts ();
 > 
 >    cleanup_cfi ();    /* <=== HERE */
 > 
 >    objfile_purge_solibs ();
 > 
 >    do_run_cleanups (NULL);
 > 
 >    reopen_exec_file ();
 >    reread_symbols ();
 >    [...]
 > }
 > 
 > I know it isn't the right solution because it would require linking of 
 > dwarf2cfi.o to all targets. If I would wrap it by #ifdef X86_64 ... 
 > #endif it still isn't perfect, because other archs will hopefully use 
 > CFI in the future as well.
 > 
 > I was thinking about defining something like USE_DWARF2CFI for each 
 > target that use it in their config/whatever file...? Is it a way to go?
 > 
 > I can't attach this function to run_cleanup_chain, because I need to 
 > call cleanup_cfi() before objfile_purge_solibs() and also because 
 > do_run_cleanups() finally destroys the contents of run_cleanup_chain and 
 > finally because I don't know how (when/where) to attach cleanup_cfi() to 
 > run_cleanup_chain.
 > 
 > Could someone please tell me what is the cleanest way to call 
 > cleanup_cfi()? Thanks.
 > 
 > Michal Ludvig
 > -- 
 > * SuSE CR, s.r.o     * mludvig@suse.cz
 > * (+420) 296.545.373 * http://www.suse.cz
 > Index: dwarf2cfi.h
 > ===================================================================
 > RCS file: /cvs/src/src/gdb/dwarf2cfi.c,v
 > retrieving revision 1.16
 > diff -u -p -r1.16 dwarf2cfi.h
 > --- dwarf2cfi.h	19 Jul 2002 09:40:51 -0000	1.16
 > +++ dwarf2cfi.h	20 Dec 2002 15:14:21 -0000
 > @@ -64,6 +64,12 @@ struct cie_unit
 >  
 >    /* Next in chain.  */
 >    struct cie_unit *next;
 > +
 > +  /* Keep or destroy this CIE on a new run? */
 > +  int keep;
 > +
 > +  /* How many FDEs refer to this CIE? */
 > +  int refs;
 >  };
 >  
 >  /* Frame Description Entry.  */
 > Index: dwarf2cfi.c
 > ===================================================================
 > RCS file: /cvs/src/src/gdb/dwarf2cfi.c,v
 > retrieving revision 1.16
 > diff -u -p -r1.16 dwarf2cfi.c
 > --- dwarf2cfi.c	19 Jul 2002 09:40:51 -0000	1.16
 > +++ dwarf2cfi.c	20 Dec 2002 15:14:21 -0000
 > @@ -317,6 +326,86 @@ frame_state_alloc (void)
 >      (struct frame_state_reg *) obstack_alloc (&unwind_tmp_obstack, regs_size);
 >    memset (fs->regs.reg, 0, regs_size);
 >    return fs;
 > +}
 > +
 > +void
 > +cleanup_cfi (void *name)
 > +{
 > +  struct objfile *ofp;
 > +  struct cie_unit *cie, *cie_prev;
 > +  int fde_index=0, fde_free=0;
 > +  
 > +  cie = cie_chunks;
 > +  while (cie)
 > +  {
 > +	  cie->refs = 0;
 > +	  cie->keep = 0;
 > +	  cie = cie->next;
 > +  }
 > +
 > +  /* Mark all unwanted CIEs. */
 > +  ALL_OBJFILES (ofp)
 > +  {
 > +	  if (!(ofp->flags & OBJF_USERLOADED) && (ofp->flags & OBJF_SHARED))
 > +		  printf ("\tRemoving %s...\n", ofp->name);
 > +	  else
 > +	  {
 > +		  printf ("\tKeeping %s...\n", ofp->name);
 > +		  cie = cie_chunks;
 > +		  while(cie)
 > +		  {
 > +			  if (cie->objfile == ofp)
 > +				  cie->keep = 1;
 > +			  cie = cie->next;
 > +		  }
 > +	  }
 > +  }
 > +
 > +  /* Remove all FDEs pointing to unwanted CIEs. */
 > +  for (fde_index = 0, fde_free=0; 
 > +	fde_index < fde_chunks.elems; 
 > +	fde_index++, fde_free++)
 > +  {
 > +	  if (!fde_chunks.array[fde_index]->cie_ptr->keep)
 > +	  {
 > +		  fde_free--;
 > +		  continue;
 > +	  }
 > +	  else if (fde_free < fde_index)
 > +		  fde_chunks.array[fde_free] = fde_chunks.array[fde_index];
 > +	  fde_chunks.array[fde_free]->cie_ptr->refs++;
 > +  }
 > +  fde_chunks.elems = fde_free;
 > +
 > +  /* Remove all unwanted CIEs. */
 > +  cie = cie_chunks;
 > +  cie_prev = NULL;
 > +  while (cie)
 > +  {
 > +	  struct cie_unit *cie_tmp;
 > +	  
 > +	  if (! cie->keep || !cie->refs)
 > +	  {
 > +		  cie_tmp = cie;
 > +		  if (cie_prev == NULL)
 > +		  {
 > +			  cie_chunks = cie->next;
 > +			  cie = cie_chunks;
 > +		  }
 > +		  else 
 > +		  {
 > +			  cie_prev->next = cie->next;
 > +			  cie = cie->next;
 > +		  }
 > +		  /* cie_prev must remain unchanged. */
 > +		  xfree (cie_tmp);
 > +	  }
 > +	  else
 > +	  {
 > +		  cie_prev = cie;
 > +		  cie = cie->next;
 > +	  }
 > +  }
 >  }
 >  
 >  static void


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