aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gdb/ChangeLog-gdbtk123
-rw-r--r--gdb/annotate.c36
-rw-r--r--gdb/annotate.h5
-rwxr-xr-xgdb/configure5
-rw-r--r--gdb/configure.in4
-rw-r--r--gdb/gdb.rc1
-rw-r--r--gdb/gdbtk.c723
-rw-r--r--gdb/gdbtool.icobin0 -> 1078 bytes
-rw-r--r--gdb/top.c10
9 files changed, 685 insertions, 222 deletions
diff --git a/gdb/ChangeLog-gdbtk b/gdb/ChangeLog-gdbtk
index 871edff..2b1002c 100644
--- a/gdb/ChangeLog-gdbtk
+++ b/gdb/ChangeLog-gdbtk
@@ -1,3 +1,126 @@
+Sat Mar 21 19:34:49 1998 Elena Zannoni <ezannoni@kwikemart.cygnus.com>
+
+ Merged changes from Foundry: list follows by author:
+
+ - Tom Tromey <tromey@cygnus.com>
+
+ * Makefile.in (gdbres.o): New target.
+ (WINDRES): New define.
+ * configure: Rebuilt.
+ * configure.in (WINDRES): Define.
+ (CONFIG_OBS): Include gdbres.o on Windows.
+ * gdbtool.ico: New file.
+ * gdb.rc: New file.
+ * gdbtk.c (gdbtk_init): Call ide_create_messagebox_command.
+ (gdbtk_cleanup): Call ide_interface_deregister_all.
+ (gdbtk_init): Pass event handle to cleanup.
+ (TclDebug): Use Tcl_Merge to construct command.
+ (gdbtk_init): Call ide_create_cygwin_path_command.
+
+ - Martin M. Hunt <hunt@cygnus.com>
+
+ * gdbtk.c (gdb_set_bp): Set addr_string for bp.
+ (gdb_get_breakpoint_info): Demangle function
+ names in breakpoint info.
+ Include "demangle.h".
+ (gdb_loc, gdb_listfuncs): Demangle C++
+ function names.
+ (gdb_set_bp): Properly quote filename to fix
+ problems with spaces. Send pc back as a hex string.
+ (gdb_listfuncs): Remove debugging line.
+ Turn off some debugging lines.
+ (breakpoint_notify): Return correct line number.
+ (gdb_get_breakpoint_info): Return correct line number.
+ (gdb_set_bp): New function to provide a better way to
+ set breakpoints.
+ (gdbtk_readline, gdbtk_readline_begin): Memory
+ allocated by tcl needs to be freed by Tcl_Free().
+ (find_file_in_dir): Deleted.
+ (gdb_find_file_command): Call full_lookup_symtab().
+ (gdb_listfuncs): Call full_lookup_symtab().
+ (full_lookup_symtab): New function. Like lookup_symtab
+ except handles multiple files with the same basename,
+ full pathnames, and always sets symtab->fullname.
+ (gdb_loadfile): Call full_lookup_symtab(). Clear
+ realloc'd memory.
+ (gdb_loadfile): Don't tag lines without source.
+ Tag source lines with source_tag.
+ (gdb_find_file_command, find_file_in_dir):
+ Rewrite. Now searches symtabs and psymtabs for a match
+ on the partial or full filename. Returns the full pathname.
+ (gdb_loadfile): Realloc additional memory
+ if someone loads in a file with more than 160,000
+ lines. I don't know if this really works because
+ I don't have enough memory to test it.
+ (gdb_sourcelines): Deleted.
+ (gdb_loadfile): New function. Takes a text widget
+ and loads it with the contents of a file. Marks
+ and tags source lines.
+ (pc_changed): New function.
+ (get_pc_register): Returns the value of
+ the PC to GDB.
+ (gdb_loc): If looking on the stack, return
+ real pc along with calling source line.
+ (gdb_loc): Return "" instead of "N/A" if
+ filename is not found.
+ (gdb_get_breakpoint_info): Same.
+ (get_register): For Natural mode, set format to 0.
+ Minor bugfixes from keiths.
+ (TclDebug): New function for debugging use.
+ (gdb_loc): Return correct PC for frames
+ that are not the innermost frame.
+ (gdb_listfiles): Rewritten to use object
+ API. Now takes an optional dirname which will cause
+ only files in that directory or its subdirectories
+ to be returned. Now returns basenames instead of
+ full pathnames.
+ (gdb_cmd): Set/reset load_in_progress flag.
+ (call_wrapper): Don't pop up dialog for errors in
+ downloads; just abort download.
+ (gdbtk_load_hash): Set return value correctly.
+
+ - Keith Seitz <keiths@onions.cygnus.com>
+
+ * gdbtk.c (gdbtk_init): Define the ui_loop_hook so that it can be
+ called by routines which might block, allowing us to update the GUI.
+ (gdbtk_wait): Move timer calls to annotation hooks.
+ (gdbtk_init): Define the annotation hooks.
+ (gdbtk_annotate_starting): New function for cygwin32 hosts.
+ (gdbtk_annotate_stopped): New function for cygwin32 hosts.
+ (gdbtk_annotate_exited): New function for cygwin32 hosts.
+ (gdbtk_annotate_signalled): New function. for cygwin32 hosts.
+ (gdbtk_init): Use gdbtk_print_frame_info hook.
+ (gdbtk_print_frame_info): New function which sets current_source_symtab
+ based on the given symtab and line info.
+ (gdb_immediate_command): New function which does
+ not buffer any
+ output. (Contrast to gdb_cmd.)
+ (gdb_prompt_command): New function to return gdb's prompt.
+ (find_file_in_dir): New functon which searches source paths
+ for a given filename.
+ (gdb_find_file): New function which returns path to given file -- uses
+ find_file_in_dir.
+ (gdbtk_init): Install "gdb_immediate", "gdb_find_file", and
+ "gdb_prompt"
+ commands into interpreter.
+
+ - Ian Lance Taylor <ian@cygnus.com>
+
+ * gdbtk.c (gdbtk_timer_going): If __CYGWIN32__, new static
+ variable.
+ (gdb_cmd): If __CYGWIN32__, if executing the load command, call
+ gdbtk_start_timer and gdbtk_stop_timer.
+ (call_wrapper): If __CYGWIN32__, if the timer is going, turn it
+ off. Clear load_in_progress.
+ (x_event): If load_in_progress, quit if download_cancel_ok.
+ (gdbtk_start_timer): Set gdbtk_timer_going.
+ (gdbtk_stop_timer): Clear gdbtk_timer_going.
+ (gdbtk_wait): Call x_event.
+ (gdbtk_init): Call ide_create_win_grab_command if
+ __CYGIN32__.
+ (gdb_clear_file): Clear stop_pc.
+
+
Tue Feb 10 17:50:37 1998 Keith Seitz <keiths@onions.cygnus.com>
* gdbtk.c (gdbtk_modify_tracepoint): Define new tracepoint modification hook.
diff --git a/gdb/annotate.c b/gdb/annotate.c
index cf83a8a..09d31f5 100644
--- a/gdb/annotate.c
+++ b/gdb/annotate.c
@@ -27,6 +27,11 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
static void print_value_flags PARAMS ((struct type *));
static void breakpoint_changed PARAMS ((struct breakpoint *));
+void (*annotate_starting_hook) PARAMS ((void));
+void (*annotate_stopped_hook) PARAMS ((void));
+void (*annotate_signalled_hook) PARAMS ((void));
+void (*annotate_exited_hook) PARAMS ((void));
+
static void
print_value_flags (t)
struct type *t;
@@ -66,30 +71,49 @@ annotate_watchpoint (num)
void
annotate_starting ()
{
- if (annotation_level > 1)
+
+ if (annotate_starting_hook)
+ annotate_starting_hook ();
+ else
{
- printf_filtered ("\n\032\032starting\n");
+ if (annotation_level > 1)
+ {
+ printf_filtered ("\n\032\032starting\n");
+ }
}
}
void
annotate_stopped ()
{
- if (annotation_level > 1)
- printf_filtered ("\n\032\032stopped\n");
+ if (annotate_stopped_hook)
+ annotate_stopped_hook ();
+ else
+ {
+ if (annotation_level > 1)
+ printf_filtered ("\n\032\032stopped\n");
+ }
}
void
annotate_exited (exitstatus)
int exitstatus;
{
- if (annotation_level > 1)
- printf_filtered ("\n\032\032exited %d\n", exitstatus);
+ if (annotate_exited_hook)
+ annotate_exited_hook ();
+ else
+ {
+ if (annotation_level > 1)
+ printf_filtered ("\n\032\032exited %d\n", exitstatus);
+ }
}
void
annotate_signalled ()
{
+ if (annotate_signalled_hook)
+ annotate_signalled_hook ();
+
if (annotation_level > 1)
printf_filtered ("\n\032\032signalled\n");
}
diff --git a/gdb/annotate.h b/gdb/annotate.h
index b91d140..3aad4d0 100644
--- a/gdb/annotate.h
+++ b/gdb/annotate.h
@@ -93,3 +93,8 @@ extern void annotate_elt_rep PARAMS ((unsigned int));
extern void annotate_elt_rep_end PARAMS ((void));
extern void annotate_elt PARAMS ((void));
extern void annotate_array_section_end PARAMS ((void));
+
+extern void (*annotate_starting_hook) PARAMS ((void));
+extern void (*annotate_stopped_hook) PARAMS ((void));
+extern void (*annotate_signalled_hook) PARAMS ((void));
+extern void (*annotate_exited_hook) PARAMS ((void));
diff --git a/gdb/configure b/gdb/configure
index 916e602..cc9be21 100755
--- a/gdb/configure
+++ b/gdb/configure
@@ -2608,6 +2608,9 @@ WIN32LDAPP=
+WINDRES=${WINDRES-windres}
+
+
if test x$gdb_cv_os_cygwin32 = xyes; then
if test x$enable_ide = xyes; then
WIN32LIBS="-ladvapi32"
@@ -3191,6 +3194,7 @@ fi
if test x$gdb_cv_os_cygwin32 = xyes; then
WIN32LIBS="${WIN32LIBS} -lshell32 -lgdi32 -lcomdlg32 -ladvapi32 -luser32"
WIN32LDAPP="-Wl,--subsystem,windows"
+ CONFIG_OBS="${CONFIG_OBS} gdbres.o"
fi
fi
fi
@@ -3630,6 +3634,7 @@ s%@MMALLOC@%$MMALLOC%g
s%@ENABLE_IDE@%$ENABLE_IDE%g
s%@WIN32LIBS@%$WIN32LIBS%g
s%@WIN32LDAPP@%$WIN32LDAPP%g
+s%@WINDRES@%$WINDRES%g
s%@TCL_VERSION@%$TCL_VERSION%g
s%@TCL_MAJOR_VERSION@%$TCL_MAJOR_VERSION%g
s%@TCL_MINOR_VERSION@%$TCL_MINOR_VERSION%g
diff --git a/gdb/configure.in b/gdb/configure.in
index c2d01ab..dc0e161 100644
--- a/gdb/configure.in
+++ b/gdb/configure.in
@@ -338,6 +338,9 @@ WIN32LDAPP=
AC_SUBST(WIN32LIBS)
AC_SUBST(WIN32LDAPP)
+WINDRES=${WINDRES-windres}
+AC_SUBST(WINDRES)
+
if test x$gdb_cv_os_cygwin32 = xyes; then
if test x$enable_ide = xyes; then
WIN32LIBS="-ladvapi32"
@@ -414,6 +417,7 @@ if test "${enable_gdbtk}" = "yes"; then
if test x$gdb_cv_os_cygwin32 = xyes; then
WIN32LIBS="${WIN32LIBS} -lshell32 -lgdi32 -lcomdlg32 -ladvapi32 -luser32"
WIN32LDAPP="-Wl,--subsystem,windows"
+ CONFIG_OBS="${CONFIG_OBS} gdbres.o"
fi
fi
fi
diff --git a/gdb/gdb.rc b/gdb/gdb.rc
new file mode 100644
index 0000000..9f7c440
--- /dev/null
+++ b/gdb/gdb.rc
@@ -0,0 +1 @@
+tk ICON DISCARDABLE "gdbtool.ico"
diff --git a/gdb/gdbtk.c b/gdb/gdbtk.c
index f335a68..fdc0d7e 100644
--- a/gdb/gdbtk.c
+++ b/gdb/gdbtk.c
@@ -29,6 +29,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
#include "target.h"
#include "gdbcore.h"
#include "tracepoint.h"
+#include "demangle.h"
#ifdef _WIN32
#include <winuser.h>
@@ -71,6 +72,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
#endif
#ifdef __CYGWIN32__
+#include "annotate.h"
#include <sys/time.h>
#endif
@@ -93,6 +95,16 @@ int (*ui_load_progress_hook) PARAMS ((char *, unsigned long));
void (*pre_add_symbol_hook) PARAMS ((char *));
void (*post_add_symbol_hook) PARAMS ((void));
+/* This is a disgusting hack. Unfortunately, the UI will lock up if we
+ are doing something like blocking in a system call, waiting for serial I/O,
+ or what have you.
+
+ This hook should be used whenever we might block. This means adding appropriate
+ timeouts to code and what not to allow this hook to be called. */
+void (*ui_loop_hook) PARAMS ((int));
+
+char * get_prompt PARAMS ((void));
+
static void null_routine PARAMS ((int));
static void gdbtk_flush PARAMS ((FILE *));
static void gdbtk_fputs PARAMS ((const char *, FILE *));
@@ -120,6 +132,7 @@ static int gdb_cmd PARAMS ((ClientData, Tcl_Interp *, int, char *argv[]));
static int gdb_immediate_command PARAMS ((ClientData, Tcl_Interp *, int, char *argv[]));
static int gdb_fetch_registers PARAMS ((ClientData, Tcl_Interp *, int, char *[]));
static void gdbtk_readline_end PARAMS ((void));
+static void pc_changed PARAMS ((void));
static int gdb_changed_register_list PARAMS ((ClientData, Tcl_Interp *, int, char *[]));
static void register_changed_p PARAMS ((int, void *));
static int gdb_get_breakpoint_list PARAMS ((ClientData, Tcl_Interp *, int, char *[]));
@@ -130,7 +143,6 @@ static void gdbtk_delete_breakpoint PARAMS ((struct breakpoint *));
static void gdbtk_modify_breakpoint PARAMS ((struct breakpoint *));
static int gdb_loc PARAMS ((ClientData, Tcl_Interp *, int, char *[]));
static int gdb_eval PARAMS ((ClientData, Tcl_Interp *, int, char *[]));
-static int gdb_sourcelines PARAMS ((ClientData, Tcl_Interp *, int, char *[]));
static int map_arg_registers PARAMS ((int, char *[], void (*) (int, void *), void *));
static void get_register_name PARAMS ((int, void *));
static int gdb_regnames PARAMS ((ClientData, Tcl_Interp *, int, char *[]));
@@ -156,9 +168,19 @@ static void tracepoint_notify PARAMS ((struct tracepoint *, const char *));
static void gdbtk_print_frame_info PARAMS ((struct symtab *, int, int, int));
void gdbtk_pre_add_symbol PARAMS ((char *));
void gdbtk_post_add_symbol PARAMS ((void));
+static int get_pc_register PARAMS ((ClientData, Tcl_Interp *, int, char *[]));
+static int gdb_loadfile PARAMS ((ClientData, Tcl_Interp *, int, Tcl_Obj *CONST objv[]));
+static int gdb_set_bp PARAMS ((ClientData, Tcl_Interp *, int, Tcl_Obj *CONST objv[]));
+static struct symtab *full_lookup_symtab PARAMS ((char *file));
+static int gdb_get_mem PARAMS ((ClientData, Tcl_Interp *, int, char *[]));
+#ifdef __CYGWIN32__
+static void gdbtk_annotate_starting PARAMS ((void));
+static void gdbtk_annotate_stopped PARAMS ((void));
+static void gdbtk_annotate_signalled PARAMS ((void));
+static void gdbtk_annotate_exited PARAMS ((void));
+#endif
/* Handle for TCL interpreter */
-
static Tcl_Interp *interp = NULL;
#ifndef WINNT
@@ -360,7 +382,7 @@ gdbtk_readline_begin (va_alist)
merge[1] = buf;
command = Tcl_Merge (2, merge);
Tcl_Eval (interp, command);
- free (command);
+ Tcl_Free (command);
}
static char *
@@ -379,7 +401,7 @@ gdbtk_readline (prompt)
merge[1] = prompt;
command = Tcl_Merge (2, merge);
result = Tcl_Eval (interp, command);
- free (command);
+ Tcl_Free (command);
if (result == TCL_OK)
{
return (strdup (interp -> result));
@@ -398,6 +420,12 @@ gdbtk_readline_end ()
Tcl_Eval (interp, "gdbtk_tcl_readline_end");
}
+static void
+pc_changed()
+{
+ Tcl_Eval (interp, "gdbtk_pc_changed");
+}
+
static void
#ifdef ANSI_PROTOTYPES
@@ -489,8 +517,8 @@ gdb_get_breakpoint_info (clientData, interp, argc, argv)
int bpnum;
struct breakpoint *b;
extern struct breakpoint *breakpoint_chain;
- char *funcname, *filename;
-
+ char *funcname, *fname, *filename;
+
if (argc != 2)
error ("wrong # args");
@@ -509,9 +537,17 @@ gdb_get_breakpoint_info (clientData, interp, argc, argv)
if (filename == NULL)
filename = "";
Tcl_DStringAppendElement (result_ptr, filename);
+
find_pc_partial_function (b->address, &funcname, NULL, NULL);
- Tcl_DStringAppendElement (result_ptr, funcname);
- dsprintf_append_element (result_ptr, "%d", sal.line);
+ fname = cplus_demangle (funcname, 0);
+ if (fname)
+ {
+ Tcl_DStringAppendElement (result_ptr, fname);
+ free (fname);
+ }
+ else
+ Tcl_DStringAppendElement (result_ptr, funcname);
+ dsprintf_append_element (result_ptr, "%d", b->line_number);
dsprintf_append_element (result_ptr, "0x%lx", b->address);
Tcl_DStringAppendElement (result_ptr, bptypes[b->type]);
Tcl_DStringAppendElement (result_ptr, b->enable == enabled ? "1" : "0");
@@ -549,9 +585,10 @@ breakpoint_notify(b, action)
sal = find_pc_line (b->address, 0);
filename = symtab_to_filename (sal.symtab);
if (filename == NULL)
- filename = "N/A";
+ filename = "";
+
sprintf (buf, "gdbtk_tcl_breakpoint %s %d 0x%lx %d {%s}", action, b->number,
- (long)b->address, sal.line, filename);
+ (long)b->address, b->line_number, filename);
v = Tcl_Eval (interp, buf);
@@ -583,8 +620,9 @@ gdbtk_modify_breakpoint(b)
breakpoint_notify (b, "modify");
}
-/* This implements the TCL command `gdb_loc', which returns a list consisting
- of the source and line number associated with the current pc. */
+/* This implements the TCL command `gdb_loc', which returns a list */
+/* consisting of the following: */
+/* basename, function name, filename, line number, address, current pc */
static int
gdb_loc (clientData, interp, argc, argv)
@@ -595,7 +633,7 @@ gdb_loc (clientData, interp, argc, argv)
{
char *filename;
struct symtab_and_line sal;
- char *funcname;
+ char *funcname, *fname;
CORE_ADDR pc;
if (!have_full_symbols () && !have_partial_symbols ())
@@ -603,18 +641,28 @@ gdb_loc (clientData, interp, argc, argv)
Tcl_SetResult (interp, "No symbol table is loaded", TCL_STATIC);
return TCL_ERROR;
}
-
+
if (argc == 1)
{
- if (selected_frame)
+ if (selected_frame && (selected_frame->pc != stop_pc))
{
+ /* Note - this next line is not correct on all architectures. */
+ /* For a graphical debugged we really want to highlight the */
+ /* assembly line that called the next function on the stack. */
+ /* Many architectures have the next instruction saved as the */
+ /* pc on the stack, so what happens is the next instruction is hughlighted. */
+ /* FIXME */
+ pc = selected_frame->pc;
sal = find_pc_line (selected_frame->pc,
selected_frame->next != NULL
&& !selected_frame->next->signal_handler_caller
&& !frame_in_dummy (selected_frame->next));
}
else
- sal = find_pc_line (stop_pc, 0);
+ {
+ pc = stop_pc;
+ sal = find_pc_line (stop_pc, 0);
+ }
}
else if (argc == 2)
{
@@ -640,11 +688,17 @@ gdb_loc (clientData, interp, argc, argv)
Tcl_DStringAppendElement (result_ptr, "");
find_pc_partial_function (pc, &funcname, NULL, NULL);
- Tcl_DStringAppendElement (result_ptr, funcname);
-
+ fname = cplus_demangle (funcname, 0);
+ if (fname)
+ {
+ Tcl_DStringAppendElement (result_ptr, fname);
+ free (fname);
+ }
+ else
+ Tcl_DStringAppendElement (result_ptr, funcname);
filename = symtab_to_filename (sal.symtab);
if (filename == NULL)
- filename = "N/A";
+ filename = "";
Tcl_DStringAppendElement (result_ptr, filename);
dsprintf_append_element (result_ptr, "%d", sal.line); /* line number */
@@ -771,55 +825,6 @@ gdb_get_mem (clientData, interp, argc, argv)
}
-/* This implements the TCL command `gdb_sourcelines', which returns a list of
- all of the lines containing executable code for the specified source file
- (ie: lines where you can put breakpoints). */
-
-static int
-gdb_sourcelines (clientData, interp, argc, argv)
- ClientData clientData;
- Tcl_Interp *interp;
- int argc;
- char *argv[];
-{
- struct symtab *symtab;
- struct linetable_entry *le;
- int nlines;
-
- if (argc != 2)
- error ("wrong # args");
-
- symtab = lookup_symtab (argv[1]);
-
- if (!symtab)
- error ("No such file");
-
- /* If there's no linetable, or no entries, then we are done. */
-
- if (!symtab->linetable
- || symtab->linetable->nitems == 0)
- {
- Tcl_DStringAppendElement (result_ptr, "");
- return TCL_OK;
- }
-
- le = symtab->linetable->item;
- nlines = symtab->linetable->nitems;
-
- for (;nlines > 0; nlines--, le++)
- {
- /* If the pc of this line is the same as the pc of the next line, then
- just skip it. */
- if (nlines > 1
- && le->pc == (le + 1)->pc)
- continue;
-
- dsprintf_append_element (result_ptr, "%d", le->line);
- }
-
- return TCL_OK;
-}
-
static int
map_arg_registers (argc, argv, func, argp)
int argc;
@@ -909,6 +914,9 @@ get_register (regnum, fp)
char virtual_buffer[MAX_REGISTER_VIRTUAL_SIZE];
int format = (int)fp;
+ if (format == 'N')
+ format = 0;
+
if (read_relative_register_raw_bytes (regnum, raw_buffer))
{
Tcl_DStringAppendElement (result_ptr, "Optimized out");
@@ -944,6 +952,17 @@ get_register (regnum, fp)
}
static int
+get_pc_register (clientData, interp, argc, argv)
+ ClientData clientData;
+ Tcl_Interp *interp;
+ int argc;
+ char *argv[];
+{
+ sprintf(interp->result,"0x%llx",(long long)read_register(PC_REGNUM));
+ return TCL_OK;
+}
+
+static int
gdb_fetch_registers (clientData, interp, argc, argv)
ClientData clientData;
Tcl_Interp *interp;
@@ -955,12 +974,10 @@ gdb_fetch_registers (clientData, interp, argc, argv)
if (argc < 2)
error ("wrong # args");
- argc--;
+ argc -= 2;
argv++;
-
- argc--;
format = **argv++;
-
+
return map_arg_registers (argc, argv, get_register, (void *) format);
}
@@ -1160,14 +1177,9 @@ call_wrapper (clientData, interp, argc, argv)
running_now = 0;
Tcl_Eval (interp, "gdbtk_tcl_idle");
}
-
- /* if the download was cancelled, don't print the error */
- if (load_in_progress)
- {
- Tcl_DStringInit (&error_string);
- wrapped_args.val = TCL_OK;
- load_in_progress = 0;
- }
+
+ /* do not suppress any errors -- a remote target could have errored */
+ load_in_progress = 0;
if (Tcl_DStringLength (&error_string) == 0)
{
@@ -1206,7 +1218,6 @@ comp_files (file1, file2)
return strcmp(*file1,*file2);
}
-
static int
gdb_listfiles (clientData, interp, objc, objv)
ClientData clientData;
@@ -1217,14 +1228,10 @@ gdb_listfiles (clientData, interp, objc, objv)
struct objfile *objfile;
struct partial_symtab *psymtab;
struct symtab *symtab;
- char *lastfile, *pathname, **files;
- int files_size;
+ char *lastfile, *pathname, *files[1000];
int i, numfiles = 0, len = 0;
Tcl_Obj *mylist;
- files_size = 1000;
- files = (char **) xmalloc (sizeof (char *) * files_size);
-
if (objc > 2)
{
Tcl_WrongNumArgs (interp, 1, objv, "Usage: gdb_listfiles ?pathname?");
@@ -1237,11 +1244,6 @@ gdb_listfiles (clientData, interp, objc, objv)
ALL_PSYMTABS (objfile, psymtab)
{
- if (numfiles == files_size)
- {
- files_size = files_size * 2;
- files = (char **) xrealloc (files, sizeof (char *) * files_size);
- }
if (len == 0)
{
if (psymtab->filename)
@@ -1255,11 +1257,6 @@ gdb_listfiles (clientData, interp, objc, objv)
ALL_SYMTABS (objfile, symtab)
{
- if (numfiles == files_size)
- {
- files_size = files_size * 2;
- files = (char **) xrealloc (files, sizeof (char *) * files_size);
- }
if (len == 0)
{
if (symtab->filename)
@@ -1281,7 +1278,6 @@ gdb_listfiles (clientData, interp, objc, objv)
lastfile = files[i];
}
Tcl_SetObjResult (interp, mylist);
- free (files);
return TCL_OK;
}
@@ -1296,13 +1292,13 @@ gdb_listfuncs (clientData, interp, argc, argv)
struct blockvector *bv;
struct block *b;
struct symbol *sym;
+ char buf[128];
int i,j;
-
+
if (argc != 2)
error ("wrong # args");
- symtab = lookup_symtab (argv[1]);
-
+ symtab = full_lookup_symtab (argv[1]);
if (!symtab)
error ("No such file");
@@ -1318,7 +1314,15 @@ gdb_listfuncs (clientData, interp, argc, argv)
sym = BLOCK_SYM (b, j);
if (SYMBOL_CLASS (sym) == LOC_BLOCK)
{
- Tcl_DStringAppendElement (result_ptr, SYMBOL_NAME(sym));
+
+ char *name = cplus_demangle (SYMBOL_NAME(sym), 0);
+ if (name)
+ {
+ sprintf (buf,"{%s} 1", name);
+ }
+ else
+ sprintf (buf,"{%s} 0", SYMBOL_NAME(sym));
+ Tcl_DStringAppendElement (result_ptr, buf);
}
}
}
@@ -1708,10 +1712,10 @@ x_event (signo)
int signo;
{
/* Process pending events */
-
while (Tcl_DoOneEvent (TCL_DONT_WAIT|TCL_ALL_EVENTS) != 0)
;
+
/* If we are doing a download, see if the download should be
cancelled. FIXME: We should use a better variable name. */
if (load_in_progress)
@@ -1746,6 +1750,7 @@ gdbtk_start_timer ()
struct sigaction action;
struct itimerval it;
+ /*TclDebug ("Starting timer....");*/
sigemptyset (&nullsigmask);
action.sa_handler = x_event;
@@ -1772,7 +1777,8 @@ gdbtk_stop_timer ()
struct itimerval it;
gdbtk_timer_going = 0;
-
+
+ /*TclDebug ("Stopping timer.");*/
sigemptyset (&nullsigmask);
action.sa_handler = SIG_IGN;
@@ -1813,21 +1819,8 @@ gdbtk_wait (pid, ourstatus)
sigaction(SIGIO, &action, NULL);
#endif /* WINNT */
-#ifdef __CYGWIN32__
- /* Call x_event ourselves now, as well as starting the timer;
- otherwise, if single stepping, we may never wait long enough for
- the timer to trigger. */
- x_event (SIGALRM);
-
- gdbtk_start_timer ();
-#endif
-
pid = target_wait (pid, ourstatus);
-#ifdef __CYGWIN32__
- gdbtk_stop_timer ();
-#endif
-
#ifndef WINNT
action.sa_handler = SIG_IGN;
sigaction(SIGIO, &action, NULL);
@@ -1900,6 +1893,11 @@ static void
gdbtk_cleanup (dummy)
PTR dummy;
{
+#ifdef IDE
+ struct ide_event_handle *h = (struct ide_event_handle *) dummy;
+
+ ide_interface_deregister_all (h);
+#endif
Tcl_Finalize ();
}
@@ -1945,7 +1943,11 @@ gdbtk_init ( argv0 )
if (Tcl_Init(interp) != TCL_OK)
error ("Tcl_Init failed: %s", interp->result);
- make_final_cleanup (gdbtk_cleanup, NULL);
+#ifndef IDE
+ /* For the IDE we register the cleanup later, after we've
+ initialized events. */
+ make_final_cleanup (gdbtk_cleanup, NULL);
+#endif
/* Initialize the Paths variable. */
if (ide_initialize_paths (interp, "gdbtcl") != TCL_OK)
@@ -1960,6 +1962,7 @@ gdbtk_init ( argv0 )
IluTk_Init ();
h = ide_event_init_from_environment (&errmsg, libexecdir);
+ make_final_cleanup (gdbtk_cleanup, h);
if (h == NULL)
{
Tcl_AppendResult (interp, "can't initialize event system: ", errmsg,
@@ -2023,6 +2026,8 @@ gdbtk_init ( argv0 )
error ("Tix_Init failed: %s", interp->result);
#ifdef __CYGWIN32__
+ if (ide_create_messagebox_command (interp) != TCL_OK)
+ error ("messagebox command initialization failed");
/* On Windows, create a sizebox widget command */
if (ide_create_sizebox_command (interp) != TCL_OK)
error ("sizebox creation failed");
@@ -2033,6 +2038,11 @@ gdbtk_init ( argv0 )
if (ide_create_shell_execute_command (interp) != TCL_OK)
error ("shell execute command initialization failed");
/* end-sanitize-ide */
+ if (ide_create_win_grab_command (interp) != TCL_OK)
+ error ("grab support command initialization failed");
+ /* Path conversion functions. */
+ if (ide_create_cygwin_path_command (interp) != TCL_OK)
+ error ("cygwin path command initialization failed");
#endif
Tcl_CreateCommand (interp, "gdb_cmd", call_wrapper, gdb_cmd, NULL);
@@ -2040,8 +2050,6 @@ gdbtk_init ( argv0 )
gdb_immediate_command, NULL);
Tcl_CreateCommand (interp, "gdb_loc", call_wrapper, gdb_loc, NULL);
Tcl_CreateCommand (interp, "gdb_path_conv", call_wrapper, gdb_path_conv, NULL);
- Tcl_CreateCommand (interp, "gdb_sourcelines", call_wrapper, gdb_sourcelines,
- NULL);
Tcl_CreateObjCommand (interp, "gdb_listfiles", gdb_listfiles, NULL, NULL);
Tcl_CreateCommand (interp, "gdb_listfuncs", call_wrapper, gdb_listfuncs,
NULL);
@@ -2091,8 +2099,11 @@ gdbtk_init ( argv0 )
Tcl_CreateObjCommand (interp, "gdb_find_file",
gdb_find_file_command, NULL, NULL);
Tcl_CreateObjCommand (interp, "gdb_get_tracepoint_list",
- gdb_get_tracepoint_list, NULL, NULL);
-
+ gdb_get_tracepoint_list, NULL, NULL);
+ Tcl_CreateCommand (interp, "gdb_pc_reg", get_pc_register, NULL, NULL);
+ Tcl_CreateObjCommand (interp, "gdb_loadfile", gdb_loadfile, NULL, NULL);
+ Tcl_CreateObjCommand (interp, "gdb_set_bp", gdb_set_bp, NULL, NULL);
+
command_loop_hook = tk_command_loop;
print_frame_info_listing_hook = gdbtk_print_frame_info;
query_hook = gdbtk_query;
@@ -2112,7 +2123,14 @@ gdbtk_init ( argv0 )
create_tracepoint_hook = gdbtk_create_tracepoint;
delete_tracepoint_hook = gdbtk_delete_tracepoint;
modify_tracepoint_hook = gdbtk_modify_tracepoint;
-
+ pc_changed_hook = pc_changed;
+#ifdef __CYGWIN32__
+ annotate_starting_hook = gdbtk_annotate_starting;
+ annotate_stopped_hook = gdbtk_annotate_stopped;
+ annotate_signalled_hook = gdbtk_annotate_signalled;
+ annotate_exited_hook = gdbtk_annotate_exited;
+ ui_loop_hook = x_event;
+#endif
#ifndef WINNT
/* Get the file descriptor for the X server */
@@ -2613,6 +2631,71 @@ gdb_get_tracepoint_info (clientData, interp, objc, objv)
return TCL_OK;
}
+
+/* TclDebug (const char *fmt, ...) works just like printf() but */
+/* sends the output to the GDB TK debug window. */
+/* Not for normal use; just a convenient tool for debugging */
+void
+#ifdef ANSI_PROTOTYPES
+TclDebug (const char *fmt, ...)
+#else
+TclDebug (va_alist)
+ va_dcl
+#endif
+{
+ va_list args;
+ char buf[512], *v[2], *merge;
+
+#ifdef ANSI_PROTOTYPES
+ va_start (args, fmt);
+#else
+ char *fmt;
+ va_start (args);
+ fmt = va_arg (args, char *);
+#endif
+
+ v[0] = "debug";
+ v[1] = buf;
+
+ vsprintf (buf, fmt, args);
+ va_end (args);
+
+ merge = Tcl_Merge (2, v);
+ Tcl_Eval (interp, merge);
+ Tcl_Free (merge);
+}
+
+
+/* Find the full pathname to a file, searching the symbol tables */
+
+static int
+gdb_find_file_command (clientData, interp, objc, objv)
+ ClientData clientData;
+ Tcl_Interp *interp;
+ int objc;
+ Tcl_Obj *CONST objv[];
+{
+ char *filename = NULL;
+ struct symtab *st;
+
+ if (objc != 2)
+ {
+ Tcl_WrongNumArgs(interp, 1, objv, "filename");
+ return TCL_ERROR;
+ }
+
+ st = full_lookup_symtab (Tcl_GetStringFromObj (objv[1], NULL));
+ if (st)
+ filename = st->fullname;
+
+ if (filename == NULL)
+ Tcl_SetObjResult (interp, Tcl_NewStringObj ("", 0));
+ else
+ Tcl_SetObjResult (interp, Tcl_NewStringObj (filename, -1));
+
+ return TCL_OK;
+}
+
static void
gdbtk_create_tracepoint (tp)
struct tracepoint *tp;
@@ -2816,140 +2899,350 @@ gdb_get_tracepoint_list (clientData, interp, objc, objv)
return TCL_OK;
}
-/* This is stolen from source.c */
-#ifdef CRLF_SOURCE_FILES
-/* Define CRLF_SOURCE_FILES in an xm-*.h file if source files on the
- host use \r\n rather than just \n. Defining CRLF_SOURCE_FILES is
- much faster than defining LSEEK_NOT_LINEAR. */
+/* This hook is called whenever we are ready to load a symbol file so that
+ the UI can notify the user... */
+void
+gdbtk_pre_add_symbol (name)
+ char *name;
+{
+ char command[256];
-#ifndef O_BINARY
-#define O_BINARY 0
-#endif
+ sprintf (command, "gdbtk_tcl_pre_add_symbol %s", name);
+ Tcl_Eval (interp, command);
+}
-#define OPEN_MODE (O_RDONLY | O_BINARY)
+/* This hook is called whenever we finish loading a symbol file. */
+void
+gdbtk_post_add_symbol ()
+{
+ Tcl_Eval (interp, "gdbtk_tcl_post_add_symbol");
+}
-#else /* ! defined (CRLF_SOURCE_FILES) */
-#define OPEN_MODE O_RDONLY
-#endif /* ! defined (CRLF_SOURCE_FILES) */
+static void
+gdbtk_print_frame_info (s, line, stopline, noerror)
+ struct symtab *s;
+ int line;
+ int stopline;
+ int noerror;
+{
+ current_source_symtab = s;
+ current_source_line = line;
+}
+
+
+/* The lookup_symtab() in symtab.c doesn't work correctly */
+/* It will not work will full pathnames and if multiple */
+/* source files have the same basename, it will return */
+/* the first one instead of the correct one. This version */
+/* also always makes sure symtab->fullname is set. */
+
+static struct symtab *
+full_lookup_symtab(file)
+ char *file;
+{
+ struct symtab *st;
+ struct objfile *objfile;
+ char *bfile, *fullname;
+ struct partial_symtab *pt;
+
+ if (!file)
+ return NULL;
+
+ /* first try a direct lookup */
+ st = lookup_symtab (file);
+ if (st)
+ {
+ if (!st->fullname)
+ symtab_to_filename(st);
+ return st;
+ }
+
+ /* if the direct approach failed, try */
+ /* looking up the basename and checking */
+ /* all matches with the fullname */
+ bfile = basename (file);
+ ALL_SYMTABS (objfile, st)
+ {
+ if (!strcmp (bfile, basename(st->filename)))
+ {
+ if (!st->fullname)
+ fullname = symtab_to_filename (st);
+ else
+ fullname = st->fullname;
+
+ if (!strcmp (file, fullname))
+ return st;
+ }
+ }
+
+ /* still no luck? look at psymtabs */
+ ALL_PSYMTABS (objfile, pt)
+ {
+ if (!strcmp (bfile, basename(pt->filename)))
+ {
+ st = PSYMTAB_TO_SYMTAB (pt);
+ if (st)
+ {
+ fullname = symtab_to_filename (st);
+ if (!strcmp (file, fullname))
+ return st;
+ }
+ }
+ }
+ return NULL;
+}
+
+
+/* gdb_loadfile loads a c source file into a text widget. */
+
+/* LTABLE_SIZE is the number of bytes to allocate for the */
+/* line table. Its size limits the maximum number of lines */
+/* in a file to 8 * LTABLE_SIZE. This memory is freed after */
+/* the file is loaded, so it is OK to make this very large. */
+/* Additional memory will be allocated if needed. */
+#define LTABLE_SIZE 20000
-/* Find the pathname to a file, searching the source_dir */
-/* we may actually need to use openp to find the the full pathname
- so we don't have any "../" et al in it. */
static int
-gdb_find_file_command (clientData, interp, objc, objv)
+gdb_loadfile (clientData, interp, objc, objv)
ClientData clientData;
Tcl_Interp *interp;
int objc;
Tcl_Obj *CONST objv[];
{
- char *file, *filename;
+ char *file, *widget, *line, *buf, msg[128];
+ int linenumbers, ln, anum, lnum, ltable_size;
+ Tcl_Obj *a[2], *b[2], *cmd;
+ FILE *fp;
+ char *ltable;
+ struct symtab *symtab;
+ struct linetable_entry *le;
+
+ if (objc != 4)
+ {
+ Tcl_WrongNumArgs(interp, 1, objv, "widget filename linenumbers");
+ return TCL_ERROR;
+ }
- if (objc != 2)
+ widget = Tcl_GetStringFromObj (objv[1], NULL);
+ file = Tcl_GetStringFromObj (objv[2], NULL);
+ Tcl_GetBooleanFromObj (interp, objv[3], &linenumbers);
+
+ if ((fp = fopen ( file, "r" )) == NULL)
+ return TCL_ERROR;
+
+ symtab = full_lookup_symtab (file);
+ if (!symtab)
{
- Tcl_AppendResult (interp, "wrong # of args: should be \"",
- Tcl_GetStringFromObj (objv[0], NULL),
- " filename\"");
+ fclose (fp);
return TCL_ERROR;
}
- file = Tcl_GetStringFromObj (objv[1], NULL);
- filename = find_file_in_dir (file);
-
- if (filename == NULL)
- Tcl_SetResult (interp, "", TCL_STATIC);
- else
- Tcl_SetObjResult (interp, Tcl_NewStringObj (filename, -1));
+ /* Source linenumbers don't appear to be in order, and a sort is */
+ /* too slow so the fastest solution is just to allocate a huge */
+ /* array and set the array entry for each linenumber */
+
+ ltable_size = LTABLE_SIZE;
+ ltable = (char *)malloc (LTABLE_SIZE);
+ if (ltable == NULL)
+ {
+ sprintf(msg, "Out of memory.");
+ Tcl_SetStringObj ( Tcl_GetObjResult (interp), msg, -1);
+ fclose (fp);
+ return TCL_ERROR;
+ }
+
+ memset (ltable, 0, LTABLE_SIZE);
+
+ if (symtab->linetable && symtab->linetable->nitems)
+ {
+ le = symtab->linetable->item;
+ for (ln = symtab->linetable->nitems ;ln > 0; ln--, le++)
+ {
+ lnum = le->line >> 3;
+ if (lnum >= ltable_size)
+ {
+ char *new_ltable;
+ new_ltable = (char *)realloc (ltable, ltable_size*2);
+ memset (new_ltable + ltable_size, 0, ltable_size);
+ ltable_size *= 2;
+ if (new_ltable == NULL)
+ {
+ sprintf(msg, "Out of memory.");
+ Tcl_SetStringObj ( Tcl_GetObjResult (interp), msg, -1);
+ free (ltable);
+ fclose (fp);
+ return TCL_ERROR;
+ }
+ ltable = new_ltable;
+ }
+ ltable[lnum] |= 1 << (le->line % 8);
+ }
+ }
+ /* create an object with enough space, then grab its */
+ /* buffer and sprintf directly into it. */
+ a[0] = Tcl_NewStringObj (ltable, 1024);
+ a[1] = Tcl_NewListObj(0,NULL);
+ buf = a[0]->bytes;
+ b[0] = Tcl_NewStringObj (ltable,1024);
+ b[1] = Tcl_NewStringObj ("source_tag", -1);
+ Tcl_IncrRefCount (b[0]);
+ Tcl_IncrRefCount (b[1]);
+ line = b[0]->bytes + 1;
+ strcpy(b[0]->bytes,"\t");
+
+ ln = 1;
+ while (fgets (line, 980, fp))
+ {
+ if (linenumbers)
+ {
+ if (ltable[ln >> 3] & (1 << (ln % 8)))
+ a[0]->length = sprintf (buf,"%s insert end {-\t%d} break_tag", widget, ln);
+ else
+ a[0]->length = sprintf (buf,"%s insert end {\t%d} \"\"", widget, ln);
+ }
+ else
+ {
+ if (ltable[ln >> 3] & (1 << (ln % 8)))
+ a[0]->length = sprintf (buf,"%s insert end {-\t} break_tag", widget);
+ else
+ a[0]->length = sprintf (buf,"%s insert end {\t} \"\"", widget);
+ }
+ b[0]->length = strlen(b[0]->bytes);
+ Tcl_SetListObj(a[1],2,b);
+ cmd = Tcl_ConcatObj(2,a);
+ Tcl_EvalObj (interp, cmd);
+ Tcl_DecrRefCount (cmd);
+ ln++;
+ }
+ Tcl_DecrRefCount (b[0]);
+ Tcl_DecrRefCount (b[0]);
+ Tcl_DecrRefCount (b[1]);
+ Tcl_DecrRefCount (b[1]);
+ free (ltable);
+ fclose (fp);
return TCL_OK;
}
-static char *
-find_file_in_dir (file)
- char *file;
+/* at some point make these static in breakpoint.c and move GUI code there */
+extern struct breakpoint *set_raw_breakpoint (struct symtab_and_line sal);
+extern void set_breakpoint_count (int);
+extern int breakpoint_count;
+
+/* set a breakpoint by source file and line number */
+/* flags are as follows: */
+/* least significant 2 bits are disposition, rest is */
+/* type (normally 0).
+
+enum bptype {
+ bp_breakpoint, Normal breakpoint
+ bp_hardware_breakpoint, Hardware assisted breakpoint
+}
+
+Disposition of breakpoint. Ie: what to do after hitting it.
+enum bpdisp {
+ del, Delete it
+ del_at_next_stop, Delete at next stop, whether hit or not
+ disable, Disable it
+ donttouch Leave it alone
+ };
+*/
+
+static int
+gdb_set_bp (clientData, interp, objc, objv)
+ ClientData clientData;
+ Tcl_Interp *interp;
+ int objc;
+ Tcl_Obj *CONST objv[];
+
{
- struct symtab *st = NULL;
+ struct symtab_and_line sal;
+ int line, flags, ret;
+ struct breakpoint *b;
+ char buf[64];
+ Tcl_Obj *a[5], *cmd;
- if (file != NULL)
+ if (objc != 4)
{
- /* try something simple first */
- if (access (file, R_OK) == 0)
- return file;
-
- /* We really need a symtab for this to work... */
- st = lookup_symtab (file);
- if (st != NULL)
- {
- file = symtab_to_filename (st);
- if (file != NULL)
- return file;
- }
+ Tcl_WrongNumArgs(interp, 1, objv, "filename line type");
+ return TCL_ERROR;
}
- return NULL;
+ sal.symtab = full_lookup_symtab (Tcl_GetStringFromObj( objv[1], NULL));
+ if (sal.symtab == NULL)
+ return TCL_ERROR;
+
+ if (Tcl_GetIntFromObj( interp, objv[2], &line) == TCL_ERROR)
+ return TCL_ERROR;
+
+ if (Tcl_GetIntFromObj( interp, objv[3], &flags) == TCL_ERROR)
+ return TCL_ERROR;
+
+ sal.line = line;
+ sal.pc = find_line_pc (sal.symtab, sal.line);
+ if (sal.pc == 0)
+ return TCL_ERROR;
+
+ sal.section = find_pc_overlay (sal.pc);
+ b = set_raw_breakpoint (sal);
+ set_breakpoint_count (breakpoint_count + 1);
+ b->number = breakpoint_count;
+ b->type = flags >> 2;
+ b->disposition = flags & 3;
+
+ /* FIXME: this won't work for duplicate basenames! */
+ sprintf (buf, "%s:%d", basename(Tcl_GetStringFromObj( objv[1], NULL)), line);
+ b->addr_string = strsave (buf);
+
+ /* now send notification command back to GUI */
+ sprintf (buf, "0x%x", sal.pc);
+ a[0] = Tcl_NewStringObj ("gdbtk_tcl_breakpoint create", -1);
+ a[1] = Tcl_NewIntObj (b->number);
+ a[2] = Tcl_NewStringObj (buf, -1);
+ a[3] = objv[2];
+ a[4] = Tcl_NewListObj (1,&objv[1]);
+ cmd = Tcl_ConcatObj(5,a);
+ ret = Tcl_EvalObj (interp, cmd);
+ Tcl_DecrRefCount (cmd);
+ return ret;
}
-/* This hook is called whenever we are ready to load a symbol file so that
- the UI can notify the user... */
-void
-gdbtk_pre_add_symbol (name)
- char *name;
+#ifdef __CYGWIN32__
+/* The whole timer idea is an easy one, but POSIX does not appear to have
+ some sort of interval timer requirement. Consequently, we cannot rely
+ on cygwin32 to always deliver the timer's signal. This is especially
+ painful given that all serial I/O will block the timer right now. */
+static void
+gdbtk_annotate_starting ()
{
- char command[256];
-
- sprintf (command, "gdbtk_tcl_pre_add_symbol %s", name);
- Tcl_Eval (interp, command);
+ /* TclDebug ("### STARTING ###"); */
+ gdbtk_start_timer ();
}
-/* This hook is called whenever we finish loading a symbol file. */
-void
-gdbtk_post_add_symbol ()
+static void
+gdbtk_annotate_stopped ()
{
- Tcl_Eval (interp, "gdbtk_tcl_post_add_symbol");
+ /* TclDebug ("### STOPPED ###"); */
+ gdbtk_stop_timer ();
}
-
-/* TclDebug (const char *fmt, ...) works just like printf() but */
-/* sends the output to the GDB TK debug window. */
-/* Not for normal use; just a convenient tool for debugging */
-void
-#ifdef ANSI_PROTOTYPES
-TclDebug (const char *fmt, ...)
-#else
-TclDebug (va_alist)
- va_dcl
-#endif
+static void
+gdbtk_annotate_exited ()
{
- va_list args;
- char buf[512];
-
-#ifdef ANSI_PROTOTYPES
- va_start (args, fmt);
-#else
- char *fmt;
- va_start (args);
- fmt = va_arg (args, char *);
-#endif
-
- strcpy (buf, "debug \"");
- vsprintf (&buf[7], fmt, args);
- va_end (args);
- strcat (buf, "\"");
- Tcl_Eval (interp, buf);
+ /* TclDebug ("### EXITED ###"); */
+ gdbtk_stop_timer ();
}
static void
-gdbtk_print_frame_info (s, line, stopline, noerror)
- struct symtab *s;
- int line;
- int stopline;
- int noerror;
+gdbtk_annotate_signalled ()
{
- current_source_symtab = s;
- current_source_line = line;
+ /* TclDebug ("### SIGNALLED ###"); */
+ gdbtk_stop_timer ();
}
+#endif
/* Come here during initialize_all_files () */
diff --git a/gdb/gdbtool.ico b/gdb/gdbtool.ico
new file mode 100644
index 0000000..7e7f68a
--- /dev/null
+++ b/gdb/gdbtool.ico
Binary files differ
diff --git a/gdb/top.c b/gdb/top.c
index fd5f316..544f09e 100644
--- a/gdb/top.c
+++ b/gdb/top.c
@@ -439,6 +439,9 @@ void (*interactive_hook) PARAMS ((void));
void (*registers_changed_hook) PARAMS ((void));
+/* tell the GUI someone changed the PC */
+void (*pc_changed_hook) PARAMS ((void));
+
/* Called when going to wait for the target. Usually allows the GUI to run
while waiting for target events. */
@@ -2877,7 +2880,12 @@ quit_confirm ()
{
char *s;
- if (attach_flag)
+ /* This is something of a hack. But there's no reliable way to
+ see if a GUI is running. The `use_windows' variable doesn't
+ cut it. */
+ if (init_ui_hook)
+ s = "A debugging session is active.\nDo you still want to close the debugger?";
+ else if (attach_flag)
s = "The program is running. Quit anyway (and detach it)? ";
else
s = "The program is running. Exit anyway? ";