mirror of
				https://github.com/espressif/binutils-gdb.git
				synced 2025-11-04 06:37:06 +08:00 
			
		
		
		
	2011-10-12 Gary Benson <gbenson@redhat.com>
* breakpoint.h (pc_at_non_inline_function): Declare. * breakpoint.c (is_non_inline_function, pc_at_non_inline_function): New functions. * infrun.c (handle_inferior_event): Don't call skip_inline_frames if the stop is at a location where functions cannot be inlined.
This commit is contained in:
		@ -1,3 +1,11 @@
 | 
				
			|||||||
 | 
					2011-10-12  Gary Benson  <gbenson@redhat.com>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						* breakpoint.h (pc_at_non_inline_function): Declare.
 | 
				
			||||||
 | 
						* breakpoint.c (is_non_inline_function,
 | 
				
			||||||
 | 
						pc_at_non_inline_function): New functions.
 | 
				
			||||||
 | 
						* infrun.c (handle_inferior_event): Don't call skip_inline_frames
 | 
				
			||||||
 | 
						if the stop is at a location where functions cannot be inlined.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
2011-10-12  Pedro Alves  <pedro@codesourcery.com>
 | 
					2011-10-12  Pedro Alves  <pedro@codesourcery.com>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	* linux-nat.c (stop_and_resume_callback): Don't re-resume LWPs if
 | 
						* linux-nat.c (stop_and_resume_callback): Don't re-resume LWPs if
 | 
				
			||||||
 | 
				
			|||||||
@ -13325,6 +13325,45 @@ iterate_over_breakpoints (int (*callback) (struct breakpoint *, void *),
 | 
				
			|||||||
  return NULL;
 | 
					  return NULL;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* Zero if any of the breakpoint's locations could be a location where
 | 
				
			||||||
 | 
					   functions have been inlined, nonzero otherwise.  */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static int
 | 
				
			||||||
 | 
					is_non_inline_function (struct breakpoint *b)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					  /* The shared library event breakpoint is set on the address of a
 | 
				
			||||||
 | 
					     non-inline function.  */
 | 
				
			||||||
 | 
					  if (b->type == bp_shlib_event)
 | 
				
			||||||
 | 
					    return 1;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  return 0;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* Nonzero if the specified PC cannot be a location where functions
 | 
				
			||||||
 | 
					   have been inlined.  */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					int
 | 
				
			||||||
 | 
					pc_at_non_inline_function (struct address_space *aspace, CORE_ADDR pc)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					  struct breakpoint *b;
 | 
				
			||||||
 | 
					  struct bp_location *bl;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  ALL_BREAKPOINTS (b)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					      if (!is_non_inline_function (b))
 | 
				
			||||||
 | 
						continue;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      for (bl = b->loc; bl != NULL; bl = bl->next)
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
						  if (!bl->shlib_disabled
 | 
				
			||||||
 | 
						      && bpstat_check_location (bl, aspace, pc))
 | 
				
			||||||
 | 
						    return 1;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  return 0;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void
 | 
					void
 | 
				
			||||||
initialize_breakpoint_ops (void)
 | 
					initialize_breakpoint_ops (void)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
 | 
				
			|||||||
@ -1357,6 +1357,12 @@ extern void end_rbreak_breakpoints (void);
 | 
				
			|||||||
extern struct breakpoint *iterate_over_breakpoints (int (*) (struct breakpoint *,
 | 
					extern struct breakpoint *iterate_over_breakpoints (int (*) (struct breakpoint *,
 | 
				
			||||||
							     void *), void *);
 | 
												     void *), void *);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* Nonzero if the specified PC cannot be a location where functions
 | 
				
			||||||
 | 
					   have been inlined.  */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					extern int pc_at_non_inline_function (struct address_space *aspace,
 | 
				
			||||||
 | 
									      CORE_ADDR pc);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
extern int user_breakpoint_p (struct breakpoint *);
 | 
					extern int user_breakpoint_p (struct breakpoint *);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#endif /* !defined (BREAKPOINT_H) */
 | 
					#endif /* !defined (BREAKPOINT_H) */
 | 
				
			||||||
 | 
				
			|||||||
							
								
								
									
										25
									
								
								gdb/infrun.c
									
									
									
									
									
								
							
							
								
								
								
								
								
									
									
								
							
						
						
									
										25
									
								
								gdb/infrun.c
									
									
									
									
									
								
							@ -4044,7 +4044,32 @@ handle_inferior_event (struct execution_control_state *ecs)
 | 
				
			|||||||
     nexti.  After stepi and nexti, always show the innermost frame (not any
 | 
					     nexti.  After stepi and nexti, always show the innermost frame (not any
 | 
				
			||||||
     inline function call sites).  */
 | 
					     inline function call sites).  */
 | 
				
			||||||
  if (ecs->event_thread->control.step_range_end != 1)
 | 
					  if (ecs->event_thread->control.step_range_end != 1)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					      struct address_space *aspace = 
 | 
				
			||||||
 | 
						get_regcache_aspace (get_thread_regcache (ecs->ptid));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      /* skip_inline_frames is expensive, so we avoid it if we can
 | 
				
			||||||
 | 
						 determine that the address is one where functions cannot have
 | 
				
			||||||
 | 
						 been inlined.  This improves performance with inferiors that
 | 
				
			||||||
 | 
						 load a lot of shared libraries, because the solib event
 | 
				
			||||||
 | 
						 breakpoint is defined as the address of a function (i.e. not
 | 
				
			||||||
 | 
						 inline).  Note that we have to check the previous PC as well
 | 
				
			||||||
 | 
						 as the current one to catch cases when we have just
 | 
				
			||||||
 | 
						 single-stepped off a breakpoint prior to reinstating it.
 | 
				
			||||||
 | 
						 Note that we're assuming that the code we single-step to is
 | 
				
			||||||
 | 
						 not inline, but that's not definitive: there's nothing
 | 
				
			||||||
 | 
						 preventing the event breakpoint function from containing
 | 
				
			||||||
 | 
						 inlined code, and the single-step ending up there.  If the
 | 
				
			||||||
 | 
						 user had set a breakpoint on that inlined code, the missing
 | 
				
			||||||
 | 
						 skip_inline_frames call would break things.  Fortunately
 | 
				
			||||||
 | 
						 that's an extremely unlikely scenario.  */
 | 
				
			||||||
 | 
					      if (!pc_at_non_inline_function (aspace, stop_pc)
 | 
				
			||||||
 | 
					          && !(ecs->event_thread->suspend.stop_signal == TARGET_SIGNAL_TRAP
 | 
				
			||||||
 | 
					               && ecs->event_thread->control.trap_expected
 | 
				
			||||||
 | 
					               && pc_at_non_inline_function (aspace,
 | 
				
			||||||
 | 
					                                             ecs->event_thread->prev_pc)))
 | 
				
			||||||
	skip_inline_frames (ecs->ptid);
 | 
						skip_inline_frames (ecs->ptid);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  if (ecs->event_thread->suspend.stop_signal == TARGET_SIGNAL_TRAP
 | 
					  if (ecs->event_thread->suspend.stop_signal == TARGET_SIGNAL_TRAP
 | 
				
			||||||
      && ecs->event_thread->control.trap_expected
 | 
					      && ecs->event_thread->control.trap_expected
 | 
				
			||||||
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user