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: [PATCH] Improved support for overlay breakpoints in ROM


Jim Blandy wrote:
> 
> Typo:
> 
> > +     /* On the same principal, an overlay manager can arrange to call a
> 
> s/principal/principle/
> 
> It seems to me that, if overlay management is disabled, or set to
> `manual', we shouldn't even set a breakpoint in _ovly_debug_event.

By analogy with the longjmp breakpoint, it seems easiest just to 
create the breakpoint when the symbol file is loaded, and then
enable/disable it as needed.  When it is disabled, it doesn't
represent any significant overhead.

> We need to document the new rules in the GDB manual.

Yep.  

> Michael Snyder <msnyder@cygnus.com> writes:
> 
> > This patch allows gdb to handle breakpoints in overlays, even if the
> > overlays are kept in ROM when not being executed.  It works by allowing
> > the overlay manager to notify gdb whenever there is a change in the
> > overlay mapping table, thus allowing gdb to update breakpoints.
> >
> > 2002-02-04  Michael Snyder  <msnyder@redhat.com>
> >
> >       * breakpoint.h (enum bptype): Add new overlay event bp type.
> >       (enable_overlay_breakpoints, disable_overlay_breakpoints): Export.
> >
> >       * breakpoint.c (create_internal_breakpoint): New function.
> >       (intenal_breakpoint_number): Moved into create_internal_breakpoint.
> >       (create_longjmp_breakpoint): Use create_internal_breakpoint.
> >       (create_thread_event_breakpoint): Ditto.
> >       (create_solib_event_breakpoint): Ditto.
> >       (create_overlay_event_breakpoint): New function.
> >       (enable_overlay_breakpoints, disable_overlay_breakpoints): New funcs.
> >       (update_breakpoints_after_exec): Delete and re-initialize
> >       overlay event breakpoints after an exec.  Add FIXME comment
> >       about longjmp breakpoint.
> >       (print_it_typical): Ignore overlay event breakpoints.
> >       (print_one_breakpoint): Ditto.
> >       (mention): Ditto.
> >       (bpstat_what): Do not stop for overlay event breakpoints.
> >       (delete_breakpoint): Don't delete overlay event breakpoints.
> >       (breakpoint_re_set_one): Delete the overlay event breakpoint.
> >       (breakpoint_re_set): Re-create overlay event breakpoint.
> >
> >       * symfile.c (overlay_auto_command): Enable overlay breakpoints.
> >       (overlay_manual_command): Disable overlay breakpoints.
> >       (overlay_off_command): Disable overlay breakpoints.
> >
> > 2002-02-04  Michael Snyder  <msnyder@redhat.com>
> >
> >       * testsuite/gdb.base/ovlymgr.c (_ovly_debug_event): New function.
> >       (OverlayLoad, OverlayUnload): Add calls to _ovly_debug_event.
> >
> > Index: breakpoint.c
> > ===================================================================
> > RCS file: /cvs/src/src/gdb/breakpoint.c,v
> > retrieving revision 1.64
> > diff -c -3 -p -r1.64 breakpoint.c
> > *** breakpoint.c      2002/02/03 11:43:19     1.64
> > --- breakpoint.c      2002/02/04 23:54:30
> > *************** static int get_number_trailer (char **,
> > *** 117,126 ****
> >
> >   void set_breakpoint_count (int);
> >
> > - #if 0
> > - static struct breakpoint *create_temp_exception_breakpoint (CORE_ADDR);
> > - #endif
> > -
> >   typedef enum
> >     {
> >       mark_inserted,
> > --- 117,122 ----
> > *************** static void maintenance_info_breakpoints
> > *** 151,156 ****
> > --- 147,154 ----
> >   static void create_longjmp_breakpoint (char *);
> >   #endif
> >
> > + static void create_overlay_event_breakpoint (char *);
> > +
> >   static int hw_breakpoint_used_count (void);
> >
> >   static int hw_watchpoint_used_count (enum bptype, int *);
> > *************** void _initialize_breakpoint (void);
> > *** 218,225 ****
> >
> >   extern int addressprint;    /* Print machine addresses? */
> >
> > - static int internal_breakpoint_number = -1;
> > -
> >   /* Are we executing breakpoint commands?  */
> >   static int executing_breakpoint_commands;
> >
> > --- 216,221 ----
> > *************** update_breakpoints_after_exec (void)
> > *** 1107,1114 ****
> >       continue;
> >         }
> >
> > !     /* Thread event breakpoints must be set anew after an exec().  */
> > !     if (b->type == bp_thread_event)
> >         {
> >       delete_breakpoint (b);
> >       continue;
> > --- 1103,1111 ----
> >       continue;
> >         }
> >
> > !     /* Thread event breakpoints must be set anew after an exec(),
> > !        as must overlay event breakpoints.  */
> > !     if (b->type == bp_thread_event || b->type == bp_overlay_event)
> >         {
> >       delete_breakpoint (b);
> >       continue;
> > *************** update_breakpoints_after_exec (void)
> > *** 1216,1221 ****
> > --- 1213,1220 ----
> >          So I think this assignment could be deleted without effect.  */
> >       b->address = (CORE_ADDR) NULL;
> >     }
> > +   /* FIXME what about longjmp breakpoints?  Re-create them here?  */
> > +   create_overlay_event_breakpoint ("_ovly_debug_event");
> >   }
> >
> >   int
> > *************** print_it_typical (bpstat bs)
> > *** 1910,1915 ****
> > --- 1909,1920 ----
> >         return PRINT_NOTHING;
> >         break;
> >
> > +     case bp_overlay_event:
> > +       /* By analogy with the thread event, GDB should not stop for these. */
> > +       printf_filtered ("Overlay Event Breakpoint: gdb should not stop!\n");
> > +       return PRINT_NOTHING;
> > +       break;
> > +
> >       case bp_catch_load:
> >         annotate_catchpoint (bs->breakpoint_at->number);
> >         printf_filtered ("\nCatchpoint %d (", bs->breakpoint_at->number);
> > *************** bpstat_what (bpstat bs)
> > *** 2896,2901 ****
> > --- 2901,2907 ----
> >         bs_class = shlib_event;
> >         break;
> >       case bp_thread_event:
> > +     case bp_overlay_event:
> >         bs_class = bp_nostop;
> >         break;
> >       case bp_catch_load:
> > *************** print_one_breakpoint (struct breakpoint
> > *** 3072,3077 ****
> > --- 3078,3084 ----
> >       {bp_call_dummy, "call dummy"},
> >       {bp_shlib_event, "shlib events"},
> >       {bp_thread_event, "thread events"},
> > +     {bp_overlay_event, "overlay events"},
> >       {bp_catch_load, "catch load"},
> >       {bp_catch_unload, "catch unload"},
> >       {bp_catch_fork, "catch fork"},
> > *************** print_one_breakpoint (struct breakpoint
> > *** 3228,3233 ****
> > --- 3235,3241 ----
> >       case bp_call_dummy:
> >       case bp_shlib_event:
> >       case bp_thread_event:
> > +     case bp_overlay_event:
> >         if (addressprint)
> >       {
> >         annotate_field (4);
> > *************** make_breakpoint_permanent (struct breakp
> > *** 3731,3766 ****
> >     b->inserted = 1;
> >   }
> >
> >   #ifdef GET_LONGJMP_TARGET
> >
> >   static void
> >   create_longjmp_breakpoint (char *func_name)
> >   {
> > -   struct symtab_and_line sal;
> >     struct breakpoint *b;
> >
> > !   INIT_SAL (&sal);          /* initialize to zeroes */
> > !   if (func_name != NULL)
> >       {
> > !       struct minimal_symbol *m;
> > !
> > !       m = lookup_minimal_symbol_text (func_name, NULL,
> > !                                   (struct objfile *) NULL);
> > !       if (m)
> > !     sal.pc = SYMBOL_VALUE_ADDRESS (m);
> > !       else
> >       return;
> >       }
> > -   sal.section = find_pc_overlay (sal.pc);
> > -   b = set_raw_breakpoint (sal,
> > -                           func_name != NULL ? bp_longjmp : bp_longjmp_resume);
> >
> > -   b->disposition = disp_donttouch;
> >     b->enable_state = bp_disabled;
> >     b->silent = 1;
> >     if (func_name)
> >       b->addr_string = xstrdup (func_name);
> > -   b->number = internal_breakpoint_number--;
> >   }
> >
> >   #endif /* #ifdef GET_LONGJMP_TARGET */
> > --- 3739,3785 ----
> >     b->inserted = 1;
> >   }
> >
> > + static struct breakpoint *
> > + create_internal_breakpoint (CORE_ADDR address, enum bptype type)
> > + {
> > +   static int internal_breakpoint_number = -1;
> > +   struct symtab_and_line sal;
> > +   struct breakpoint *b;
> > +
> > +   INIT_SAL (&sal);          /* initialize to zeroes */
> > +
> > +   sal.pc = address;
> > +   sal.section = find_pc_overlay (sal.pc);
> > +
> > +   b = set_raw_breakpoint (sal, type);
> > +   b->number = internal_breakpoint_number--;
> > +   b->disposition = disp_donttouch;
> > +
> > +   return b;
> > + }
> > +
> >   #ifdef GET_LONGJMP_TARGET
> >
> >   static void
> >   create_longjmp_breakpoint (char *func_name)
> >   {
> >     struct breakpoint *b;
> > +   struct minimal_symbol *m;
> >
> > !   if (func_name == NULL)
> > !     b = create_internal_breakpoint (0, bp_longjmp_resume);
> > !   else
> >       {
> > !       if ((m = lookup_minimal_symbol_text (func_name, NULL, NULL)) == NULL)
> >       return;
> > +
> > +       b = create_internal_breakpoint (SYMBOL_VALUE_ADDRESS (m), bp_longjmp);
> >       }
> >
> >     b->enable_state = bp_disabled;
> >     b->silent = 1;
> >     if (func_name)
> >       b->addr_string = xstrdup (func_name);
> >   }
> >
> >   #endif /* #ifdef GET_LONGJMP_TARGET */
> > *************** disable_longjmp_breakpoint (void)
> > *** 3796,3815 ****
> >       }
> >   }
> >
> >   struct breakpoint *
> >   create_thread_event_breakpoint (CORE_ADDR address)
> >   {
> >     struct breakpoint *b;
> > -   struct symtab_and_line sal;
> >     char addr_string[80];             /* Surely an addr can't be longer than that. */
> >
> > !   INIT_SAL (&sal);          /* initialize to zeroes */
> > !   sal.pc = address;
> > !   sal.section = find_pc_overlay (sal.pc);
> > !   b = set_raw_breakpoint (sal, bp_thread_event);
> >
> > -   b->number = internal_breakpoint_number--;
> > -   b->disposition = disp_donttouch;
> >     b->enable_state = bp_enabled;
> >     /* addr_string has to be used or breakpoint_re_set will delete me.  */
> >     sprintf (addr_string, "*0x%s", paddr (b->address));
> > --- 3815,3875 ----
> >       }
> >   }
> >
> > + static struct breakpoint *
> > + create_overlay_event_breakpoint (char *func_name)
> > + {
> > +   struct breakpoint *b;
> > +   struct minimal_symbol *m;
> > +
> > +   if ((m = lookup_minimal_symbol_text (func_name, NULL, NULL)) == NULL)
> > +     return NULL;
> > +
> > +   b = create_internal_breakpoint (SYMBOL_VALUE_ADDRESS (m),
> > +                               bp_overlay_event);
> > +   b->addr_string = xstrdup (func_name);
> > +
> > +   if (overlay_debugging == ovly_auto)
> > +     b->enable_state = bp_enabled;
> > +   else
> > +     b->enable_state = bp_disabled;
> > +
> > +   return b;
> > + }
> > +
> > + void
> > + enable_overlay_breakpoints (void)
> > + {
> > +   register struct breakpoint *b;
> > +
> > +   ALL_BREAKPOINTS (b)
> > +     if (b->type == bp_overlay_event)
> > +     {
> > +       b->enable_state = bp_enabled;
> > +       check_duplicates (b);
> > +     }
> > + }
> > +
> > + void
> > + disable_overlay_breakpoints (void)
> > + {
> > +   register struct breakpoint *b;
> > +
> > +   ALL_BREAKPOINTS (b)
> > +     if (b->type == bp_overlay_event)
> > +     {
> > +       b->enable_state = bp_disabled;
> > +       check_duplicates (b);
> > +     }
> > + }
> > +
> >   struct breakpoint *
> >   create_thread_event_breakpoint (CORE_ADDR address)
> >   {
> >     struct breakpoint *b;
> >     char addr_string[80];             /* Surely an addr can't be longer than that. */
> >
> > !   b = create_internal_breakpoint (address, bp_thread_event);
> >
> >     b->enable_state = bp_enabled;
> >     /* addr_string has to be used or breakpoint_re_set will delete me.  */
> >     sprintf (addr_string, "*0x%s", paddr (b->address));
> > *************** struct breakpoint *
> > *** 3843,3857 ****
> >   create_solib_event_breakpoint (CORE_ADDR address)
> >   {
> >     struct breakpoint *b;
> > -   struct symtab_and_line sal;
> >
> > !   INIT_SAL (&sal);          /* initialize to zeroes */
> > !   sal.pc = address;
> > !   sal.section = find_pc_overlay (sal.pc);
> > !   b = set_raw_breakpoint (sal, bp_shlib_event);
> > !   b->number = internal_breakpoint_number--;
> > !   b->disposition = disp_donttouch;
> > !
> >     return b;
> >   }
> >
> > --- 3903,3910 ----
> >   create_solib_event_breakpoint (CORE_ADDR address)
> >   {
> >     struct breakpoint *b;
> >
> > !   b = create_internal_breakpoint (address, bp_shlib_event);
> >     return b;
> >   }
> >
> > *************** mention (struct breakpoint *b)
> > *** 4311,4316 ****
> > --- 4364,4370 ----
> >       case bp_watchpoint_scope:
> >       case bp_shlib_event:
> >       case bp_thread_event:
> > +     case bp_overlay_event:
> >         break;
> >       }
> >     if (say_where)
> > *************** delete_command (char *arg, int from_tty)
> > *** 6665,6670 ****
> > --- 6719,6725 ----
> >       if (b->type != bp_call_dummy &&
> >           b->type != bp_shlib_event &&
> >           b->type != bp_thread_event &&
> > +         b->type != bp_overlay_event &&
> >           b->number >= 0)
> >         breaks_to_delete = 1;
> >         }
> > *************** delete_command (char *arg, int from_tty)
> > *** 6678,6683 ****
> > --- 6733,6739 ----
> >           if (b->type != bp_call_dummy &&
> >               b->type != bp_shlib_event &&
> >               b->type != bp_thread_event &&
> > +             b->type != bp_overlay_event &&
> >               b->number >= 0)
> >             delete_breakpoint (b);
> >         }
> > *************** breakpoint_re_set_one (PTR bint)
> > *** 6861,6870 ****
> >       default:
> >         printf_filtered ("Deleting unknown breakpoint type %d\n", b->type);
> >         /* fall through */
> > !       /* Delete longjmp breakpoints, they will be reset later by
> > !          breakpoint_re_set.  */
> >       case bp_longjmp:
> >       case bp_longjmp_resume:
> >         delete_breakpoint (b);
> >         break;
> >
> > --- 6917,6927 ----
> >       default:
> >         printf_filtered ("Deleting unknown breakpoint type %d\n", b->type);
> >         /* fall through */
> > !       /* Delete longjmp and overlay event breakpoints; they will be
> > !          reset later by breakpoint_re_set.  */
> >       case bp_longjmp:
> >       case bp_longjmp_resume:
> > +     case bp_overlay_event:
> >         delete_breakpoint (b);
> >         break;
> >
> > *************** breakpoint_re_set (void)
> > *** 6919,6924 ****
> > --- 6976,6982 ----
> >     create_longjmp_breakpoint ("_siglongjmp");
> >     create_longjmp_breakpoint (NULL);
> >   #endif
> > +   create_overlay_event_breakpoint ("_ovly_debug_event");
> >   }
> >
> >   /* Reset the thread number of this breakpoint:
> > *************** map_breakpoint_numbers (char *args, void
> > *** 7046,7051 ****
> > --- 7104,7113 ----
> >         p = p1;
> >       }
> >   }
> > +
> > + /* Set ignore-count of breakpoint number BPTNUM to COUNT.
> > +    If from_tty is nonzero, it prints a message to that effect,
> > +    which ends with a period (no newline).  */
> >
> >   void
> >   disable_breakpoint (struct breakpoint *bpt)
> > Index: breakpoint.h
> > ===================================================================
> > RCS file: /cvs/src/src/gdb/breakpoint.h,v
> > retrieving revision 1.10
> > diff -c -3 -p -r1.10 breakpoint.h
> > *** breakpoint.h      2001/10/20 23:54:29     1.10
> > --- breakpoint.h      2002/02/04 23:54:30
> > *************** enum bptype
> > *** 107,112 ****
> > --- 107,120 ----
> >
> >       bp_thread_event,
> >
> > +     /* On the same principal, an overlay manager can arrange to call a
> > +        magic location in the inferior whenever there is an interesting
> > +        change in overlay status.  GDB can update its overlay tables
> > +        and fiddle with breakpoints in overlays when this breakpoint
> > +        is hit.  */
> > +
> > +     bp_overlay_event,
> > +
> >       /* These breakpoints are used to implement the "catch load" command
> >          on platforms whose dynamic linkers support such functionality.  */
> >       bp_catch_load,
> > *************** extern void update_breakpoints_after_exe
> > *** 603,610 ****
> >   extern int detach_breakpoints (int);
> >
> >   extern void enable_longjmp_breakpoint (void);
> > -
> >   extern void disable_longjmp_breakpoint (void);
> >
> >   extern void set_longjmp_resume_breakpoint (CORE_ADDR, struct frame_info *);
> >   /* These functions respectively disable or reenable all currently
> > --- 611,619 ----
> >   extern int detach_breakpoints (int);
> >
> >   extern void enable_longjmp_breakpoint (void);
> >   extern void disable_longjmp_breakpoint (void);
> > + extern void enable_overlay_breakpoint (void);
> > + extern void disable_overlay_breakpoint (void);
> >
> >   extern void set_longjmp_resume_breakpoint (CORE_ADDR, struct frame_info *);
> >   /* These functions respectively disable or reenable all currently
> > Index: symfile.c
> > ===================================================================
> > RCS file: /cvs/src/src/gdb/symfile.c,v
> > retrieving revision 1.51
> > diff -c -3 -p -r1.51 symfile.c
> > *** symfile.c 2002/02/01 01:14:20     1.51
> > --- symfile.c 2002/02/04 23:54:31
> > *************** static void
> > *** 2898,2903 ****
> > --- 2898,2904 ----
> >   overlay_auto_command (char *args, int from_tty)
> >   {
> >     overlay_debugging = ovly_auto;
> > +   enable_overlay_breakpoints ();
> >     if (info_verbose)
> >       printf_filtered ("Automatic overlay debugging enabled.");
> >   }
> > *************** static void
> > *** 2910,2915 ****
> > --- 2911,2917 ----
> >   overlay_manual_command (char *args, int from_tty)
> >   {
> >     overlay_debugging = ovly_on;
> > +   disable_overlay_breakpoints ();
> >     if (info_verbose)
> >       printf_filtered ("Overlay debugging enabled.");
> >   }
> > *************** static void
> > *** 2922,2927 ****
> > --- 2924,2930 ----
> >   overlay_off_command (char *args, int from_tty)
> >   {
> >     overlay_debugging = ovly_off;
> > +   disable_overlay_breakpoints ();
> >     if (info_verbose)
> >       printf_filtered ("Overlay debugging disabled.");
> >   }
> > Index: testsuite/gdb.base/ovlymgr.c
> > ===================================================================
> > RCS file: /cvs/src/src/gdb/testsuite/gdb.base/ovlymgr.c,v
> > retrieving revision 1.1.1.1
> > diff -c -3 -p -r1.1.1.1 ovlymgr.c
> > *** ovlymgr.c 1999/04/16 01:34:31     1.1.1.1
> > --- ovlymgr.c 2002/02/05 00:11:50
> > *************** FlushCache (void)
> > *** 30,35 ****
> > --- 30,44 ----
> >   #endif
> >   }
> >
> > + /* _ovly_debug_event:
> > +  * Debuggers may set a breakpoint here, to be notified
> > +  * when the overlay table has been modified.
> > +  */
> > + static void
> > + _ovly_debug_event (void)
> > + {
> > + }
> > +
> >   /* OverlayLoad:
> >    * Copy the overlay into its runtime region,
> >    * and mark the overlay as "mapped".
> > *************** OverlayLoad (unsigned long ovlyno)
> > *** 58,63 ****
> > --- 67,74 ----
> >
> >     FlushCache ();
> >
> > +   /* Notify debugger, if any. */
> > +   _ovly_debug_event ();
> >     return TRUE;
> >   }
> >
> > *************** OverlayUnload (unsigned long ovlyno)
> > *** 80,85 ****
> > --- 91,100 ----
> >            _ovly_table[ovlyno][VMA],
> >            _ovly_table[ovlyno][SIZE]);
> >
> > + #if 0
> > +   /* Does the debugger need to be notified of an unload event? */
> > +   _ovly_debug_event ();
> > + #endif
> >     return TRUE;
> >   }
> >


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