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]

[RFA] Improved support for overlay breakpoints in ROM


Err, I meant to say [RFA], not [PATCH]...

Michael Snyder wrote:
> 
> 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]