diff options
author | Keith Seitz <keiths@redhat.com> | 2001-05-10 22:34:54 +0000 |
---|---|---|
committer | Keith Seitz <keiths@redhat.com> | 2001-05-10 22:34:54 +0000 |
commit | b2f2c8582b245afb25fd6abb5c5f46c8fb576ad6 (patch) | |
tree | 027d0ee2e77fafcca620cddd6226c6042a82f040 | |
parent | 2559f4ee07e376a9b53188c6443f849fda7cf3ec (diff) | |
download | gdb-b2f2c8582b245afb25fd6abb5c5f46c8fb576ad6.tar.gz |
* generic/gdbtk-bp.c (breakpoint_list, breakpoint_list_size): New
variables. Gdb is forcing us to maintain our own breakpoint
database.
(Gdbtk_Breakpoint_Init): Initialize our breakpoint database.
(gdb_find_bp_at_addr): Use our breakpoint database.
(gdb_find_bp_at_line): Ditto.
(gdb_get_breakpoint_list): Ditto.
(gdb_get_breakpoint_info): Remove deleted breakpoint hack.
(gdbtk_create_breakpoint): Moved here from gdbtk-hooks.c.
Add breakpoint to our breakpoint database.
(gdbtk_modify_breakpoint): Ditto the move.
(gdbtk_delete_breakpoint): Ditto the move.
Remove breakpoint from our database.
(gdb_get_tracepoint_info): Remove delete tracepoint hack.
It's not needed for tracepoints: they were implemented properly.
(gdbtk_create_tracepoint): Moved here from gdbtk-hooks.c.
(gdbtk_modify_tracepoint): Ditto.
(gdbtk_delete_tracepoint): Ditto.
* generic/gdbtk-hooks.c: Include "gdb-events.h".
(gdbtk_create_breakpoint): Moved to gdbtk-bp.c
(gdbtk_modify_breakpoint): Ditto.
(gdbtk_delete_breakpoint): Ditto.
(breakpoint_notify): Ditto.
(gdbtk_create_tracepoint): Ditto.
(gdbtk_modify_tracepoint): Ditto.
(gdbtk_delete_tracepoint): Ditto.
(tracepoint_notify): Ditto.
(report_error): No longer static.
(gdbtk_add_hooks): Create our own event handler
vector and register breakpoint_create, breakpoint_modify,
and breakpoint_delete handlers in gdbtk-bp.c.
-rw-r--r-- | gdb/gdbtk/ChangeLog | 34 | ||||
-rw-r--r-- | gdb/gdbtk/generic/gdbtk-bp.c | 237 | ||||
-rw-r--r-- | gdb/gdbtk/generic/gdbtk-hooks.c | 140 |
3 files changed, 237 insertions, 174 deletions
diff --git a/gdb/gdbtk/ChangeLog b/gdb/gdbtk/ChangeLog index b7dde452af6..62ec4f734f4 100644 --- a/gdb/gdbtk/ChangeLog +++ b/gdb/gdbtk/ChangeLog @@ -1,5 +1,39 @@ 2001-05-10 Keith Seitz <keiths@cygnus.com> + * generic/gdbtk-bp.c (breakpoint_list, breakpoint_list_size): New + variables. Gdb is forcing us to maintain our own breakpoint + database. + (Gdbtk_Breakpoint_Init): Initialize our breakpoint database. + (gdb_find_bp_at_addr): Use our breakpoint database. + (gdb_find_bp_at_line): Ditto. + (gdb_get_breakpoint_list): Ditto. + (gdb_get_breakpoint_info): Remove deleted breakpoint hack. + (gdbtk_create_breakpoint): Moved here from gdbtk-hooks.c. + Add breakpoint to our breakpoint database. + (gdbtk_modify_breakpoint): Ditto the move. + (gdbtk_delete_breakpoint): Ditto the move. + Remove breakpoint from our database. + (gdb_get_tracepoint_info): Remove delete tracepoint hack. + It's not needed for tracepoints: they were implemented properly. + (gdbtk_create_tracepoint): Moved here from gdbtk-hooks.c. + (gdbtk_modify_tracepoint): Ditto. + (gdbtk_delete_tracepoint): Ditto. + * generic/gdbtk-hooks.c: Include "gdb-events.h". + (gdbtk_create_breakpoint): Moved to gdbtk-bp.c + (gdbtk_modify_breakpoint): Ditto. + (gdbtk_delete_breakpoint): Ditto. + (breakpoint_notify): Ditto. + (gdbtk_create_tracepoint): Ditto. + (gdbtk_modify_tracepoint): Ditto. + (gdbtk_delete_tracepoint): Ditto. + (tracepoint_notify): Ditto. + (report_error): No longer static. + (gdbtk_add_hooks): Create our own event handler + vector and register breakpoint_create, breakpoint_modify, + and breakpoint_delete handlers in gdbtk-bp.c. + +2001-05-10 Keith Seitz <keiths@cygnus.com> + * generic/gdbtk-cmds.c: Put on diet. All breakpoint-, tracepoint-, register-, and stack-related functions moved into separate files. diff --git a/gdb/gdbtk/generic/gdbtk-bp.c b/gdb/gdbtk/generic/gdbtk-bp.c index 2cf4d2d9d9a..88c19e11c20 100644 --- a/gdb/gdbtk/generic/gdbtk-bp.c +++ b/gdb/gdbtk/generic/gdbtk-bp.c @@ -29,10 +29,11 @@ #include "gdbtk.h" #include "gdbtk-cmds.h" -/* Various globals we reference. */ -extern void *gdbtk_deleted_bp; +/* From breakpoint.c */ +extern struct breakpoint *breakpoint_chain; -static int tracepoint_exists (char *args); +/* From gdbtk-hooks.c */ +extern void report_error (void); /* These two lookup tables are used to translate the type & disposition fields of the breakpoint structure (respectively) into something gdbtk understands. @@ -60,6 +61,13 @@ extern struct breakpoint *set_raw_breakpoint (struct symtab_and_line sal); extern void set_breakpoint_count (int); extern int breakpoint_count; +/* Breakpoint/Tracepoint lists. Unfortunately, gdb forces us to + keep a list of breakpoints, too. Why couldn't it be done like + treacepoints? */ +#define DEFAULT_LIST_SIZE 32 +static struct breakpoint **breakpoint_list; +static int breakpoint_list_size = DEFAULT_LIST_SIZE; + /* * Forward declarations */ @@ -90,6 +98,18 @@ static int gdb_trace_status (ClientData, Tcl_Interp *, int, Tcl_Obj * CONST[]); static int gdb_tracepoint_exists_command (ClientData, Tcl_Interp *, int, Tcl_Obj * CONST objv[]); +static int tracepoint_exists (char *args); + +/* Breakpoint/tracepoint events and related functions */ + +void gdbtk_create_breakpoint (int); +void gdbtk_delete_breakpoint (int); +void gdbtk_modify_breakpoint (int); +void gdbtk_create_tracepoint (struct tracepoint *); +void gdbtk_delete_tracepoint (struct tracepoint *); +void gdbtk_modify_tracepoint (struct tracepoint *); +static void breakpoint_notify (int, const char *); +static void tracepoint_notify (struct tracepoint *, const char *); int Gdbtk_Breakpoint_Init (Tcl_Interp *interp) @@ -121,6 +141,10 @@ Gdbtk_Breakpoint_Init (Tcl_Interp *interp) Tcl_CreateObjCommand (interp, "gdb_tracepoint_exists", gdbtk_call_wrapper, gdb_tracepoint_exists_command, NULL); + /* Initialize our tables of BPs. */ + breakpoint_list = (struct breakpoint **) xmalloc (breakpoint_list_size * sizeof (struct breakpoint *)); + memset (breakpoint_list, 0, breakpoint_list_size * sizeof (struct breakpoint *)); + return TCL_OK; } @@ -163,9 +187,9 @@ gdb_find_bp_at_addr (clientData, interp, objc, objv) Tcl_Obj *CONST objv[]; { + int i; long addr; struct breakpoint *b; - extern struct breakpoint *breakpoint_chain; if (objc != 2) { @@ -180,10 +204,13 @@ gdb_find_bp_at_addr (clientData, interp, objc, objv) } Tcl_SetListObj (result_ptr->obj_ptr, 0, NULL); - for (b = breakpoint_chain; b; b = b->next) - if (b->address == (CORE_ADDR) addr) - Tcl_ListObjAppendElement (NULL, result_ptr->obj_ptr, - Tcl_NewIntObj (b->number)); + for (i = 0; i < breakpoint_list_size; i++) + { + if (breakpoint_list[i] != NULL + && breakpoint_list[i]->address == (CORE_ADDR) addr) + Tcl_ListObjAppendElement (NULL, result_ptr->obj_ptr, + Tcl_NewIntObj (i)); + } return TCL_OK; } @@ -206,8 +233,7 @@ gdb_find_bp_at_line (clientData, interp, objc, objv) { struct symtab *s; int line; - struct breakpoint *b; - extern struct breakpoint *breakpoint_chain; + int i; if (objc != 3) { @@ -226,10 +252,12 @@ gdb_find_bp_at_line (clientData, interp, objc, objv) } Tcl_SetListObj (result_ptr->obj_ptr, 0, NULL); - for (b = breakpoint_chain; b; b = b->next) - if (b->line_number == line && !strcmp (b->source_file, s->filename)) + for (i = 0; i < breakpoint_list_size; i++) + if (breakpoint_list[i] != NULL + && breakpoint_list[i]->line_number == line + && !strcmp (breakpoint_list[i]->source_file, s->filename)) Tcl_ListObjAppendElement (NULL, result_ptr->obj_ptr, - Tcl_NewIntObj (b->number)); + Tcl_NewIntObj (i)); return TCL_OK; } @@ -251,7 +279,6 @@ gdb_get_breakpoint_info (ClientData clientData, Tcl_Interp *interp, int objc, struct command_line *cmd; int bpnum; struct breakpoint *b; - extern struct breakpoint *breakpoint_chain; char *funcname, *filename; Tcl_Obj *new_obj; @@ -268,26 +295,14 @@ gdb_get_breakpoint_info (ClientData clientData, Tcl_Interp *interp, int objc, return TCL_ERROR; } - for (b = breakpoint_chain; b; b = b->next) - if (b->number == bpnum) - break; - + b = (bpnum <= breakpoint_list_size ? breakpoint_list[bpnum] : NULL); if (!b || b->type != bp_breakpoint) { - /* Hack. Check if this BP is being deleted. See comments - around the definition of gdbtk_deleted_bp in - gdbtk-hooks.c. */ - struct breakpoint *dbp = (struct breakpoint *) gdbtk_deleted_bp; - if (dbp && dbp->number == bpnum) - b = dbp; - else - { - char *err_buf; - xasprintf (&err_buf, "Breakpoint #%d does not exist.", bpnum); - Tcl_SetStringObj (result_ptr->obj_ptr, err_buf, -1); - free(err_buf); - return TCL_ERROR; - } + char *err_buf; + xasprintf (&err_buf, "Breakpoint #%d does not exist.", bpnum); + Tcl_SetStringObj (result_ptr->obj_ptr, err_buf, -1); + free(err_buf); + return TCL_ERROR; } sal = find_pc_line (b->address, 0); @@ -350,8 +365,7 @@ gdb_get_breakpoint_list (clientData, interp, objc, objv) int objc; Tcl_Obj *CONST objv[]; { - struct breakpoint *b; - extern struct breakpoint *breakpoint_chain; + int i; Tcl_Obj *new_obj; if (objc != 1) @@ -360,12 +374,15 @@ gdb_get_breakpoint_list (clientData, interp, objc, objv) return TCL_ERROR; } - for (b = breakpoint_chain; b; b = b->next) - if (b->type == bp_breakpoint) - { - new_obj = Tcl_NewIntObj (b->number); - Tcl_ListObjAppendElement (NULL, result_ptr->obj_ptr, new_obj); - } + for (i = 0; i < breakpoint_list_size; i++) + { + if (breakpoint_list[i] != NULL + && breakpoint_list[i]->type == bp_breakpoint) + { + new_obj = Tcl_NewIntObj (i); + Tcl_ListObjAppendElement (NULL, result_ptr->obj_ptr, new_obj); + } + } return TCL_OK; } @@ -539,6 +556,86 @@ gdb_set_bp_addr (ClientData clientData, Tcl_Interp *interp, int objc, } /* + * This section contains functions that deal with breakpoint + * events from gdb. + */ + +/* The next three functions use breakpoint_notify to allow the GUI + * to handle creating, deleting and modifying breakpoints. These three + * functions are put into the appropriate gdb hooks in gdbtk_init. + */ + +void +gdbtk_create_breakpoint (int num) +{ + struct breakpoint *b; + for (b = breakpoint_chain; b != NULL; b = b->next) + { + if (b->number == num) + break; + } + + if (b == NULL) + return; + + /* Check if there is room to store it */ + if (num >= breakpoint_list_size) + { + int oldsize = breakpoint_list_size; + while (num >= breakpoint_list_size) + breakpoint_list_size += DEFAULT_LIST_SIZE; + breakpoint_list = (struct breakpoint **) xrealloc (breakpoint_list, breakpoint_list_size * sizeof (struct breakpoint *)); + memset (&(breakpoint_list[oldsize]), 0, (breakpoint_list_size - oldsize) * sizeof (struct breakpoint *)); + } + + breakpoint_list[num] = b; + breakpoint_notify (num, "create"); +} + +void +gdbtk_delete_breakpoint (int num) +{ + if (breakpoint_list[num] != NULL) + { + breakpoint_notify (num, "delete"); + breakpoint_list[num] = NULL; + } +} + +void +gdbtk_modify_breakpoint (int num) +{ + breakpoint_notify (num, "modify"); +} + +/* This is the generic function for handling changes in + * a breakpoint. It routes the information to the Tcl + * command "gdbtk_tcl_breakpoint" in the form: + * gdbtk_tcl_breakpoint action b_number b_address b_line b_file + * On error, the error string is written to gdb_stdout. + */ +static void +breakpoint_notify (num, action) + int num; + const char *action; +{ + char *buf; + + if (num > breakpoint_list_size + || breakpoint_list[num] == NULL + || breakpoint_list[num]->type != bp_breakpoint) + return; + + /* We ensure that ACTION contains no special Tcl characters, so we + can do this. */ + xasprintf (&buf, "gdbtk_tcl_breakpoint %s %d", action, num); + + if (Tcl_Eval (gdbtk_interp, buf) != TCL_OK) + report_error (); + free(buf); +} + +/* * This section contains the commands that deal with tracepoints: */ @@ -668,19 +765,11 @@ gdb_get_tracepoint_info (ClientData clientData, Tcl_Interp *interp, if (tp == NULL) { - /* Hack. Check if this TP is being deleted. See comments - around the definition of gdbtk_deleted_bp in - gdbtk-hooks.c. */ - struct tracepoint *dtp = (struct tracepoint *) gdbtk_deleted_bp; - if (dtp != NULL && dtp->number == tpnum) - tp = dtp; - else { - char *buff; - xasprintf (&buff, "Tracepoint #%d does not exist", tpnum); - Tcl_SetStringObj (result_ptr->obj_ptr, buff, -1); - free(buff); - return TCL_ERROR; - } + char *buff; + xasprintf (&buff, "Tracepoint #%d does not exist", tpnum); + Tcl_SetStringObj (result_ptr->obj_ptr, buff, -1); + free(buff); + return TCL_ERROR; } Tcl_SetListObj (result_ptr->obj_ptr, 0, NULL); @@ -823,3 +912,45 @@ gdb_tracepoint_exists_command (clientData, interp, objc, objv) Tcl_SetIntObj (result_ptr->obj_ptr, tracepoint_exists (args)); return TCL_OK; } + +/* + * This section contains functions which deal with tracepoint + * events from gdb. + */ + +void +gdbtk_create_tracepoint (tp) + struct tracepoint *tp; +{ + tracepoint_notify (tp, "create"); +} + +void +gdbtk_delete_tracepoint (tp) + struct tracepoint *tp; +{ + tracepoint_notify (tp, "delete"); +} + +void +gdbtk_modify_tracepoint (tp) + struct tracepoint *tp; +{ + tracepoint_notify (tp, "modify"); +} + +static void +tracepoint_notify (tp, action) + struct tracepoint *tp; + const char *action; +{ + char *buf; + + /* We ensure that ACTION contains no special Tcl characters, so we + can do this. */ + xasprintf (&buf, "gdbtk_tcl_tracepoint %s %d", action, tp->number); + + if (Tcl_Eval (gdbtk_interp, buf) != TCL_OK) + report_error (); + free(buf); +} diff --git a/gdb/gdbtk/generic/gdbtk-hooks.c b/gdb/gdbtk/generic/gdbtk-hooks.c index 5f70202a546..2dd19c694c4 100644 --- a/gdb/gdbtk/generic/gdbtk-hooks.c +++ b/gdb/gdbtk/generic/gdbtk-hooks.c @@ -32,6 +32,7 @@ #include "gdbcore.h" #include "tracepoint.h" #include "demangle.h" +#include "gdb-events.h" #ifdef _WIN32 #define WIN32_LEAN_AND_MEAN @@ -66,33 +67,21 @@ volatile int in_fputs = 0; that it should forcibly detach from the target. */ int gdbtk_force_detach = 0; -/* Set/cleared by gdbtk_delete_breakpoint/tracepoint. Unfortunately, - clear_command (in breakpoint.c) takes the breakpoint off of the - breakpoint_chain before deleting the breakpoint. The BreakpointEvent - which is created as a result of any breakpoint/tracepoint event - calls gdb_get_breakpoint_info will, therefore, not find a breakpoint - about which to return information. So we keep a handle on the deleted - breakpoint when we're deleting it, and teach gdb_get_breakpoint_info - to check for this variable whenever a breakpoint lookup fails. - - Why not just change BreakpointEvent? Good question. Answer: I refuse - to allow BreakpointEvents to be all public variables. They are not. - They ONLY depend on the breakpoint number (gdb's handle for them). */ -void *gdbtk_deleted_bp = NULL; +/* From gdbtk-bp.c */ +extern void gdbtk_create_breakpoint (int); +extern void gdbtk_delete_breakpoint (int); +extern void gdbtk_modify_breakpoint (int); +extern void gdbtk_create_tracepoint (struct tracepoint *); +extern void gdbtk_delete_tracepoint (struct tracepoint *); +extern void gdbtk_modify_tracepoint (struct tracepoint *); extern void (*pre_add_symbol_hook) (char *); extern void (*post_add_symbol_hook) (void); extern void (*selected_frame_level_changed_hook) (int); extern int (*ui_loop_hook) (int); -static void gdbtk_create_tracepoint (struct tracepoint *); -static void gdbtk_delete_tracepoint (struct tracepoint *); -static void gdbtk_modify_tracepoint (struct tracepoint *); static void gdbtk_trace_find (char *arg, int from_tty); static void gdbtk_trace_start_stop (int, int); -static void gdbtk_create_breakpoint (struct breakpoint *); -static void gdbtk_delete_breakpoint (struct breakpoint *); -static void gdbtk_modify_breakpoint (struct breakpoint *); static void gdbtk_attach (void); static void gdbtk_detach (void); static void gdbtk_file_changed (char *); @@ -115,7 +104,7 @@ static void tracepoint_notify (struct tracepoint *, const char *); static void gdbtk_selected_frame_changed (int); static void gdbtk_context_change (int); static void gdbtk_error_begin (void); -static void report_error (void); +void report_error (void); static void gdbtk_annotate_signal (void); static void gdbtk_set_hook (struct cmd_list_element *cmdblk); @@ -126,7 +115,6 @@ static void gdbtk_set_hook (struct cmd_list_element *cmdblk); void gdbtk_fputs (const char *, struct ui_file *); static int gdbtk_load_hash (const char *, unsigned long); -static void breakpoint_notify (struct breakpoint *, const char *); /* * gdbtk_add_hooks - add all the hooks to gdb. This will get called by the @@ -136,6 +124,15 @@ static void breakpoint_notify (struct breakpoint *, const char *); void gdbtk_add_hooks (void) { + static struct gdb_events handlers; + + /* Gdb event handlers */ + handlers.breakpoint_create = gdbtk_create_breakpoint; + handlers.breakpoint_modify = gdbtk_modify_breakpoint; + handlers.breakpoint_delete = gdbtk_delete_breakpoint; + set_gdb_event_hooks (&handlers); + + /* Hooks */ command_loop_hook = tk_command_loop; call_command_hook = gdbtk_call_command; set_hook = gdbtk_set_hook; @@ -147,10 +144,6 @@ gdbtk_add_hooks (void) query_hook = gdbtk_query; warning_hook = gdbtk_warning; - create_breakpoint_hook = gdbtk_create_breakpoint; - delete_breakpoint_hook = gdbtk_delete_breakpoint; - modify_breakpoint_hook = gdbtk_modify_breakpoint; - interactive_hook = gdbtk_interactive; target_wait_hook = gdbtk_wait; ui_load_progress_hook = gdbtk_load_hash; @@ -335,7 +328,7 @@ gdbtk_warning (warning, args) /* pop up a messagebox, or it can silently log the errors through */ /* the gdbtk dbug command. */ -static void +void report_error () { TclDebug ('E', Tcl_GetVar (gdbtk_interp, "errorInfo", TCL_GLOBAL_ONLY)); @@ -635,61 +628,6 @@ gdbtk_set_hook (struct cmd_list_element *cmdblk) } } -/* The next three functions use breakpoint_notify to allow the GUI - * to handle creating, deleting and modifying breakpoints. These three - * functions are put into the appropriate gdb hooks in gdbtk_init. - */ - -static void -gdbtk_create_breakpoint (b) - struct breakpoint *b; -{ - breakpoint_notify (b, "create"); -} - -static void -gdbtk_delete_breakpoint (b) - struct breakpoint *b; -{ - /* Hack. See comments near top of this file. */ - gdbtk_deleted_bp = b; - breakpoint_notify (b, "delete"); - gdbtk_deleted_bp = NULL; -} - -static void -gdbtk_modify_breakpoint (b) - struct breakpoint *b; -{ - breakpoint_notify (b, "modify"); -} - -/* This is the generic function for handling changes in - * a breakpoint. It routes the information to the Tcl - * command "gdbtk_tcl_breakpoint" in the form: - * gdbtk_tcl_breakpoint action b_number b_address b_line b_file - * On error, the error string is written to gdb_stdout. - */ - -static void -breakpoint_notify (b, action) - struct breakpoint *b; - const char *action; -{ - char *buf; - - if (b->type != bp_breakpoint) - return; - - /* We ensure that ACTION contains no special Tcl characters, so we - can do this. */ - xasprintf (&buf, "gdbtk_tcl_breakpoint %s %d", action, b->number); - - if (Tcl_Eval (gdbtk_interp, buf) != TCL_OK) - report_error (); - free(buf); -} - int gdbtk_load_hash (const char *section, unsigned long num) { @@ -773,46 +711,6 @@ gdbtk_print_frame_info (s, line, stopline, noerror) current_source_line = line; } -static void -gdbtk_create_tracepoint (tp) - struct tracepoint *tp; -{ - tracepoint_notify (tp, "create"); -} - -static void -gdbtk_delete_tracepoint (tp) - struct tracepoint *tp; -{ - /* Hack. See comments near top of this file. */ - gdbtk_deleted_bp = tp; - tracepoint_notify (tp, "delete"); - gdbtk_deleted_bp = NULL; -} - -static void -gdbtk_modify_tracepoint (tp) - struct tracepoint *tp; -{ - tracepoint_notify (tp, "modify"); -} - -static void -tracepoint_notify (tp, action) - struct tracepoint *tp; - const char *action; -{ - char *buf; - - /* We ensure that ACTION contains no special Tcl characters, so we - can do this. */ - xasprintf (&buf, "gdbtk_tcl_tracepoint %s %d", action, tp->number); - - if (Tcl_Eval (gdbtk_interp, buf) != TCL_OK) - report_error (); - free(buf); -} - /* * gdbtk_trace_find * |