* defs.h, gdbtk.c (gdbtk_fputs), main.c (gdb_fputs), top.c: Add stream arg

to fputs_unfiltered_hook.  Differentiate stdout from stderr when
	passing text into tcl land.
	* defs.h, top.c, utils.c (error):  Add error_hook.
	* gdbtk.c:  Improve mechanism for capturing output values.
	* (full_filename):  Remove.
	* (gdb_cmd call_wrapper gdbtk_init):  Protect all calls from tcl
	land with call_wrapper.  This prevents longjmps (usually via
	error()) from jumping out of tcl/tk and leaving things in an
	indeterminate state.
	* gdbtk.tcl:  New view option to disable line numbers.  Put catch
	around most uses of gdb_cmd.  Add update button to reg config
	window.  Stop doing immediate updates when selecting registers.
	Change register view values into checkbuttons.
This commit is contained in:
Stu Grossman 1994-12-16 01:07:35 +00:00
parent 243babd424
commit 86db943ceb
6 changed files with 375 additions and 236 deletions

View File

@ -1,3 +1,20 @@
Thu Dec 15 16:40:10 1994 Stu Grossman (grossman@cygnus.com)
* defs.h, gdbtk.c (gdbtk_fputs), main.c (gdb_fputs), top.c: Add stream arg
to fputs_unfiltered_hook. Differentiate stdout from stderr when
passing text into tcl land.
* defs.h, top.c, utils.c (error): Add error_hook.
* gdbtk.c: Improve mechanism for capturing output values.
* (full_filename): Remove.
* (gdb_cmd call_wrapper gdbtk_init): Protect all calls from tcl
land with call_wrapper. This prevents longjmps (usually via
error()) from jumping out of tcl/tk and leaving things in an
indeterminate state.
* gdbtk.tcl: New view option to disable line numbers. Put catch
around most uses of gdb_cmd. Add update button to reg config
window. Stop doing immediate updates when selecting registers.
Change register view values into checkbuttons.
Tue Dec 13 15:15:33 1994 Stan Shebs <shebs@andros.cygnus.com>
* breakpoint.c, infrun.c, printcmd.c: Change long command help

View File

@ -33,6 +33,8 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
/* libiberty.h can't declare this one, but evidently we can. */
extern char *strsignal PARAMS ((int));
#include "mmalloc.h"
/* For BFD64 and bfd_vma. */
#include "bfd.h"
@ -138,28 +140,6 @@ extern int inside_main_func PARAMS ((CORE_ADDR pc));
extern char *chill_demangle PARAMS ((const char *));
/* From libiberty.a */
extern char *cplus_demangle PARAMS ((const char *, int));
extern char *cplus_mangle_opname PARAMS ((char *, int));
/* From libmmalloc.a (memory mapped malloc library) */
extern PTR mmalloc_attach PARAMS ((int, PTR));
extern PTR mmalloc_detach PARAMS ((PTR));
extern PTR mmalloc PARAMS ((PTR, long));
extern PTR mrealloc PARAMS ((PTR, PTR, long));
extern void mfree PARAMS ((PTR, PTR));
extern int mmalloc_setkey PARAMS ((PTR, int, PTR));
extern PTR mmalloc_getkey PARAMS ((PTR, int));
/* From utils.c */
extern int strcmp_iw PARAMS ((const char *, const char *));
@ -544,19 +524,9 @@ extern PTR xmmalloc PARAMS ((PTR, long));
extern PTR xmrealloc PARAMS ((PTR, PTR, long));
extern PTR mmalloc PARAMS ((PTR, long));
extern PTR mrealloc PARAMS ((PTR, PTR, long));
extern void mfree PARAMS ((PTR, PTR));
extern int mmcheck PARAMS ((PTR, void (*) (void)));
extern int mmtrace PARAMS ((void));
extern int parse_escape PARAMS ((char **));
extern const char * const reg_names[];
extern char *reg_names[];
/* Message to be printed before the error message, when an error occurs. */
@ -862,7 +832,7 @@ extern CORE_ADDR push_word PARAMS ((CORE_ADDR, unsigned LONGEST));
extern void (*init_ui_hook) PARAMS ((void));
extern void (*command_loop_hook) PARAMS ((void));
extern void (*fputs_unfiltered_hook) PARAMS ((const char *linebuffer));
extern void (*fputs_unfiltered_hook) PARAMS ((const char *linebuffer, FILE *stream));
extern void (*print_frame_info_listing_hook) PARAMS ((struct symtab *s, int line,
int stopline, int noerror));
extern int (*query_hook) PARAMS (());
@ -884,6 +854,8 @@ extern int (*target_wait_hook) PARAMS ((int pid,
extern void (*call_command_hook) PARAMS ((struct cmd_list_element *c,
char *cmd, int from_tty));
extern NORETURN void (*error_hook) PARAMS (());
/* Inhibit window interface if non-zero. */
extern int use_windows;

View File

@ -31,6 +31,8 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
#include <signal.h>
#include <fcntl.h>
#include <unistd.h>
#include <setjmp.h>
#include "top.h"
/* Non-zero means that we're doing the gdbtk interface. */
int gdbtk = 0;
@ -53,6 +55,70 @@ null_routine(arg)
{
}
static char *saved_output_buf = NULL; /* Start of output buffer */
static char *saved_output_data_end = NULL; /* Ptr to nul at end of data */
static int saved_output_buf_free = 0; /* Amount of free space in buffer */
static char saved_output_static_buf[200]; /* Default buffer */
static void
start_saving_output ()
{
if (saved_output_buf)
abort (); /* Should always be zero at this point */
saved_output_buf = saved_output_static_buf;
saved_output_data_end = saved_output_buf;
*saved_output_data_end = '\000';
saved_output_buf_free = sizeof saved_output_static_buf - 1;
}
static void
save_output (ptr)
const char *ptr;
{
int len;
int needed, data_len;
len = strlen (ptr);
if (len <= saved_output_buf_free)
{
strcpy (saved_output_data_end, ptr);
saved_output_data_end += len;
saved_output_buf_free -= len;
return;
}
data_len = saved_output_data_end - saved_output_buf;
needed = (data_len + len + 1) * 2;
if (saved_output_buf == saved_output_static_buf)
{
char *tmp;
tmp = xmalloc (needed);
strcpy (tmp, saved_output_buf);
saved_output_buf = tmp;
}
else
saved_output_buf = xrealloc (saved_output_buf, needed);
saved_output_data_end = saved_output_buf + data_len;
saved_output_buf_free = (needed - data_len) - 1;
save_output (ptr);
}
#define get_saved_output() saved_output_buf
static void
finish_saving_output ()
{
if (saved_output_buf != saved_output_static_buf)
free (saved_output_buf);
saved_output_buf = NULL;
}
/* This routine redirects the output of fputs_unfiltered so that
the user can see what's going on in his debugger window. */
@ -76,17 +142,37 @@ static void
gdbtk_flush (stream)
FILE *stream;
{
if (stream != gdb_stdout || saved_output_buf)
return;
/* Flush output from C to tcl land. */
flush_holdbuf ();
/* Force immediate screen update */
Tcl_VarEval (interp, "gdbtk_tcl_flush", NULL);
}
static void
gdbtk_fputs (ptr)
gdbtk_fputs (ptr, stream)
const char *ptr;
FILE *stream;
{
int len;
if (stream != gdb_stdout)
{
Tcl_VarEval (interp, "gdbtk_tcl_fputs_error ", "{", ptr, "}", NULL);
return;
}
if (saved_output_buf)
{
save_output (ptr);
return;
}
len = strlen (ptr) + 1;
if (len > holdfree)
@ -122,43 +208,6 @@ gdbtk_query (args)
return val;
}
#if 0
static char *
full_filename(symtab)
struct symtab *symtab;
{
int pathlen;
char *filename;
if (!symtab)
return NULL;
if (symtab->fullname)
return savestring(symtab->fullname, strlen(symtab->fullname));
if (symtab->filename[0] == '/')
return savestring(symtab->filename, strlen(symtab->filename));
if (symtab->dirname)
pathlen = strlen(symtab->dirname);
else
pathlen = 0;
if (symtab->filename)
pathlen += strlen(symtab->filename);
filename = xmalloc(pathlen+1);
if (symtab->dirname)
strcpy(filename, symtab->dirname);
else
*filename = '\000';
if (symtab->filename)
strcat(filename, symtab->filename);
return filename;
}
#endif
static void
breakpoint_notify(b, action)
struct breakpoint *b;
@ -420,22 +469,6 @@ gdb_regnames (clientData, interp, argc, argv)
return map_arg_registers (argc, argv, get_register_name, 0);
}
static char reg_value[200];
static char *reg_valp = reg_value;
static void
save_reg_value (ptr)
const char *ptr;
{
int len;
len = strlen (ptr);
strncpy (reg_valp, ptr, len + 1);
reg_valp += len;
}
#ifndef REGISTER_CONVERTIBLE
#define REGISTER_CONVERTIBLE(x) (0 != 0)
#endif
@ -462,9 +495,7 @@ get_register (regnum, fp)
return;
}
fputs_unfiltered_hook = save_reg_value;
flush_hook = 0;
reg_valp = reg_value;
start_saving_output (); /* Start collecting stdout */
/* Convert raw data to virtual format if necessary. */
@ -479,10 +510,9 @@ get_register (regnum, fp)
val_print (REGISTER_VIRTUAL_TYPE (regnum), virtual_buffer, 0,
gdb_stdout, format, 1, 0, Val_pretty_default);
fputs_unfiltered_hook = gdbtk_fputs;
flush_hook = gdbtk_flush;
Tcl_AppendElement (interp, get_saved_output ());
Tcl_AppendElement (interp, reg_value);
finish_saving_output (); /* Set stdout back to normal */
}
static int
@ -552,15 +582,6 @@ gdb_changed_register_list (clientData, interp, argc, argv)
return map_arg_registers (argc, argv, register_changed_p, NULL);
}
static int
gdb_cmd_stub (cmd)
char *cmd;
{
execute_command (cmd, 1);
return 1; /* Indicate success */
}
/* This implements the TCL command `gdb_cmd', which sends it's argument into
the GDB command scanner. */
@ -571,40 +592,72 @@ gdb_cmd (clientData, interp, argc, argv)
int argc;
char *argv[];
{
int val;
struct cleanup *old_chain;
if (argc != 2)
{
Tcl_SetResult (interp, "wrong # args", TCL_STATIC);
return TCL_ERROR;
}
old_chain = make_cleanup (null_routine, 0);
val = catch_errors (gdb_cmd_stub, argv[1], "", RETURN_MASK_ERROR);
/* In case of an error, we may need to force the GUI into idle mode because
gdbtk_call_command may have bombed out while in the command routine. */
if (val == 0)
Tcl_VarEval (interp, "gdbtk_tcl_idle", NULL);
execute_command (argv[1], 1);
bpstat_do_actions (&stop_bpstat);
do_cleanups (old_chain);
/* Drain all buffered command output */
gdb_flush (gdb_stderr);
gdb_flush (gdb_stdout);
/* We could base the return value on val, but that would require most users
to use catch. Since GDB errors are already being handled elsewhere, I
see no reason to pass them up to the caller. */
return TCL_OK;
}
/* This routine acts as a top-level for all GDB code called by tcl/Tk. It
handles cleanups, and calls to return_to_top_level (usually via error).
This is necessary in order to prevent a longjmp out of the bowels of Tk,
possibly leaving things in a bad state. Since this routine can be called
recursively, it needs to save and restore the contents of the jmp_buf as
necessary. */
static int
call_wrapper (clientData, interp, argc, argv)
ClientData clientData;
Tcl_Interp *interp;
int argc;
char *argv[];
{
int val;
struct cleanup *saved_cleanup_chain;
Tcl_CmdProc *func;
jmp_buf saved_error_return;
func = (Tcl_CmdProc *)clientData;
memcpy (saved_error_return, error_return, sizeof (jmp_buf));
saved_cleanup_chain = save_cleanups ();
if (!setjmp (error_return))
val = func (clientData, interp, argc, argv);
else
{
val = TCL_ERROR; /* Flag an error for TCL */
finish_saving_output (); /* Restore stdout to normal */
gdb_flush (gdb_stderr); /* Flush error output */
/* In case of an error, we may need to force the GUI into idle mode because
gdbtk_call_command may have bombed out while in the command routine. */
Tcl_VarEval (interp, "gdbtk_tcl_idle", NULL);
}
do_cleanups (ALL_CLEANUPS);
restore_cleanups (saved_cleanup_chain);
memcpy (error_return, saved_error_return, sizeof (jmp_buf));
return val;
}
static int
gdb_listfiles (clientData, interp, argc, argv)
ClientData clientData;
@ -740,16 +793,18 @@ gdbtk_init ()
if (Tk_Init(interp) != TCL_OK)
error ("Tk_Init failed: %s", interp->result);
Tcl_CreateCommand (interp, "gdb_cmd", gdb_cmd, NULL, NULL);
Tcl_CreateCommand (interp, "gdb_loc", gdb_loc, NULL, NULL);
Tcl_CreateCommand (interp, "gdb_sourcelines", gdb_sourcelines, NULL, NULL);
Tcl_CreateCommand (interp, "gdb_listfiles", gdb_listfiles, NULL, NULL);
Tcl_CreateCommand (interp, "gdb_stop", gdb_stop, NULL, NULL);
Tcl_CreateCommand (interp, "gdb_regnames", gdb_regnames, NULL, NULL);
Tcl_CreateCommand (interp, "gdb_fetch_registers", gdb_fetch_registers, NULL,
Tcl_CreateCommand (interp, "gdb_cmd", call_wrapper, gdb_cmd, NULL);
Tcl_CreateCommand (interp, "gdb_loc", call_wrapper, gdb_loc, NULL);
Tcl_CreateCommand (interp, "gdb_sourcelines", call_wrapper, gdb_sourcelines,
NULL);
Tcl_CreateCommand (interp, "gdb_changed_register_list",
gdb_changed_register_list, NULL, NULL);
Tcl_CreateCommand (interp, "gdb_listfiles", call_wrapper, gdb_listfiles,
NULL);
Tcl_CreateCommand (interp, "gdb_stop", call_wrapper, gdb_stop, NULL);
Tcl_CreateCommand (interp, "gdb_regnames", call_wrapper, gdb_regnames, NULL);
Tcl_CreateCommand (interp, "gdb_fetch_registers", call_wrapper,
gdb_fetch_registers, NULL);
Tcl_CreateCommand (interp, "gdb_changed_register_list", call_wrapper,
gdb_changed_register_list, NULL);
gdbtk_filename = getenv ("GDBTK_FILENAME");
if (!gdbtk_filename)

View File

@ -8,6 +8,8 @@ set screen_top 0
set screen_bot 0
set current_output_win .cmd.text
set cfunc NIL
set line_numbers 1
#option add *Foreground Black
#option add *Background White
#option add *Font -*-*-medium-r-normal--18-*-*-*-m-*-*-1
@ -46,6 +48,11 @@ proc gdbtk_tcl_fputs {arg} {
$current_output_win yview -pickplace end
}
proc gdbtk_tcl_fputs_error {arg} {
.cmd.text insert end "$arg"
.cmd.text yview -pickplace end
}
#
# GDB Callback:
#
@ -354,43 +361,52 @@ proc delete_breakpoint_tag {win line} {
}
proc gdbtk_tcl_busy {} {
.src.start configure -state disabled
.src.stop configure -state normal
.src.step configure -state disabled
.src.next configure -state disabled
.src.continue configure -state disabled
.src.finish configure -state disabled
.src.up configure -state disabled
.src.down configure -state disabled
.src.bottom configure -state disabled
.asm.stepi configure -state disabled
.asm.nexti configure -state disabled
.asm.continue configure -state disabled
.asm.finish configure -state disabled
.asm.up configure -state disabled
.asm.down configure -state disabled
.asm.bottom configure -state disabled
.asm.close configure -state disabled
if [winfo exists .src] {
.src.start configure -state disabled
.src.stop configure -state normal
.src.step configure -state disabled
.src.next configure -state disabled
.src.continue configure -state disabled
.src.finish configure -state disabled
.src.up configure -state disabled
.src.down configure -state disabled
.src.bottom configure -state disabled
}
if [winfo exists .asm] {
.asm.stepi configure -state disabled
.asm.nexti configure -state disabled
.asm.continue configure -state disabled
.asm.finish configure -state disabled
.asm.up configure -state disabled
.asm.down configure -state disabled
.asm.bottom configure -state disabled
.asm.close configure -state disabled
}
}
proc gdbtk_tcl_idle {} {
.src.start configure -state normal
.src.stop configure -state disabled
.src.step configure -state normal
.src.next configure -state normal
.src.continue configure -state normal
.src.finish configure -state normal
.src.up configure -state normal
.src.down configure -state normal
.src.bottom configure -state normal
.asm.stepi configure -state normal
.asm.nexti configure -state normal
.asm.continue configure -state normal
.asm.finish configure -state normal
.asm.up configure -state normal
.asm.down configure -state normal
.asm.bottom configure -state normal
.asm.close configure -state normal
if [winfo exists .src] {
.src.start configure -state normal
.src.stop configure -state disabled
.src.step configure -state normal
.src.next configure -state normal
.src.continue configure -state normal
.src.finish configure -state normal
.src.up configure -state normal
.src.down configure -state normal
.src.bottom configure -state normal
}
if [winfo exists .asm] {
.asm.stepi configure -state normal
.asm.nexti configure -state normal
.asm.continue configure -state normal
.asm.finish configure -state normal
.asm.up configure -state normal
.asm.down configure -state normal
.asm.bottom configure -state normal
.asm.close configure -state normal
}
}
#
@ -732,6 +748,7 @@ proc display_expression {expression} {
proc create_file_win {filename debug_file} {
global breakpoint_file
global breakpoint_line
global line_numbers
# Replace all the dirty characters in $filename with clean ones, and generate
# a unique name for the text widget.
@ -767,25 +784,32 @@ proc create_file_win {filename debug_file} {
bind $win <1> do_nothing
bind $win <B1-Motion> do_nothing
bind $win n {gdb_cmd next ; update_ptr}
bind $win s {gdb_cmd step ; update_ptr}
bind $win c {gdb_cmd continue ; update_ptr}
bind $win f {gdb_cmd finish ; update_ptr}
bind $win u {gdb_cmd up ; update_ptr}
bind $win d {gdb_cmd down ; update_ptr}
bind $win n {catch {gdb_cmd next} ; update_ptr}
bind $win s {catch {gdb_cmd step} ; update_ptr}
bind $win c {catch {gdb_cmd continue} ; update_ptr}
bind $win f {catch {gdb_cmd finish} ; update_ptr}
bind $win u {catch {gdb_cmd up} ; update_ptr}
bind $win d {catch {gdb_cmd down} ; update_ptr}
$win delete 0.0 end
$win insert 0.0 [read $fh]
close $fh
# Add margins (for annotations) and a line number to each line
# Add margins (for annotations) and a line number to each line (if requested)
set numlines [$win index end]
set numlines [lindex [split $numlines .] 0]
for {set i 1} {$i <= $numlines} {incr i} {
$win insert $i.0 [format " %4d " $i]
$win tag add source $i.8 "$i.0 lineend"
}
if $line_numbers {
for {set i 1} {$i <= $numlines} {incr i} {
$win insert $i.0 [format " %4d " $i]
$win tag add source $i.8 "$i.0 lineend"
}
} else {
for {set i 1} {$i <= $numlines} {incr i} {
$win insert $i.0 " "
$win tag add source $i.8 "$i.0 lineend"
}
}
# Add the breakdots
@ -873,12 +897,12 @@ proc create_asm_win {funcname pc} {
bind $win <Enter> {focus %W}
bind $win <1> {asm_window_button_1 %W %X %Y %x %y}
bind $win <B1-Motion> do_nothing
bind $win n {gdb_cmd nexti ; update_ptr}
bind $win s {gdb_cmd stepi ; update_ptr}
bind $win c {gdb_cmd continue ; update_ptr}
bind $win f {gdb_cmd finish ; update_ptr}
bind $win u {gdb_cmd up ; update_ptr}
bind $win d {gdb_cmd down ; update_ptr}
bind $win n {catch {gdb_cmd nexti} ; update_ptr}
bind $win s {catch {gdb_cmd stepi} ; update_ptr}
bind $win c {catch {gdb_cmd continue} ; update_ptr}
bind $win f {catch {gdb_cmd finish} ; update_ptr}
bind $win u {catch {gdb_cmd up} ; update_ptr}
bind $win d {catch {gdb_cmd down} ; update_ptr}
# Disassemble the code, and read it into the new text widget
@ -1090,23 +1114,23 @@ proc create_asm_window {} {
frame .asm.row2
button .asm.stepi -width 6 -text Stepi \
-command {gdb_cmd stepi ; update_ptr}
-command {catch {gdb_cmd stepi} ; update_ptr}
button .asm.nexti -width 6 -text Nexti \
-command {gdb_cmd nexti ; update_ptr}
-command {catch {gdb_cmd nexti} ; update_ptr}
button .asm.continue -width 6 -text Cont \
-command {gdb_cmd continue ; update_ptr}
-command {catch {gdb_cmd continue} ; update_ptr}
button .asm.finish -width 6 -text Finish \
-command {gdb_cmd finish ; update_ptr}
button .asm.up -width 6 -text Up -command {gdb_cmd up ; update_ptr}
-command {catch {gdb_cmd finish} ; update_ptr}
button .asm.up -width 6 -text Up -command {catch {gdb_cmd up} ; update_ptr}
button .asm.down -width 6 -text Down \
-command {gdb_cmd down ; update_ptr}
-command {catch {gdb_cmd down} ; update_ptr}
button .asm.bottom -width 6 -text Bottom \
-command {gdb_cmd {frame 0} ; update_ptr}
-command {catch {gdb_cmd {frame 0}} ; update_ptr}
pack .asm.stepi .asm.continue .asm.up .asm.bottom -side left -padx 3 -pady 5 -in .asm.row1
pack .asm.nexti .asm.finish .asm.down -side left -padx 3 -pady 5 -in .asm.row2
pack .asm.row1 .asm.row2 -side top -anchor w
pack .asm.row2 .asm.row1 -side bottom -anchor w -before .asm.info
update
@ -1127,9 +1151,23 @@ proc reg_config_menu {} {
set regnames [gdb_regnames]
set num_regs [llength $regnames]
button .reg.config.done -text Done -command {destroy .reg.config}
frame .reg.config.buts
pack .reg.config.done -side bottom -fill x
button .reg.config.done -text " Done " -command "
recompute_reg_display_list $num_regs
populate_reg_window
update_registers all
destroy .reg.config "
button .reg.config.update -text Update -command "
recompute_reg_display_list $num_regs
populate_reg_window
update_registers all "
pack .reg.config.buts -side bottom -fill x
pack .reg.config.done -side left -fill x -expand yes -in .reg.config.buts
pack .reg.config.update -side right -fill x -expand yes -in .reg.config.buts
# Since there can be lots of registers, we build the window with no more than
# 32 rows, and as many columns as needed.
@ -1151,10 +1189,7 @@ proc reg_config_menu {} {
for {set regnum 0} {$regnum < $num_regs} {incr regnum} {
set regname [lindex $regnames $regnum]
checkbutton .reg.config.col$col.$row -text $regname -pady 0 \
-variable regena($regnum) -relief flat -anchor w -bd 1 \
-command "recompute_reg_display_list $num_regs
populate_reg_window
update_registers all"
-variable regena($regnum) -relief flat -anchor w -bd 1
pack .reg.config.col$col.$row -side top -fill both
@ -1199,44 +1234,38 @@ proc create_registers_window {} {
build_framework .reg Registers
.reg.menubar.view.menu add command -label Natural
.reg.menubar.view.menu add command -label Config -command {
reg_config_menu }
# First, delete all the old menu entries
.reg.menubar.view.menu delete 0 last
# Hex menu item
.reg.menubar.view.menu entryconfigure 0 -command {
global reg_format
.reg.menubar.view.menu add radiobutton -variable reg_format \
-label Hex -value x -command {update_registers all}
set reg_format x
update_registers all
}
# Decimal menu item
.reg.menubar.view.menu entryconfigure 1 -command {
global reg_format
.reg.menubar.view.menu add radiobutton -variable reg_format \
-label Decimal -value d -command {update_registers all}
set reg_format d
update_registers all
}
# Octal menu item
.reg.menubar.view.menu entryconfigure 2 -command {
global reg_format
.reg.menubar.view.menu add radiobutton -variable reg_format \
-label Octal -value o -command {update_registers all}
set reg_format o
update_registers all
}
# Natural menu item
.reg.menubar.view.menu entryconfigure 3 -command {
global reg_format
.reg.menubar.view.menu add radiobutton -variable reg_format \
-label Natural -value {} -command {update_registers all}
set reg_format {}
update_registers all
}
# Config menu item
.reg.menubar.view.menu add separator
.reg.menubar.view.menu add command -label Config -command {
reg_config_menu }
destroy .reg.label
# Install the reg names
populate_reg_window
update_registers all
}
# Convert regena into a list of the enabled $regnums
@ -1534,7 +1563,7 @@ proc build_framework {win {title GDBtk} {label {}}} {
${win}.menubar.file.menu add command -label Close \
-command "destroy ${win}"
${win}.menubar.file.menu add command -label Quit \
-command {gdb_cmd quit}
-command {catch {gdb_cmd quit}}
menubutton ${win}.menubar.view -padx 12 -text View \
-menu ${win}.menubar.view.menu -underline 0
@ -1598,36 +1627,53 @@ proc create_source_window {} {
build_framework .src Source "*No file*"
# First, delete all the old view menu entries
.src.menubar.view.menu delete 0 last
# Line numbers enable/disable menu item
.src.menubar.view.menu add checkbutton -variable line_numbers \
-label "Line numbers" -onvalue 1 -offvalue 0 -command {
foreach source [array names wins] {
if {$source == "Blank"} continue
destroy $wins($source)
unset wins($source)
}
set cfile Blank
update_listing [gdb_loc]
}
frame .src.row1
frame .src.row2
button .src.start -width 6 -text Start -command \
{gdb_cmd {break main}
gdb_cmd {enable delete $bpnum}
gdb_cmd run
{catch {gdb_cmd {break main}}
catch {gdb_cmd {enable delete $bpnum}}
catch {gdb_cmd run}
update_ptr }
button .src.stop -width 6 -text Stop -fg red -activeforeground red \
-state disabled -command gdb_stop
button .src.step -width 6 -text Step \
-command {gdb_cmd step ; update_ptr}
-command {catch {gdb_cmd step} ; update_ptr}
button .src.next -width 6 -text Next \
-command {gdb_cmd next ; update_ptr}
-command {catch {gdb_cmd next} ; update_ptr}
button .src.continue -width 6 -text Cont \
-command {gdb_cmd continue ; update_ptr}
-command {catch {gdb_cmd continue} ; update_ptr}
button .src.finish -width 6 -text Finish \
-command {gdb_cmd finish ; update_ptr}
button .src.up -width 6 -text Up -command {gdb_cmd up ; update_ptr}
-command {catch {gdb_cmd finish} ; update_ptr}
button .src.up -width 6 -text Up \
-command {catch {gdb_cmd up} ; update_ptr}
button .src.down -width 6 -text Down \
-command {gdb_cmd down ; update_ptr}
-command {catch {gdb_cmd down} ; update_ptr}
button .src.bottom -width 6 -text Bottom \
-command {gdb_cmd {frame 0} ; update_ptr}
-command {catch {gdb_cmd {frame 0}} ; update_ptr}
pack .src.start .src.step .src.continue .src.up .src.bottom \
-side left -padx 3 -pady 5 -in .src.row1
pack .src.stop .src.next .src.finish .src.down -side left -padx 3 \
-pady 5 -in .src.row2
pack .src.row1 .src.row2 -side top -anchor w
pack .src.row2 .src.row1 -side bottom -anchor w -before .src.info
$wins($cfile) insert 0.0 " This page intentionally left blank."
$wins($cfile) configure -width 88 -state disabled \
@ -1667,7 +1713,7 @@ proc create_command_window {} {
%W insert end \n
%W yview -pickplace end
gdb_cmd $command_line
catch "gdb_cmd {$command_line}"
set command_line {}
update_ptr
%W insert end "(gdb) "

View File

@ -41,6 +41,7 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
#endif
/* Temporary variable for SET_TOP_LEVEL. */
static int top_level_val;
/* Do a setjmp on error_return and quit_return. catch_errors is
@ -52,6 +53,14 @@ static int top_level_val;
? (PTR) 0 : (PTR) memcpy (quit_return, error_return, sizeof (jmp_buf))) \
, top_level_val)
/* If nonzero, display time usage both at startup and for each command. */
int display_time;
/* If nonzero, display space usage both at startup and for each command. */
int display_space;
extern void gdb_init PARAMS ((void));
int
@ -93,6 +102,8 @@ main (argc, argv)
register int i;
long time_at_startup = get_run_time ();
/* start-sanitize-mpw */
#ifdef MPW
/* Drop into MacsBug, but only if the executable is specially named. */
@ -174,13 +185,16 @@ main (argc, argv)
{"tty", required_argument, 0, 't'},
{"baud", required_argument, 0, 'b'},
{"b", required_argument, 0, 'b'},
{"nw", no_argument, &no_windows, 1},
{"nowindows", no_argument, &no_windows, 1},
{"nw", no_argument, &use_windows, 0},
{"nowindows", no_argument, &use_windows, 0},
{"w", no_argument, &use_windows, 1},
{"windows", no_argument, &use_windows, 1},
{"statistics", no_argument, 0, 13},
/* Allow machine descriptions to add more options... */
#ifdef ADDITIONAL_OPTIONS
ADDITIONAL_OPTIONS
#endif
{0, no_argument, 0, 0},
{0, no_argument, 0, 0}
};
while (1)
@ -212,6 +226,11 @@ main (argc, argv)
/* FIXME: what if the syntax is wrong (e.g. not digits)? */
annotation_level = atoi (optarg);
break;
case 13:
/* Enable the display of both time and space usage. */
display_time = 1;
display_space = 1;
break;
case 'f':
annotation_level = 1;
break;
@ -522,6 +541,25 @@ GDB manual (available as on-line info or a printed manual).\n", gdb_stdout);
BEFORE_MAIN_LOOP_HOOK;
#endif
/* Show time and/or space usage. */
if (display_time)
{
long init_time = get_run_time () - time_at_startup;
printf_unfiltered ("Startup time: %ld.%06ld\n",
init_time / 1000000, init_time % 1000000);
}
if (display_space)
{
extern char **environ;
char *lim = (char *) sbrk (0);
printf_unfiltered ("Startup size: data size %ld\n",
(long) (lim - (char *) &environ));
}
/* The command loop. */
while (1)
@ -570,7 +608,12 @@ fputs_unfiltered (linebuffer, stream)
{
if (fputs_unfiltered_hook)
{
fputs_unfiltered_hook (linebuffer);
/* FIXME: I think we should only be doing this for stdout or stderr.
Either that or we should be passing stream to the hook so it can
deal with it. If that is cleaned up, this function can go back
into utils.c and the fputs_unfiltered_hook can replace the current
ability to avoid this function by not linking with main.c. */
fputs_unfiltered_hook (linebuffer, stream);
return;
}

View File

@ -354,7 +354,7 @@ void (*command_loop_hook) PARAMS ((void));
/* Called instead of fputs for all output. */
void (*fputs_unfiltered_hook) PARAMS ((const char *linebuffer));
void (*fputs_unfiltered_hook) PARAMS ((const char *linebuffer, FILE *stream));
/* Called from print_frame_info to list the line we stopped in. */
@ -391,6 +391,12 @@ int (*target_wait_hook) PARAMS ((int pid, struct target_waitstatus *status));
void (*call_command_hook) PARAMS ((struct cmd_list_element *c, char *cmd,
int from_tty));
/* Takes control from error (). Typically used to prevent longjmps out of the
middle of the GUI. Usually used in conjunction with a catch routine. */
NORETURN void (*error_hook) PARAMS (());
/* Where to go for return_to_top_level (RETURN_ERROR). */
jmp_buf error_return;