aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gdb/ChangeLog20
-rw-r--r--gdb/defs.h40
-rw-r--r--gdb/gdbtk.c22
-rw-r--r--gdb/gdbtk.tcl108
-rw-r--r--gdb/top.c8
5 files changed, 129 insertions, 69 deletions
diff --git a/gdb/ChangeLog b/gdb/ChangeLog
index 398bd4c..8e8c8d1 100644
--- a/gdb/ChangeLog
+++ b/gdb/ChangeLog
@@ -1,3 +1,23 @@
+Fri Sep 16 15:40:34 1994 Stu Grossman (grossman@cygnus.com)
+
+ * defs.h (QUIT): Call interactive_hook to allow GUI to interrupt.
+ Also, add decl for symtab_to_filename.
+ * gdbtk.c: Replace calls to full_filename with symtab_to_filename.
+ * gdbtk.tcl: New routine pc_to_line replaces in line code. New
+ routine decr replaces in line code.
+ * (create_file_win): Use catch to handle open failures more
+ elegantly. Also, create special window to display file open
+ failure message. Move opening of file prior to creation of text
+ widget.
+ * (create_asm_win): Add PC as argument. We now base disassembly
+ on PC instead of function name, since function names can be
+ ambiguous (usually seen with shared libs). Also, use catch to
+ simplify code where we don't care about failures.
+ * source.c (symtab_to_filename): New. Returns the file
+ associated with a symtab.
+ * top.c: Define interactive_hook. Called during QUIT to animate
+ the GUI.
+
Fri Sep 16 00:14:40 1994 Per Bothner (bothner@kalessin.cygnus.com)
* stabsread.c (read_type): Handle stub types for bitstrings.
diff --git a/gdb/defs.h b/gdb/defs.h
index 4e98e21..36baf7f 100644
--- a/gdb/defs.h
+++ b/gdb/defs.h
@@ -66,7 +66,7 @@ extern int sevenbit_strings;
extern void quit PARAMS ((void));
-#define QUIT { if (quit_flag) quit (); }
+#define QUIT { if (quit_flag) quit (); if (interactive_hook) interactive_hook (); }
/* Command classes are top-level categories into which commands are broken
down for "help" purposes.
@@ -119,6 +119,13 @@ struct cleanup
PTR arg;
};
+/* Needed for various prototypes */
+
+#ifdef __STDC__
+struct symtab;
+struct breakpoint;
+#endif
+
/* From blockframe.c */
extern int inside_entry_func PARAMS ((CORE_ADDR));
@@ -310,6 +317,8 @@ extern void directory_command PARAMS ((char *, int));
extern void init_source_path PARAMS ((void));
+extern char *symtab_to_filename PARAMS ((struct symtab *));
+
/* From findvar.c */
extern int read_relative_register_raw_bytes PARAMS ((int, char *));
@@ -318,26 +327,6 @@ extern int read_relative_register_raw_bytes PARAMS ((int, char *));
extern char *tilde_expand PARAMS ((char *));
-/* Control types for commands */
-
-enum misc_command_type
-{
- ok_command,
- end_command,
- else_command,
- nop_command,
-};
-
-enum command_control_type
-{
- simple_control,
- break_control,
- continue_control,
- while_control,
- if_control,
- invalid_control
-};
-
/* Structure for saved commands lines
(for breakpoints, defined commands, etc). */
@@ -345,9 +334,6 @@ struct command_line
{
struct command_line *next;
char *line;
- enum command_control_type control_type;
- int body_count;
- struct command_line **body_list;
};
extern struct command_line *read_command_lines PARAMS ((void));
@@ -832,11 +818,6 @@ extern CORE_ADDR push_word PARAMS ((CORE_ADDR, unsigned LONGEST));
/* Hooks for alternate command interfaces. */
-#ifdef __STDC__
-struct symtab;
-struct breakpoint;
-#endif
-
extern void (*init_ui_hook) PARAMS ((void));
extern void (*command_loop_hook) PARAMS ((void));
extern void (*fputs_unfiltered_hook) PARAMS ((const char *linebuffer));
@@ -848,6 +829,7 @@ extern void (*create_breakpoint_hook) PARAMS ((struct breakpoint *b));
extern void (*delete_breakpoint_hook) PARAMS ((struct breakpoint *bpt));
extern void (*enable_breakpoint_hook) PARAMS ((struct breakpoint *bpt));
extern void (*disable_breakpoint_hook) PARAMS ((struct breakpoint *bpt));
+extern void (*interactive_hook) PARAMS ((void));
/* Inhibit window interface if non-zero. */
diff --git a/gdb/gdbtk.c b/gdb/gdbtk.c
index e3a2ce7..9843b43 100644
--- a/gdb/gdbtk.c
+++ b/gdb/gdbtk.c
@@ -129,6 +129,7 @@ gdbtk_query (args)
return val;
}
+#if 0
static char *
full_filename(symtab)
struct symtab *symtab;
@@ -163,6 +164,7 @@ full_filename(symtab)
return filename;
}
+#endif
static void
breakpoint_notify(b, action)
@@ -180,7 +182,7 @@ breakpoint_notify(b, action)
sal = find_pc_line (b->address, 0);
- filename = full_filename (sal.symtab);
+ filename = symtab_to_filename (sal.symtab);
sprintf (bpnum, "%d", b->number);
sprintf (line, "%d", sal.line);
@@ -200,9 +202,6 @@ breakpoint_notify(b, action)
gdbtk_fputs (interp->result);
gdbtk_fputs ("\n");
}
-
- if (filename)
- free (filename);
}
static void
@@ -293,7 +292,7 @@ gdb_loc (clientData, interp, argc, argv)
find_pc_partial_function (pc, &funcname, NULL, NULL);
Tcl_AppendElement (interp, funcname);
- filename = full_filename (sal.symtab);
+ filename = symtab_to_filename (sal.symtab);
Tcl_AppendElement (interp, filename);
sprintf (buf, "%d", sal.line);
@@ -302,9 +301,6 @@ gdb_loc (clientData, interp, argc, argv)
sprintf (buf, "0x%x", pc);
Tcl_AppendElement (interp, buf); /* PC */
- if (filename)
- free(filename);
-
return TCL_OK;
}
@@ -396,6 +392,15 @@ cleanup_init (ignored)
interp = NULL;
}
+/* Come here during long calculations to check for GUI events. Usually invoked
+ via the QUIT macro. */
+
+static void
+gdbtk_interactive ()
+{
+ /* Tk_DoOneEvent (TK_DONT_WAIT|TK_IDLE_EVENTS); */
+}
+
static void
gdbtk_init ()
{
@@ -445,6 +450,7 @@ gdbtk_init ()
delete_breakpoint_hook = gdbtk_delete_breakpoint;
enable_breakpoint_hook = gdbtk_enable_breakpoint;
disable_breakpoint_hook = gdbtk_disable_breakpoint;
+ interactive_hook = gdbtk_interactive;
discard_cleanups (old_chain);
diff --git a/gdb/gdbtk.tcl b/gdb/gdbtk.tcl
index a164fae..a142c3d 100644
--- a/gdb/gdbtk.tcl
+++ b/gdb/gdbtk.tcl
@@ -183,8 +183,7 @@ proc create_breakpoint {bpnum file line pc} {
set win [asm_win_name $cfunc]
if [winfo exists $win] {
- set line [lsearch -exact $pclist($cfunc) $pc]
- insert_breakpoint_tag $win $line
+ insert_breakpoint_tag $win [pc_to_line $pclist($cfunc) $pc]
}
}
@@ -219,12 +218,11 @@ proc delete_breakpoint {bpnum file line pc} {
# Reset breakpoint annotation info
if {$pos_to_bpcount($file:$line) > 0} {
- incr pos_to_bpcount($file:$line) -1
+ decr pos_to_bpcount($file:$line)
if {$pos_to_bpcount($file:$line) == 0} {
- if [info exists pos_to_breakpoint($file:$line)] {
- unset pos_to_breakpoint($file:$line)
- }
+ catch "unset pos_to_breakpoint($file:$line)"
+
unset breakpoint_file($bpnum)
unset breakpoint_line($bpnum)
@@ -239,16 +237,14 @@ proc delete_breakpoint {bpnum file line pc} {
# If there's an assembly window, update that too
if {$pos_to_bpcount($pc) > 0} {
- incr pos_to_bpcount($pc) -1
+ decr pos_to_bpcount($pc)
if {$pos_to_bpcount($pc) == 0} {
- if [info exists pos_to_breakpoint($pc)] {
- unset pos_to_breakpoint($pc)
- }
+ catch "unset pos_to_breakpoint($pc)"
+
set win [asm_win_name $cfunc]
if [winfo exists $win] {
- set line [lsearch -exact $pclist($cfunc) $pc]
- delete_breakpoint_tag $win $line
+ delete_breakpoint_tag $win [pc_to_line $pclist($cfunc) $pc]
}
}
}
@@ -278,8 +274,7 @@ proc enable_breakpoint {bpnum file line pc} {
set win [asm_win_name $cfunc]
if [winfo exists $win] {
- set line [lsearch -exact $pclist($cfunc) $pc]
- $win tag configure $line -fgstipple {}
+ $win tag configure [pc_to_line $pclist($cfunc) $pc] -fgstipple {}
}
}
@@ -307,8 +302,7 @@ proc disable_breakpoint {bpnum file line pc} {
set win [asm_win_name $cfunc]
if [winfo exists $win] {
- set line [lsearch -exact $pclist($cfunc) $pc]
- $win tag configure $line -fgstipple gray50
+ $win tag configure [pc_to_line $pclist($cfunc) $pc] -fgstipple gray50
}
}
@@ -352,6 +346,43 @@ proc delete_breakpoint_tag {win line} {
}
#
+# Local procedure:
+#
+# decr (var val) - compliment to incr
+#
+# Description:
+#
+#
+proc decr {var {val 1}} {
+ upvar $var num
+ set num [expr $num - $val]
+ return $num
+}
+
+#
+# Local procedure:
+#
+# pc_to_line (pclist pc) - convert PC to a line number.
+#
+# Description:
+#
+# Convert PC to a line number from PCLIST. If exact line isn't found,
+# we return the first line that starts before PC.
+#
+proc pc_to_line {pclist pc} {
+ set line [lsearch -exact $pclist $pc]
+
+ if {$line >= 1} { return $line }
+
+ set line 1
+ foreach linepc [lrange $pclist 1 end] {
+ if {$pc < $linepc} { decr line ; return $line }
+ incr line
+ }
+ return [expr $line - 1]
+}
+
+#
# Menu:
#
# file popup menu - Define the file popup menu.
@@ -617,6 +648,20 @@ proc create_file_win {filename} {
regsub -all {\.|/} $filename {} temp
set win .text$temp
+# Open the file, and read it into the text widget
+
+ if [catch "open $filename" fh] {
+# File can't be read. Put error message into .nofile window and return.
+
+ catch {destroy .nofile}
+ text .nofile -height 25 -width 80 -relief raised -borderwidth 2 -yscrollcommand textscrollproc -setgrid true -cursor hand2
+ .nofile insert 0.0 $fh
+ .nofile configure -state disabled
+ bind .nofile <1> do_nothing
+ bind .nofile <B1-Motion> do_nothing
+ return .nofile
+ }
+
# Actually create and do basic configuration on the text widget.
text $win -height 25 -width 80 -relief raised -borderwidth 2 -yscrollcommand textscrollproc -setgrid true -cursor hand2
@@ -633,9 +678,6 @@ proc create_file_win {filename} {
bind $win u {gdb_cmd up ; update_ptr}
bind $win d {gdb_cmd down ; update_ptr}
-# Open the file, and read it into the text widget
-
- set fh [open $filename]
$win delete 0.0 end
$win insert 0.0 [read $fh]
close $fh
@@ -665,7 +707,7 @@ proc create_file_win {filename} {
#
# Local procedure:
#
-# create_asm_win (funcname) - Create an assembly win for FUNCNAME.
+# create_asm_win (funcname pc) - Create an assembly win for FUNCNAME.
#
# Return value:
#
@@ -679,7 +721,7 @@ proc create_file_win {filename} {
# function FUNCNAME is read into the text widget.
#
-proc create_asm_win {funcname} {
+proc create_asm_win {funcname pc} {
global breakpoint_file
global breakpoint_line
global current_output_win
@@ -710,20 +752,22 @@ proc create_asm_win {funcname} {
# Disassemble the code, and read it into the new text widget
set current_output_win $win
- gdb_cmd "disassemble '$funcname'"
+ gdb_cmd "disassemble $pc"
set current_output_win .command.text
set numlines [$win index end]
set numlines [lindex [split $numlines .] 0]
+ decr numlines
# Delete the first and last lines, cuz these contain useless info
$win delete 1.0 2.0
$win delete {end - 1 lines} end
+ decr numlines 2
# Add margins (for annotations) and note the PC for each line
- if [info exists pclist($funcname)] { unset pclist($funcname) }
+ catch "unset pclist($funcname)"
lappend pclist($funcname) Unused
for {set i 1} {$i <= $numlines} {incr i} {
scan [$win get $i.0 "$i.0 lineend"] "%s " pc
@@ -835,9 +879,11 @@ proc update_listing {linespec} {
if ![info exists wins($cfile)] then {
set wins($cfile) [create_file_win $cfile]
- set win_to_file($wins($cfile)) $cfile
- set file_to_debug_file($cfile) $debug_file
- set pointers($cfile) 1.1
+ if {$wins($cfile) != ".nofile"} {
+ set win_to_file($wins($cfile)) $cfile
+ set file_to_debug_file($cfile) $debug_file
+ set pointers($cfile) 1.1
+ }
}
# Pack the text widget into the listing widget, and scroll to the right place
@@ -1042,7 +1088,7 @@ proc update_assembly {linespec} {
# If we want to switch funcs, we need to unpack the current text widget, and
# stick in the new one.
- if {$funcname != $cfunc} then {
+ if {$funcname != $cfunc } {
pack forget $win
set cfunc $funcname
@@ -1050,8 +1096,8 @@ proc update_assembly {linespec} {
# Create a text widget for this func if necessary
- if ![winfo exists $win] then {
- create_asm_win $cfunc
+ if {![winfo exists $win]} {
+ create_asm_win $cfunc $pc
set asm_pointers($cfunc) 1.1
set current_asm_label NIL
}
@@ -1060,7 +1106,7 @@ proc update_assembly {linespec} {
pack $win -side left -expand yes -fill both \
-after .asm.buts
- set line [lsearch -exact $pclist($cfunc) $pc]
+ set line [pc_to_line $pclist($cfunc) $pc]
$win yview [expr $line - $asm_screen_height / 2]
}
@@ -1083,7 +1129,7 @@ proc update_assembly {linespec} {
# Map the PC back to a line in the window
- set line [lsearch -exact $pclist($cfunc) $pc]
+ set line [pc_to_line $pclist($cfunc) $pc]
if {$line == -1} {
echo "Can't find PC $pc"
diff --git a/gdb/top.c b/gdb/top.c
index 2b5e9af..c052302 100644
--- a/gdb/top.c
+++ b/gdb/top.c
@@ -349,10 +349,16 @@ void (*flush_hook) PARAMS ((FILE *stream));
/* Called as appropriate to notify the interface of the specified breakpoint
conditions. */
-void (*create_breakpoint_hook) PARAMS ((struct breakpoint *b));
+void (*create_breakpoint_hook) PARAMS ((struct breakpoint *bpt));
void (*delete_breakpoint_hook) PARAMS ((struct breakpoint *bpt));
void (*enable_breakpoint_hook) PARAMS ((struct breakpoint *bpt));
void (*disable_breakpoint_hook) PARAMS ((struct breakpoint *bpt));
+
+/* Called during long calculations to allow GUI to repair window damage, and to
+ check for stop buttons, etc... */
+
+void (*interactive_hook) PARAMS ((void));
+
/* Where to go for return_to_top_level (RETURN_ERROR). */
jmp_buf error_return;