This is the mail archive of the
gdb-patches@sources.redhat.com
mailing list for the GDB project.
Re: [PATCH] Improved support for overlay breakpoints in ROM
- From: Michael Snyder <msnyder at redhat dot com>
- To: Jim Blandy <jimb at cygnus dot com>
- Cc: Michael Snyder <msnyder at cygnus dot com>, gdb-patches at sources dot redhat dot com, ezannoni at redhat dot com
- Date: Tue, 05 Feb 2002 17:04:08 -0800
- Subject: Re: [PATCH] Improved support for overlay breakpoints in ROM
- Organization: Red Hat, Inc.
- References: <200202050011.g150BfB21148@reddwarf.cygnus.com> <np8za7pih3.fsf@zwingli.cygnus.com>
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;
> > }
> >