diff options
author | Stan Shebs <shebs@codesourcery.com> | 1999-05-11 13:35:55 +0000 |
---|---|---|
committer | Stan Shebs <shebs@codesourcery.com> | 1999-05-11 13:35:55 +0000 |
commit | cd0fc7c3ebe90ce6390e06cef0ae9a54fe9c9891 (patch) | |
tree | 422678986a58e51b2a7fe3d64c38b97d4996abe1 /gdb | |
parent | e9868447b4b62dd04b5350113b136856ddbaa232 (diff) | |
download | gdb-cd0fc7c3ebe90ce6390e06cef0ae9a54fe9c9891.zip gdb-cd0fc7c3ebe90ce6390e06cef0ae9a54fe9c9891.tar.gz gdb-cd0fc7c3ebe90ce6390e06cef0ae9a54fe9c9891.tar.bz2 |
import gdb-1999-05-10
Diffstat (limited to 'gdb')
-rw-r--r-- | gdb/ChangeLog | 129 | ||||
-rw-r--r-- | gdb/Makefile.in | 19 | ||||
-rw-r--r-- | gdb/coffread.c | 17 | ||||
-rw-r--r-- | gdb/config.in | 3 | ||||
-rwxr-xr-x | gdb/configure | 37 | ||||
-rw-r--r-- | gdb/configure.in | 9 | ||||
-rw-r--r-- | gdb/defs.h | 3 | ||||
-rw-r--r-- | gdb/infrun.c | 657 | ||||
-rw-r--r-- | gdb/main.c | 32 | ||||
-rw-r--r-- | gdb/mips-tdep.c | 32 | ||||
-rw-r--r-- | gdb/target.c | 7 | ||||
-rw-r--r-- | gdb/target.h | 13 | ||||
-rw-r--r-- | gdb/testsuite/ChangeLog | 16 | ||||
-rw-r--r-- | gdb/testsuite/gdb.base/Makefile.in | 6 | ||||
-rw-r--r-- | gdb/testsuite/gdb.base/annota2.cc | 2 | ||||
-rw-r--r-- | gdb/top.c | 172 | ||||
-rw-r--r-- | gdb/top.h | 16 |
17 files changed, 806 insertions, 364 deletions
diff --git a/gdb/ChangeLog b/gdb/ChangeLog index 5aa6fbd..579d4bd 100644 --- a/gdb/ChangeLog +++ b/gdb/ChangeLog @@ -1,3 +1,132 @@ +1999-05-10 Martin Hunt <hunt@cygnus.com> + + * debugify.c, debugify.h: Removed because they are no + longer used. + +1999-05-08 Jim Blandy <jimb@zwingli.cygnus.com> + + * infrun.c (_initialize_infrun): Handle TARGET_SIGNAL_LWP, + TARGET_SIGNAL_WAITING, and TARGET_SIGNAL_CANCEL like SIGALRM or + SIGIO --- pass them through to the inferior silently. + * target.h (enum target_signals): Add TARGET_SIGNAL_CANCEL, for + Solaris's SIGCANCEL. + * target.c (target_signal_from_host, target_signal_to_host): Add + mapping between SIGCANCEL and TARGET_SIGNAL_CANCEL. + (signals): Add entry for SIGCANCEL. + +1999-05-07 Stan Shebs <shebs@andros.cygnus.com> + + After years of talking about it, finally break up the + wait_for_inferior loop. + * infrun.c (struct execution_control_state): New struct, + holds what used to be local vars governing wfi behavior. + (init_execution_control_state): New function, was code in + wfi that set up execution control state. + (handle_inferior_event): New function, was body of main + wfi loop. Rewrite all local var references to go through + the ecs structure passed into this function. + (wait_for_inferior): Rewrite to set up and use execution control + state, and to call the new functions. + (currently_stepping): New function, was the macro + CURRENTLY_STEPPING. + (enum infwait_states): Rename from wfi_states. + (infwait_normal_state, etc): Similarly. + +Thu May 6 15:25:32 1999 Philippe De Muyter <phdm@macqel.be> + + * coffread.c (coff_symtab_read): Call `record_line' with the line + number of the ".bf" symbol only for one-line functions. + +1999-05-06 Michael Snyder <msnyder@cleaver.cygnus.com> + + * Makefile.in: thread.o depends on target.h. + +1999-05-06 Elena Zannoni <ezannoni@kwikemart.cygnus.com> + + * event-top.c (change_line_handler): Use POLLIN instead of + POLLRDNORM, for compatibility with Linux. + (setup_event_loop): Ditto. + +1999-05-06 Jim Blandy <jimb@zwingli.cygnus.com> + + * mips-tdep.c (heuristic_proc_start): Rewrite cryptic error + message about hitting the "heuristic fence post" with something + that actually gives the user a fighting chance of figuring out + why GDB is unhappy. + +1999-05-06 Elena Zannoni <ezannoni@kwikemart.cygnus.com> + + * top.c: Include event-loop.h. + (init_main): Add async version of 'set prompt' command. + If in async mode define the editing and annotate set + commands in a different way. + Initialize new variable asyn_command_editing_p to 1. + Initialize the gdb prompt for async mode. + (quit_cover): Make not static, for use by the event loop. + (gdb_init): Call async_init_signals for the asynchronous case. + (source_line_number, source_file_name, source_error, + source_pre_error, history_expansion_p): Make non-static, so + event-top.c can use them. + (command_loop_marker): Make non-static, for use in event-top.c. + Include event-loop.h. + + * top.h: Add prototype for async_init_signals. + (SET_TOP_LEVEL): Move here from main.c. + Add setup_event_loop to exported functions. + + * defs.h: Add async_hook to exported variables. + + * main.c (SET_TOP_LEVEL): Move to top.h, so that it is visible in + event-loop.c. Add new global variable async to determine whether + we are running in async mode or not. + (main): Add support for --async switch. Use async_hook to call + setup_event_loop, when running in async mode. + + * event-top.c: New file. Gdb input line handler and command line + handler for the event loop. Initialization of signal handlers. + All the handled signals have handlers called handle_<signalname>. + Set up all the appropriate tokens for asynchronous signal + handling. + + * event-loop.h: New file. Data structures and definitions for the + event loop. + + * event-loop.c: New file. Functions for the event loop + implementation. + + * config.in: Regenerate with autoheader. + + * configure.in (AC_CHECK_FUNCS): Add poll to list of functions + to be checked for. + + * configure: Regenerate. + + * Makefile.in (SFILES): Add new source files. + (eventloop_h): Define. + (COMMON_OBS): Add new object files. + (event-loop.o): Add rule for target object. + (event-top.o): Ditto. + +1999-05-05 Stan Shebs <shebs@andros.cygnus.com> + + * infrun.c (wait_for_inferior): Transform breaks and continues + into gotos, move the target_wait to the very top of the loop. + +1999-05-05 Jonathan Larmour <jlarmour@cygnus.co.uk> + + * configure.in: Ensure that GDB links with libuser32.a under + cygwin because libreadline requires it. + * Makefile.in (WIN32LIBS): Substitute in result from configure + * configure: regenerate + +1999-05-04 Jim Blandy <jimb@zwingli.cygnus.com> + + Fix from John Rigby. Richard Henderson says it seems okay. + * alpha-tdep.c (PROC_DUMMY_FRAME): As long as we're abusing fields + of (proc)->pdr, we ought to at least abuse one large enough to + hold the value we're trying to store in it. iopt is only 32 bits + wide; cbLineOffset is a bfd_vma. + 1999-05-04 DJ Delorie <dj@cygnus.com> DJGPP changes from Robert Hoehne <robert.hoehne@gmx.net> diff --git a/gdb/Makefile.in b/gdb/Makefile.in index 308bbb8..33d2760 100644 --- a/gdb/Makefile.in +++ b/gdb/Makefile.in @@ -148,6 +148,8 @@ OPCODES_CFLAGS = -I$(OP_INCLUDE) # should set this to list all the .o or .a files to be linked in. SIM = +WIN32LIBS = @WIN32LIBS@ + ENABLE_CFLAGS= @ENABLE_CFLAGS@ @@ -217,7 +219,7 @@ CDEPS = $(XM_CDEPS) $(TM_CDEPS) $(NAT_CDEPS) $(SIM) $(BFD) $(READLINE) \ ADD_FILES = $(REGEX) $(XM_ADD_FILES) $(TM_ADD_FILES) $(NAT_ADD_FILES) ADD_DEPS = $(REGEX1) $(XM_ADD_FILES) $(TM_ADD_FILES) $(NAT_ADD_FILES) -VERSION = 19990504 +VERSION = 19990510 DIST=gdb LINT=/usr/5bin/lint @@ -368,6 +370,7 @@ SFILES = ax-general.c ax-gdb.c bcache.c blockframe.c breakpoint.c \ ch-exp.c ch-lang.c ch-typeprint.c ch-valprint.c coffread.c \ command.c complaints.c corefile.c cp-valprint.c dbxread.c \ demangle.c dwarfread.c dwarf2read.c elfread.c environ.c eval.c \ + event-loop.c event-top.c \ expprint.c f-exp.y f-lang.c f-typeprint.c f-valprint.c \ findvar.c gdbarch.c gdbtypes.c infcmd.c inflow.c infrun.c language.c \ jv-exp.y jv-lang.c jv-valprint.c jv-typeprint.c \ @@ -436,6 +439,7 @@ defs_h = defs.h xm.h tm.h nm.h config.status config.h gdbarch.h inferior_h = inferior.h $(breakpoint_h) tracepoint_h = tracepoint.h ax_h = ax.h +event_loop_h = event-loop.h # Header files that need to have srcdir added. Note that in the cases # where we use a macro like $(gdbcmd_h), things are carefully arranged @@ -491,7 +495,9 @@ TAGFILES_WITH_SRCDIR = $(HFILES_WITH_SRCDIR) COMMON_OBS = version.o blockframe.o breakpoint.o findvar.o stack.o thread.o \ source.o values.o eval.o valops.o valarith.o valprint.o printcmd.o \ symtab.o symfile.o symmisc.o infcmd.o infrun.o command.o \ - expprint.o environ.o gdbarch.o gdbtypes.o copying.o $(DEPFILES) \ + expprint.o environ.o \ + event-loop.o event-top.o \ + gdbarch.o gdbtypes.o copying.o $(DEPFILES) \ mem-break.o target.o parse.o language.o $(YYOBJ) buildsym.o \ exec.o bcache.o objfiles.o minsyms.o maint.o demangle.o \ dbxread.o coffread.o elfread.o \ @@ -1101,6 +1107,11 @@ eval.o: eval.c $(bfd_h) $(defs_h) $(expression_h) $(frame_h) \ $(gdbtypes_h) language.h $(symtab_h) target.h $(value_h) \ gdb_string.h +event-loop.o: event-loop.c $(event_loop_h) + +event-top.o: event-top.c top.h $(readline_headers) \ + $(defs_h) $(inferior_h) $(event_loop_h) + exec.o: exec.c $(defs_h) $(gdbcmd_h) $(gdbcore_h) $(inferior_h) \ target.h language.h gdb_string.h @@ -1545,11 +1556,11 @@ tic80-tdep.o: tic80-tdep.c $(defs_h) target.o: target.c $(bfd_h) $(defs_h) $(gdbcmd_h) $(inferior_h) \ objfiles.h symfile.h target.h gdb_string.h -thread.o: thread.c $(defs_h) gdbthread.h $(gdbcmd_h) +thread.o: thread.c $(defs_h) gdbthread.h $(gdbcmd_h) target.h top.o: top.c top.h $(bfd_h) $(getopt_h) $(readline_headers) call-cmds.h \ $(defs_h) $(gdbcmd_h) $(inferior_h) language.h signals.h \ - $(remote_utils_h) gdb_string.h + $(remote_utils_h) gdb_string.h $(event_loop_h) typeprint.o: typeprint.c $(defs_h) $(expression_h) $(gdbcmd_h) \ $(gdbcore_h) $(gdbtypes_h) language.h $(symtab_h) target.h \ diff --git a/gdb/coffread.c b/gdb/coffread.c index 56c1438..ae1deca 100644 --- a/gdb/coffread.c +++ b/gdb/coffread.c @@ -764,6 +764,7 @@ coff_symtab_read (symtab_offset, nsyms, section_offsets, objfile) char *filestring = ""; int depth = 0; int fcn_first_line = 0; + CORE_ADDR fcn_first_line_addr; int fcn_last_line = 0; int fcn_start_addr = 0; long fcn_line_ptr = 0; @@ -1020,6 +1021,7 @@ coff_symtab_read (symtab_offset, nsyms, section_offsets, objfile) if (cs->c_naux != 1) complain (&bf_no_aux_complaint, cs->c_symnum); fcn_first_line = main_aux.x_sym.x_misc.x_lnsz.x_lnno; + fcn_first_line_addr = cs->c_value; /* Might want to check that locals are 0 and context_stack_depth is zero, and complain if not. */ @@ -1030,7 +1032,6 @@ coff_symtab_read (symtab_offset, nsyms, section_offsets, objfile) new->name = process_coff_symbol (&fcn_cs_saved, &fcn_aux_saved, section_offsets, objfile); - record_line (current_subfile, fcn_first_line, cs->c_value); } else if (STREQ (cs->c_name, ".ef")) { @@ -1063,8 +1064,18 @@ coff_symtab_read (symtab_offset, nsyms, section_offsets, objfile) { fcn_last_line = main_aux.x_sym.x_misc.x_lnsz.x_lnno; } - enter_linenos (fcn_line_ptr, fcn_first_line, fcn_last_line, - section_offsets); + /* fcn_first_line is the line number of the opening '{'. + Do not record it - because it would affect gdb's idea + of the line number of the first statement of the function - + except for one-line functions, for which it is also the line + number of all the statements and of the closing '}', and + for which we do not have any other statement-line-number. */ + if (fcn_last_line == 1) + record_line (current_subfile, fcn_first_line, + fcn_first_line_addr); + else + enter_linenos (fcn_line_ptr, fcn_first_line, fcn_last_line, + section_offsets); finish_block (new->name, &local_symbols, new->old_blocks, new->start_addr, diff --git a/gdb/config.in b/gdb/config.in index 6bef6b40..1093eaf 100644 --- a/gdb/config.in +++ b/gdb/config.in @@ -135,6 +135,9 @@ /* Define if you have the bzero function. */ #undef HAVE_BZERO +/* Define if you have the poll function. */ +#undef HAVE_POLL + /* Define if you have the dcgettext function. */ #undef HAVE_DCGETTEXT diff --git a/gdb/configure b/gdb/configure index a3ad095..8e6b14d 100755 --- a/gdb/configure +++ b/gdb/configure @@ -3371,7 +3371,7 @@ EOF fi -for ac_func in setpgid sbrk sigaction isascii bzero bcopy btowc +for ac_func in setpgid sbrk sigaction isascii bzero bcopy btowc poll do echo $ac_n "checking for $ac_func""... $ac_c" 1>&6 echo "configure:3378: checking for $ac_func" >&5 @@ -5372,6 +5372,11 @@ fi fi +# libreadline needs libuser32.a in a cygwin environment +WIN32LIBS= +if test x$gdb_cv_os_cygwin = xyes; then + WIN32LIBS="-luser32" +fi @@ -5380,7 +5385,7 @@ fi # Uses ac_ vars as temps to allow command line to override cache and checks. # --without-x overrides everything else, but does not touch the cache. echo $ac_n "checking for X""... $ac_c" 1>&6 -echo "configure:6593: checking for X" >&5 +echo "configure:6597: checking for X" >&5 # Check whether --with-x or --without-x was given. if test "${with_x+set}" = set; then @@ -5442,12 +5447,12 @@ if test "$ac_x_includes" = NO; then # First, try using that file with no special directory specified. cat > conftest.$ac_ext <<EOF -#line 6655 "configure" +#line 6659 "configure" #include "confdefs.h" #include <$x_direct_test_include> EOF ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" -{ (eval echo configure:6660: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } +{ (eval echo configure:6664: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` if test -z "$ac_err"; then rm -rf conftest* @@ -5516,14 +5521,14 @@ if test "$ac_x_libraries" = NO; then ac_save_LIBS="$LIBS" LIBS="-l$x_direct_test_library $LIBS" cat > conftest.$ac_ext <<EOF -#line 6729 "configure" +#line 6733 "configure" #include "confdefs.h" int main() { ${x_direct_test_function}() ; return 0; } EOF -if { (eval echo configure:6736: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:6740: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* LIBS="$ac_save_LIBS" # We can link X programs with no special library path. @@ -5796,12 +5801,12 @@ fi echo $ac_n "checking for Cygwin environment""... $ac_c" 1>&6 -echo "configure:7080: checking for Cygwin environment" >&5 +echo "configure:7084: checking for Cygwin environment" >&5 if eval "test \"`echo '$''{'ac_cv_cygwin'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <<EOF -#line 7085 "configure" +#line 7089 "configure" #include "confdefs.h" int main() { @@ -5812,7 +5817,7 @@ int main() { return __CYGWIN__; ; return 0; } EOF -if { (eval echo configure:7096: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then +if { (eval echo configure:7100: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then rm -rf conftest* ac_cv_cygwin=yes else @@ -5829,19 +5834,19 @@ echo "$ac_t""$ac_cv_cygwin" 1>&6 CYGWIN= test "$ac_cv_cygwin" = yes && CYGWIN=yes echo $ac_n "checking for mingw32 environment""... $ac_c" 1>&6 -echo "configure:7113: checking for mingw32 environment" >&5 +echo "configure:7117: checking for mingw32 environment" >&5 if eval "test \"`echo '$''{'ac_cv_mingw32'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <<EOF -#line 7118 "configure" +#line 7122 "configure" #include "confdefs.h" int main() { return __MINGW32__; ; return 0; } EOF -if { (eval echo configure:7125: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then +if { (eval echo configure:7129: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then rm -rf conftest* ac_cv_mingw32=yes else @@ -5860,7 +5865,7 @@ test "$ac_cv_mingw32" = yes && MINGW32=yes echo $ac_n "checking for executable suffix""... $ac_c" 1>&6 -echo "configure:7144: checking for executable suffix" >&5 +echo "configure:7148: checking for executable suffix" >&5 if eval "test \"`echo '$''{'ac_cv_exeext'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -5870,10 +5875,10 @@ else rm -f conftest* echo 'int main () { return 0; }' > conftest.$ac_ext ac_cv_exeext= - if { (eval echo configure:7154: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; }; then + if { (eval echo configure:7158: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; }; then for file in conftest.*; do case $file in - *.c | *.o | *.obj | *.ilk | *.pdb) ;; + *.c | *.o | *.obj) ;; *) ac_cv_exeext=`echo $file | sed -e s/conftest//` ;; esac done @@ -6082,6 +6087,7 @@ s%@MACHINE_OBS@%$MACHINE_OBS%g s%@DLLTOOL@%$DLLTOOL%g s%@WINDRES@%$WINDRES%g s%@TERM_LIB@%$TERM_LIB%g +s%@WIN32LIBS@%$WIN32LIBS%g s%@ENABLE_IDE@%$ENABLE_IDE%g s%@FOUNDRY_LIB_BASE@%$FOUNDRY_LIB_BASE%g s%@LIBGUI@%$LIBGUI%g @@ -6091,7 +6097,6 @@ s%@IDE_X@%$IDE_X%g s%@LIBIDETCL@%$LIBIDETCL%g s%@LIBIDE@%$LIBIDE%g s%@IDE_DEPS@%$IDE_DEPS%g -s%@WIN32LIBS@%$WIN32LIBS%g s%@WIN32LDAPP@%$WIN32LDAPP%g s%@TCL_VERSION@%$TCL_VERSION%g s%@TCL_MAJOR_VERSION@%$TCL_MAJOR_VERSION%g diff --git a/gdb/configure.in b/gdb/configure.in index 216f6d6..82cd0d0 100644 --- a/gdb/configure.in +++ b/gdb/configure.in @@ -75,7 +75,7 @@ AC_HEADER_STAT AC_C_CONST -AC_CHECK_FUNCS(setpgid sbrk sigaction isascii bzero bcopy btowc) +AC_CHECK_FUNCS(setpgid sbrk sigaction isascii bzero bcopy btowc poll) AC_FUNC_ALLOCA BFD_NEED_DECLARATION(malloc) @@ -447,7 +447,12 @@ fi fi AC_SUBST(TERM_LIB) - +# libreadline needs libuser32.a in a cygwin environment +WIN32LIBS= +if test x$gdb_cv_os_cygwin = xyes; then + WIN32LIBS="-luser32" +fi +AC_SUBST(WIN32LIBS) AC_PATH_X @@ -1012,7 +1012,7 @@ extern void store_floating PARAMS ((void *, int, DOUBLEST)); I'm not sure it's used in all contexts. It exists to deal with there being a few stray bits in the PC which would mislead us, not as some sort of generic thing to handle alignment or segmentation (it's possible it - should be in TARGET_READ_PC instead). */ + should be in TARGET_READ_PC instead). */ #if !defined (ADDR_BITS_REMOVE) #define ADDR_BITS_REMOVE(addr) (addr) #endif /* No ADDR_BITS_REMOVE. */ @@ -1032,6 +1032,7 @@ struct target_waitstatus; struct cmd_list_element; #endif +extern void (*async_hook) PARAMS ((void)); extern void (*init_ui_hook) PARAMS ((char *argv0)); extern void (*command_loop_hook) PARAMS ((void)); extern void (*fputs_unfiltered_hook) PARAMS ((const char *linebuffer, diff --git a/gdb/infrun.c b/gdb/infrun.c index d1a2d9b..7851ef8 100644 --- a/gdb/infrun.c +++ b/gdb/infrun.c @@ -1050,103 +1050,148 @@ delete_breakpoint_current_contents (arg) } } -/* Wait for control to return from inferior to debugger. - If inferior gets a signal, we may decide to start it up again - instead of returning. That is why there is a loop in this function. - When this function actually returns it means the inferior - should be left stopped and GDB should read more commands. */ - /* This enum encodes possible reasons for doing a target_wait, so that wfi can call target_wait in one place. (Ultimately the call will be moved out of the infinite loop entirely.) */ -enum wfi_states { - wfi_normal_state, - wfi_thread_hop_state, - wfi_nullified_state, - wfi_nonstep_watch_state +enum infwait_states { + infwait_normal_state, + infwait_thread_hop_state, + infwait_nullified_state, + infwait_nonstep_watch_state }; -void -wait_for_inferior () -{ - struct cleanup *old_cleanups; - struct target_waitstatus w; +/* This structure contains what used to be local variables in + wait_for_inferior. Probably many of them can return to being + locals in handle_inferior_event. */ + +struct execution_control_state { + struct target_waitstatus ws; + struct target_waitstatus *wp; int another_trap; - int random_signal = 0; + int random_signal; CORE_ADDR stop_func_start; CORE_ADDR stop_func_end; char *stop_func_name; - CORE_ADDR tmp; struct symtab_and_line sal; - int remove_breakpoints_on_following_step = 0; + int remove_breakpoints_on_following_step; int current_line; struct symtab *current_symtab; - int handling_longjmp = 0; /* FIXME */ + int handling_longjmp; /* FIXME */ int pid; int saved_inferior_pid; - int update_step_sp = 0; - int stepping_through_solib_after_catch = 0; - bpstat stepping_through_solib_catchpoints = NULL; - int enable_hw_watchpoints_after_wait = 0; - int stepping_through_sigtramp = 0; + int update_step_sp; + int stepping_through_solib_after_catch; + bpstat stepping_through_solib_catchpoints; + int enable_hw_watchpoints_after_wait; + int stepping_through_sigtramp; int new_thread_event; - int stepped_after_stopped_by_watchpoint; struct target_waitstatus tmpstatus; - enum wfi_states wfi_state; + enum infwait_states infwait_state; int waiton_pid; - struct target_waitstatus *wp; + int wait_some_more; +}; + +void init_execution_control_state PARAMS ((struct execution_control_state *ecs)); + +void handle_inferior_event PARAMS ((struct execution_control_state *ecs)); + +/* Wait for control to return from inferior to debugger. + If inferior gets a signal, we may decide to start it up again + instead of returning. That is why there is a loop in this function. + When this function actually returns it means the inferior + should be left stopped and GDB should read more commands. */ + +void +wait_for_inferior () +{ + struct cleanup *old_cleanups; + struct execution_control_state ecss; + struct execution_control_state *ecs; old_cleanups = make_cleanup (delete_breakpoint_current_contents, &step_resume_breakpoint); make_cleanup (delete_breakpoint_current_contents, &through_sigtramp_breakpoint); - sal = find_pc_line (prev_pc, 0); - current_line = sal.line; - current_symtab = sal.symtab; - - /* Are we stepping? */ -#define CURRENTLY_STEPPING() \ - ((through_sigtramp_breakpoint == NULL \ - && !handling_longjmp \ - && ((step_range_end && step_resume_breakpoint == NULL) \ - || trap_expected)) \ - || stepping_through_solib_after_catch \ - || bpstat_should_step ()) - ; + + /* wfi still stays in a loop, so it's OK just to take the address of + a local to get the ecs pointer. */ + ecs = &ecss; + + /* Fill in with reasonable starting values. */ + init_execution_control_state (ecs); + thread_step_needed = 0; /* We'll update this if & when we switch to a new thread. */ if (may_switch_from_inferior_pid) switched_from_inferior_pid = inferior_pid; - wfi_state = wfi_normal_state; + overlay_cache_invalid = 1; + + /* We have to invalidate the registers BEFORE calling target_wait + because they can be loaded from the target while in target_wait. + This makes remote debugging a bit more efficient for those + targets that provide critical registers as part of their normal + status mechanism. */ + + registers_changed (); while (1) { - if (wfi_state == wfi_normal_state) - { - overlay_cache_invalid = 1; + if (target_wait_hook) + ecs->pid = target_wait_hook (ecs->waiton_pid, ecs->wp); + else + ecs->pid = target_wait (ecs->waiton_pid, ecs->wp); - /* We have to invalidate the registers BEFORE calling - target_wait because they can be loaded from the target - while in target_wait. This makes remote debugging a bit - more efficient for those targets that provide critical - registers as part of their normal status mechanism. */ + /* Now figure out what to do with the result of the result. */ + handle_inferior_event (ecs); - registers_changed (); - waiton_pid = -1; - wp = &w; - } + if (!ecs->wait_some_more) + break; + } + do_cleanups (old_cleanups); +} - if (target_wait_hook) - pid = target_wait_hook (waiton_pid, wp); - else - pid = target_wait (waiton_pid, wp); +/* Prepare an execution control state for looping through a + wait_for_inferior-type loop. */ + +void +init_execution_control_state (ecs) + struct execution_control_state *ecs; +{ + ecs->random_signal = 0; + ecs->remove_breakpoints_on_following_step = 0; + ecs->handling_longjmp = 0; /* FIXME */ + ecs->update_step_sp = 0; + ecs->stepping_through_solib_after_catch = 0; + ecs->stepping_through_solib_catchpoints = NULL; + ecs->enable_hw_watchpoints_after_wait = 0; + ecs->stepping_through_sigtramp = 0; + ecs->sal = find_pc_line (prev_pc, 0); + ecs->current_line = ecs->sal.line; + ecs->current_symtab = ecs->sal.symtab; + ecs->infwait_state = infwait_normal_state; + ecs->waiton_pid = -1; + ecs->wp = &(ecs->ws); +} + +/* Given an execution control state that has been freshly filled in + by an event from the inferior, figure out what it means and take + appropriate action. */ - switch (wfi_state) +void +handle_inferior_event (ecs) + struct execution_control_state *ecs; +{ + CORE_ADDR tmp; + int stepped_after_stopped_by_watchpoint; + + /* Keep this extra brace for now, minimizes diffs. */ + { + switch (ecs->infwait_state) { - case wfi_normal_state: + case infwait_normal_state: /* Since we've done a wait, we have a new event. Don't carry over any expectations about needing to step over a breakpoint. */ @@ -1154,32 +1199,32 @@ wait_for_inferior () /* See comments where a TARGET_WAITKIND_SYSCALL_RETURN event is serviced in this loop, below. */ - if (enable_hw_watchpoints_after_wait) + if (ecs->enable_hw_watchpoints_after_wait) { TARGET_ENABLE_HW_WATCHPOINTS (inferior_pid); - enable_hw_watchpoints_after_wait = 0; + ecs->enable_hw_watchpoints_after_wait = 0; } stepped_after_stopped_by_watchpoint = 0; break; - case wfi_thread_hop_state: + case infwait_thread_hop_state: insert_breakpoints (); /* We need to restart all the threads now, * unles we're running in scheduler-locked mode. - * FIXME: shouldn't we look at CURRENTLY_STEPPING ()? + * FIXME: shouldn't we look at currently_stepping ()? */ if (scheduler_mode == schedlock_on) - target_resume (pid, 0, TARGET_SIGNAL_0); + target_resume (ecs->pid, 0, TARGET_SIGNAL_0); else target_resume (-1, 0, TARGET_SIGNAL_0); - wfi_state = wfi_normal_state; - continue; + ecs->infwait_state = infwait_normal_state; + goto wfi_continue; - case wfi_nullified_state: + case infwait_nullified_state: break; - case wfi_nonstep_watch_state: + case infwait_nonstep_watch_state: insert_breakpoints (); /* FIXME-maybe: is this cleaner than setting a flag? Does it @@ -1188,21 +1233,21 @@ wait_for_inferior () stepped_after_stopped_by_watchpoint = 1; break; } - wfi_state = wfi_normal_state; + ecs->infwait_state = infwait_normal_state; flush_cached_frames (); /* If it's a new process, add it to the thread database */ - new_thread_event = ((pid != inferior_pid) && !in_thread_list (pid)); + ecs->new_thread_event = ((ecs->pid != inferior_pid) && !in_thread_list (ecs->pid)); - if (w.kind != TARGET_WAITKIND_EXITED - && w.kind != TARGET_WAITKIND_SIGNALLED - && new_thread_event) + if (ecs->ws.kind != TARGET_WAITKIND_EXITED + && ecs->ws.kind != TARGET_WAITKIND_SIGNALLED + && ecs->new_thread_event) { - add_thread (pid); + add_thread (ecs->pid); - printf_filtered ("[New %s]\n", target_pid_or_tid_to_str (pid)); + printf_filtered ("[New %s]\n", target_pid_or_tid_to_str (ecs->pid)); #if 0 /* NOTE: This block is ONLY meant to be invoked in case of a @@ -1225,11 +1270,11 @@ wait_for_inferior () make progress. */ target_resume (-1, 0, TARGET_SIGNAL_0); - continue; + goto wfi_continue; #endif } - switch (w.kind) + switch (ecs->ws.kind) { case TARGET_WAITKIND_LOADED: /* Ignore gracefully during startup of the inferior, as it @@ -1260,18 +1305,18 @@ wait_for_inferior () } #endif resume (0, TARGET_SIGNAL_0); - continue; + goto wfi_continue; case TARGET_WAITKIND_SPURIOUS: resume (0, TARGET_SIGNAL_0); - continue; + goto wfi_continue; case TARGET_WAITKIND_EXITED: target_terminal_ours (); /* Must do this before mourn anyway */ - annotate_exited (w.value.integer); - if (w.value.integer) + annotate_exited (ecs->ws.value.integer); + if (ecs->ws.value.integer) printf_filtered ("\nProgram exited with code 0%o.\n", - (unsigned int) w.value.integer); + (unsigned int) ecs->ws.value.integer); else printf_filtered ("\nProgram exited normally.\n"); @@ -1279,7 +1324,7 @@ wait_for_inferior () that the user can inspect this again later. */ set_internalvar (lookup_internalvar ("_exitcode"), value_from_longest (builtin_type_int, - (LONGEST) w.value.integer)); + (LONGEST) ecs->ws.value.integer)); gdb_flush (gdb_stdout); target_mourn_inferior (); singlestep_breakpoints_inserted_p = 0; /*SOFTWARE_SINGLE_STEP_P*/ @@ -1288,7 +1333,7 @@ wait_for_inferior () case TARGET_WAITKIND_SIGNALLED: stop_print_frame = 0; - stop_signal = w.value.sig; + stop_signal = ecs->ws.value.sig; target_terminal_ours (); /* Must do this before mourn anyway */ annotate_signalled (); @@ -1318,38 +1363,38 @@ wait_for_inferior () the above cases end in a continue or goto. */ case TARGET_WAITKIND_FORKED: stop_signal = TARGET_SIGNAL_TRAP; - pending_follow.kind = w.kind; + pending_follow.kind = ecs->ws.kind; /* Ignore fork events reported for the parent; we're only interested in reacting to forks of the child. Note that we expect the child's fork event to be available if we waited for it now. */ - if (inferior_pid == pid) + if (inferior_pid == ecs->pid) { pending_follow.fork_event.saw_parent_fork = 1; - pending_follow.fork_event.parent_pid = pid; - pending_follow.fork_event.child_pid = w.value.related_pid; - continue; + pending_follow.fork_event.parent_pid = ecs->pid; + pending_follow.fork_event.child_pid = ecs->ws.value.related_pid; + goto wfi_continue; } else { pending_follow.fork_event.saw_child_fork = 1; - pending_follow.fork_event.child_pid = pid; - pending_follow.fork_event.parent_pid = w.value.related_pid; + pending_follow.fork_event.child_pid = ecs->pid; + pending_follow.fork_event.parent_pid = ecs->ws.value.related_pid; } - stop_pc = read_pc_pid (pid); - saved_inferior_pid = inferior_pid; - inferior_pid = pid; + stop_pc = read_pc_pid (ecs->pid); + ecs->saved_inferior_pid = inferior_pid; + inferior_pid = ecs->pid; stop_bpstat = bpstat_stop_status (&stop_pc, (DECR_PC_AFTER_BREAK ? (prev_pc != stop_pc - DECR_PC_AFTER_BREAK - && CURRENTLY_STEPPING ()) + && currently_stepping (ecs)) : 0) ); - random_signal = !bpstat_explains_signal (stop_bpstat); - inferior_pid = saved_inferior_pid; + ecs->random_signal = !bpstat_explains_signal (stop_bpstat); + inferior_pid = ecs->saved_inferior_pid; goto process_event_stop_test; /* If this a platform which doesn't allow a debugger to touch a @@ -1361,7 +1406,7 @@ wait_for_inferior () little choice. */ case TARGET_WAITKIND_VFORKED: stop_signal = TARGET_SIGNAL_TRAP; - pending_follow.kind = w.kind; + pending_follow.kind = ecs->ws.kind; /* Is this a vfork of the parent? If so, then give any vfork catchpoints a chance to trigger now. (It's @@ -1369,11 +1414,11 @@ wait_for_inferior () it execs, and the child has not yet exec'd. We probably should warn the user to that effect when the catchpoint triggers...) */ - if (pid == inferior_pid) + if (ecs->pid == inferior_pid) { pending_follow.fork_event.saw_parent_fork = 1; - pending_follow.fork_event.parent_pid = pid; - pending_follow.fork_event.child_pid = w.value.related_pid; + pending_follow.fork_event.parent_pid = ecs->pid; + pending_follow.fork_event.child_pid = ecs->ws.value.related_pid; } /* If we've seen the child's vfork event but cannot really touch @@ -1382,14 +1427,14 @@ wait_for_inferior () else { pending_follow.fork_event.saw_child_fork = 1; - pending_follow.fork_event.child_pid = pid; - pending_follow.fork_event.parent_pid = w.value.related_pid; + pending_follow.fork_event.child_pid = ecs->pid; + pending_follow.fork_event.parent_pid = ecs->ws.value.related_pid; target_post_startup_inferior (pending_follow.fork_event.child_pid); follow_vfork_when_exec = !target_can_follow_vfork_prior_to_exec (); if (follow_vfork_when_exec) { - target_resume (pid, 0, TARGET_SIGNAL_0); - continue; + target_resume (ecs->pid, 0, TARGET_SIGNAL_0); + goto wfi_continue; } } @@ -1398,10 +1443,10 @@ wait_for_inferior () (&stop_pc, (DECR_PC_AFTER_BREAK ? (prev_pc != stop_pc - DECR_PC_AFTER_BREAK - && CURRENTLY_STEPPING ()) + && currently_stepping (ecs)) : 0) ); - random_signal = !bpstat_explains_signal (stop_bpstat); + ecs->random_signal = !bpstat_explains_signal (stop_bpstat); goto process_event_stop_test; case TARGET_WAITKIND_EXECD: @@ -1416,14 +1461,14 @@ wait_for_inferior () inferior_ignoring_leading_exec_events--; if (pending_follow.kind == TARGET_WAITKIND_VFORKED) ENSURE_VFORKING_PARENT_REMAINS_STOPPED (pending_follow.fork_event.parent_pid); - target_resume (pid, 0, TARGET_SIGNAL_0); - continue; + target_resume (ecs->pid, 0, TARGET_SIGNAL_0); + goto wfi_continue; } inferior_ignoring_leading_exec_events = target_reported_exec_events_per_exec_call () - 1; - pending_follow.execd_pathname = savestring (w.value.execd_pathname, - strlen (w.value.execd_pathname)); + pending_follow.execd_pathname = savestring (ecs->ws.value.execd_pathname, + strlen (ecs->ws.value.execd_pathname)); /* Did inferior_pid exec, or did a (possibly not-yet-followed) child of a vfork exec? @@ -1449,9 +1494,9 @@ wait_for_inferior () the parent vfork event is delivered. A single-step suffices. */ if (RESUME_EXECD_VFORKING_CHILD_TO_GET_PARENT_VFORK ()) - target_resume (pid, 1, TARGET_SIGNAL_0); + target_resume (ecs->pid, 1, TARGET_SIGNAL_0); /* We expect the parent vfork event to be available now. */ - continue; + goto wfi_continue; } /* This causes the eventpoints and symbol table to be reset. Must @@ -1459,18 +1504,18 @@ wait_for_inferior () follow_exec (inferior_pid, pending_follow.execd_pathname); free (pending_follow.execd_pathname); - stop_pc = read_pc_pid (pid); - saved_inferior_pid = inferior_pid; - inferior_pid = pid; + stop_pc = read_pc_pid (ecs->pid); + ecs->saved_inferior_pid = inferior_pid; + inferior_pid = ecs->pid; stop_bpstat = bpstat_stop_status (&stop_pc, (DECR_PC_AFTER_BREAK ? (prev_pc != stop_pc - DECR_PC_AFTER_BREAK - && CURRENTLY_STEPPING ()) + && currently_stepping (ecs)) : 0) ); - random_signal = !bpstat_explains_signal (stop_bpstat); - inferior_pid = saved_inferior_pid; + ecs->random_signal = !bpstat_explains_signal (stop_bpstat); + inferior_pid = ecs->saved_inferior_pid; goto process_event_stop_test; /* These syscall events are returned on HP-UX, as part of its @@ -1497,7 +1542,7 @@ wait_for_inferior () TARGET_DISABLE_HW_WATCHPOINTS (inferior_pid); } resume (0, TARGET_SIGNAL_0); - continue; + goto wfi_continue; /* Before examining the threads further, step this thread to get it entirely out of the syscall. (We get notice of the @@ -1510,22 +1555,22 @@ wait_for_inferior () the thread (this causes the next wait on the thread to hang). Nor can we enable them after stepping until we've done a wait. - Thus, we simply set the flag enable_hw_watchpoints_after_wait + Thus, we simply set the flag ecs->enable_hw_watchpoints_after_wait here, which will be serviced immediately after the target is waited on. */ case TARGET_WAITKIND_SYSCALL_RETURN: - target_resume (pid, 1, TARGET_SIGNAL_0); + target_resume (ecs->pid, 1, TARGET_SIGNAL_0); if (number_of_threads_in_syscalls > 0) { number_of_threads_in_syscalls--; - enable_hw_watchpoints_after_wait = + ecs->enable_hw_watchpoints_after_wait = (number_of_threads_in_syscalls == 0); } - continue; + goto wfi_continue; case TARGET_WAITKIND_STOPPED: - stop_signal = w.value.sig; + stop_signal = ecs->ws.value.sig; break; } @@ -1536,13 +1581,13 @@ wait_for_inferior () /* At this point, all threads are stopped (happens automatically in either the OS or the native code). Therefore we need to continue all threads in order to make progress. */ - if (new_thread_event) + if (ecs->new_thread_event) { target_resume (-1, 0, TARGET_SIGNAL_0); - continue; + goto wfi_continue; } - stop_pc = read_pc_pid (pid); + stop_pc = read_pc_pid (ecs->pid); /* See if a thread hit a thread-specific breakpoint that was meant for another thread. If so, then step that thread past the breakpoint, @@ -1551,19 +1596,19 @@ wait_for_inferior () if (stop_signal == TARGET_SIGNAL_TRAP) { if (SOFTWARE_SINGLE_STEP_P && singlestep_breakpoints_inserted_p) - random_signal = 0; + ecs->random_signal = 0; else if (breakpoints_inserted && breakpoint_here_p (stop_pc - DECR_PC_AFTER_BREAK)) { - random_signal = 0; + ecs->random_signal = 0; if (!breakpoint_thread_match (stop_pc - DECR_PC_AFTER_BREAK, - pid)) + ecs->pid)) { int remove_status; /* Saw a breakpoint, but it was hit by the wrong thread. Just continue. */ - write_pc_pid (stop_pc - DECR_PC_AFTER_BREAK, pid); + write_pc_pid (stop_pc - DECR_PC_AFTER_BREAK, ecs->pid); remove_status = remove_breakpoints (); /* Did we fail to remove breakpoints? If so, try @@ -1575,29 +1620,29 @@ wait_for_inferior () then either :-) or execs. */ if (remove_status != 0) { - write_pc_pid (stop_pc - DECR_PC_AFTER_BREAK + 4, pid); + write_pc_pid (stop_pc - DECR_PC_AFTER_BREAK + 4, ecs->pid); } else { /* Single step */ - target_resume (pid, 1, TARGET_SIGNAL_0); + target_resume (ecs->pid, 1, TARGET_SIGNAL_0); /* FIXME: What if a signal arrives instead of the single-step happening? */ - waiton_pid = pid; - wp = &w; - wfi_state = wfi_thread_hop_state; - continue; + ecs->waiton_pid = ecs->pid; + ecs->wp = &(ecs->ws); + ecs->infwait_state = infwait_thread_hop_state; + goto wfi_continue; } /* We need to restart all the threads now, * unles we're running in scheduler-locked mode. - * FIXME: shouldn't we look at CURRENTLY_STEPPING ()? + * FIXME: shouldn't we look at currently_stepping ()? */ if (scheduler_mode == schedlock_on) - target_resume (pid, 0, TARGET_SIGNAL_0); + target_resume (ecs->pid, 0, TARGET_SIGNAL_0); else target_resume (-1, 0, TARGET_SIGNAL_0); - continue; + goto wfi_continue; } else { @@ -1610,7 +1655,7 @@ wait_for_inferior () } } else - random_signal = 1; + ecs->random_signal = 1; /* See if something interesting happened to the non-current thread. If so, then switch to that thread, and eventually give control back to @@ -1619,14 +1664,14 @@ wait_for_inferior () Note that if there's any kind of pending follow (i.e., of a fork, vfork or exec), we don't want to do this now. Rather, we'll let the next resume handle it. */ - if ((pid != inferior_pid) && + if ((ecs->pid != inferior_pid) && (pending_follow.kind == TARGET_WAITKIND_SPURIOUS)) { int printed = 0; /* If it's a random signal for a non-current thread, notify user if he's expressed an interest. */ - if (random_signal + if (ecs->random_signal && signal_print[stop_signal]) { /* ??rehrauer: I don't understand the rationale for this code. If the @@ -1662,8 +1707,8 @@ wait_for_inferior () if (signal_program[stop_signal] == 0) stop_signal = TARGET_SIGNAL_0; - target_resume (pid, 0, stop_signal); - continue; + target_resume (ecs->pid, 0, stop_signal); + goto wfi_continue; } /* It's a SIGTRAP or a signal we're interested in. Switch threads, @@ -1675,16 +1720,16 @@ wait_for_inferior () trap_expected, step_resume_breakpoint, through_sigtramp_breakpoint, step_range_start, step_range_end, - step_frame_address, handling_longjmp, - another_trap, - stepping_through_solib_after_catch, - stepping_through_solib_catchpoints, - stepping_through_sigtramp); + step_frame_address, ecs->handling_longjmp, + ecs->another_trap, + ecs->stepping_through_solib_after_catch, + ecs->stepping_through_solib_catchpoints, + ecs->stepping_through_sigtramp); if (may_switch_from_inferior_pid) switched_from_inferior_pid = inferior_pid; - inferior_pid = pid; + inferior_pid = ecs->pid; /* Load infrun state for the new thread. */ load_infrun_state (inferior_pid, &prev_pc, @@ -1692,16 +1737,16 @@ wait_for_inferior () &trap_expected, &step_resume_breakpoint, &through_sigtramp_breakpoint, &step_range_start, &step_range_end, - &step_frame_address, &handling_longjmp, - &another_trap, - &stepping_through_solib_after_catch, - &stepping_through_solib_catchpoints, - &stepping_through_sigtramp); + &step_frame_address, &ecs->handling_longjmp, + &ecs->another_trap, + &ecs->stepping_through_solib_after_catch, + &ecs->stepping_through_solib_catchpoints, + &ecs->stepping_through_sigtramp); if (context_hook) - context_hook (pid_to_thread_id (pid)); + context_hook (pid_to_thread_id (ecs->pid)); - printf_filtered ("[Switching to %s]\n", target_pid_to_str (pid)); + printf_filtered ("[Switching to %s]\n", target_pid_to_str (ecs->pid)); flush_cached_frames (); } @@ -1716,35 +1761,35 @@ wait_for_inferior () it so that the user won't be confused when GDB appears to be ready to execute it. */ - /* if (INSTRUCTION_NULLIFIED && CURRENTLY_STEPPING ()) */ + /* if (INSTRUCTION_NULLIFIED && currently_stepping (ecs)) */ if (INSTRUCTION_NULLIFIED) { registers_changed (); - target_resume (pid, 1, TARGET_SIGNAL_0); + target_resume (ecs->pid, 1, TARGET_SIGNAL_0); /* We may have received a signal that we want to pass to the inferior; therefore, we must not clobber the waitstatus - in W. */ + in WS. */ - wfi_state = wfi_nullified_state; - waiton_pid = pid; - wp = &tmpstatus; - continue; + ecs->infwait_state = infwait_nullified_state; + ecs->waiton_pid = ecs->pid; + ecs->wp = &(ecs->tmpstatus); + goto wfi_continue; } /* It may not be necessary to disable the watchpoint to stop over it. For example, the PA can (with some kernel cooperation) single step over a watchpoint without disabling the watchpoint. */ - if (HAVE_STEPPABLE_WATCHPOINT && STOPPED_BY_WATCHPOINT (w)) + if (HAVE_STEPPABLE_WATCHPOINT && STOPPED_BY_WATCHPOINT (ecs->ws)) { resume (1, 0); - continue; + goto wfi_continue; } /* It is far more common to need to disable a watchpoint to step the inferior over it. FIXME. What else might a debug register or page protection watchpoint scheme need here? */ - if (HAVE_NONSTEPPABLE_WATCHPOINT && STOPPED_BY_WATCHPOINT (w)) + if (HAVE_NONSTEPPABLE_WATCHPOINT && STOPPED_BY_WATCHPOINT (ecs->ws)) { /* At this point, we are stopped at an instruction which has attempted to write to a piece of memory under control of @@ -1767,32 +1812,32 @@ wait_for_inferior () remove_breakpoints (); registers_changed (); - target_resume (pid, 1, TARGET_SIGNAL_0); /* Single step */ + target_resume (ecs->pid, 1, TARGET_SIGNAL_0); /* Single step */ - waiton_pid = pid; - wp = &w; - wfi_state = wfi_nonstep_watch_state; - continue; + ecs->waiton_pid = ecs->pid; + ecs->wp = &(ecs->ws); + ecs->infwait_state = infwait_nonstep_watch_state; + goto wfi_continue; } /* It may be possible to simply continue after a watchpoint. */ if (HAVE_CONTINUABLE_WATCHPOINT) - STOPPED_BY_WATCHPOINT (w); + STOPPED_BY_WATCHPOINT (ecs->ws); - stop_func_start = 0; - stop_func_end = 0; - stop_func_name = 0; + ecs->stop_func_start = 0; + ecs->stop_func_end = 0; + ecs->stop_func_name = 0; /* Don't care about return value; stop_func_start and stop_func_name will both be 0 if it doesn't work. */ - find_pc_partial_function (stop_pc, &stop_func_name, &stop_func_start, - &stop_func_end); - stop_func_start += FUNCTION_START_OFFSET; - another_trap = 0; + find_pc_partial_function (stop_pc, &ecs->stop_func_name, + &ecs->stop_func_start, &ecs->stop_func_end); + ecs->stop_func_start += FUNCTION_START_OFFSET; + ecs->another_trap = 0; bpstat_clear (&stop_bpstat); stop_step = 0; stop_stack_dummy = 0; stop_print_frame = 1; - random_signal = 0; + ecs->random_signal = 0; stopped_by_random_signal = 0; breakpoints_failed = 0; @@ -1800,8 +1845,8 @@ wait_for_inferior () The alternatives are: 1) break; to really stop and return to the debugger, 2) drop through to start up again - (set another_trap to 1 to single step once) - 3) set random_signal to 1, and the decision between 1 and 2 + (set ecs->another_trap to 1 to single step once) + 3) set ecs->random_signal to 1, and the decision between 1 and 2 will be made according to the signal handling tables. */ /* First, distinguish signals caused by the debugger from signals @@ -1821,10 +1866,10 @@ wait_for_inferior () if (stop_signal == TARGET_SIGNAL_TRAP && stop_after_trap) { stop_print_frame = 0; - break; + goto wfi_break; } if (stop_soon_quietly) - break; + goto wfi_break; /* Don't even think about breakpoints if just proceeded over a breakpoint. @@ -1852,7 +1897,7 @@ wait_for_inferior () without an intervening stop in sigtramp, which is detected by a new stack pointer value below any usual function calling stack adjustments. */ - (CURRENTLY_STEPPING () + (currently_stepping (ecs) && prev_pc != stop_pc - DECR_PC_AFTER_BREAK && !(step_range_end && INNER_THAN (read_sp (), (step_sp - 16)))) : @@ -1864,7 +1909,7 @@ wait_for_inferior () } if (stop_signal == TARGET_SIGNAL_TRAP) - random_signal + ecs->random_signal = !(bpstat_explains_signal (stop_bpstat) || trap_expected || (!CALL_DUMMY_BREAKPOINT_OFFSET_P @@ -1874,7 +1919,7 @@ wait_for_inferior () else { - random_signal + ecs->random_signal = !(bpstat_explains_signal (stop_bpstat) /* End of a stack dummy. Some systems (e.g. Sony news) give another signal besides SIGTRAP, so @@ -1883,7 +1928,7 @@ wait_for_inferior () && PC_IN_CALL_DUMMY (stop_pc, read_sp (), FRAME_FP (get_current_frame ()))) ); - if (!random_signal) + if (!ecs->random_signal) stop_signal = TARGET_SIGNAL_TRAP; } } @@ -1893,14 +1938,14 @@ wait_for_inferior () (unexpected) signal. */ else - random_signal = 1; + ecs->random_signal = 1; /* If a fork, vfork or exec event was seen, then there are two possible responses we can make: - 1. If a catchpoint triggers for the event (random_signal == 0), + 1. If a catchpoint triggers for the event (ecs->random_signal == 0), then we must stop now and issue a prompt. We will resume the inferior when the user tells us to. - 2. If no catchpoint triggers for the event (random_signal == 1), + 2. If no catchpoint triggers for the event (ecs->random_signal == 1), then we must resume the inferior now and keep checking. In either case, we must take appropriate steps to "follow" the @@ -1911,27 +1956,27 @@ wait_for_inferior () In either case, setting pending_follow causes the next resume() to take the appropriate following action. */ process_event_stop_test: - if (w.kind == TARGET_WAITKIND_FORKED) + if (ecs->ws.kind == TARGET_WAITKIND_FORKED) { - if (random_signal) /* I.e., no catchpoint triggered for this. */ + if (ecs->random_signal) /* I.e., no catchpoint triggered for this. */ { trap_expected = 1; stop_signal = TARGET_SIGNAL_0; goto keep_going; } } - else if (w.kind == TARGET_WAITKIND_VFORKED) + else if (ecs->ws.kind == TARGET_WAITKIND_VFORKED) { - if (random_signal) /* I.e., no catchpoint triggered for this. */ + if (ecs->random_signal) /* I.e., no catchpoint triggered for this. */ { stop_signal = TARGET_SIGNAL_0; goto keep_going; } } - else if (w.kind == TARGET_WAITKIND_EXECD) + else if (ecs->ws.kind == TARGET_WAITKIND_EXECD) { - pending_follow.kind = w.kind; - if (random_signal) /* I.e., no catchpoint triggered for this. */ + pending_follow.kind = ecs->ws.kind; + if (ecs->random_signal) /* I.e., no catchpoint triggered for this. */ { trap_expected = 1; stop_signal = TARGET_SIGNAL_0; @@ -1942,7 +1987,7 @@ wait_for_inferior () /* For the program's own signals, act according to the signal handling tables. */ - if (random_signal) + if (ecs->random_signal) { /* Signal not for debugging purposes. */ int printed = 0; @@ -1966,7 +2011,7 @@ wait_for_inferior () gdb_flush (gdb_stdout); } if (signal_stop[stop_signal]) - break; + goto wfi_break; /* If not going to stop, give terminal back if we took it away. */ else if (printed) @@ -2038,7 +2083,7 @@ wait_for_inferior () else #endif /* 0 */ set_longjmp_resume_breakpoint (jmp_buf_pc, NULL); - handling_longjmp = 1; /* FIXME */ + ecs->handling_longjmp = 1; /* FIXME */ goto keep_going; case BPSTAT_WHAT_CLEAR_LONGJMP_RESUME: @@ -2051,12 +2096,12 @@ wait_for_inferior () && (INNER_THAN (FRAME_FP (get_current_frame ()), step_frame_address))) { - another_trap = 1; + ecs->another_trap = 1; goto keep_going; } #endif /* 0 */ disable_longjmp_breakpoint (); - handling_longjmp = 0; /* FIXME */ + ecs->handling_longjmp = 0; /* FIXME */ if (what.main_action == BPSTAT_WHAT_CLEAR_LONGJMP_RESUME) break; /* else fallthrough */ @@ -2068,7 +2113,7 @@ wait_for_inferior () remove_breakpoints (); } breakpoints_inserted = 0; - another_trap = 1; + ecs->another_trap = 1; /* Still need to check other stuff, at least the case where we are stepping and step out of the right range. */ break; @@ -2121,7 +2166,7 @@ wait_for_inferior () /* If were waiting for a trap, hitting the step_resume_break doesn't count as getting it. */ if (trap_expected) - another_trap = 1; + ecs->another_trap = 1; break; case BPSTAT_WHAT_CHECK_SHLIBS: @@ -2185,18 +2230,18 @@ wait_for_inferior () friends) until we reach non-dld code. At that point, we can stop stepping. */ bpstat_get_triggered_catchpoints (stop_bpstat, - &stepping_through_solib_catchpoints); - stepping_through_solib_after_catch = 1; + &ecs->stepping_through_solib_catchpoints); + ecs->stepping_through_solib_after_catch = 1; /* Be sure to lift all breakpoints, so the inferior does actually step past this point... */ - another_trap = 1; + ecs->another_trap = 1; break; } else { /* We want to step over this breakpoint, then keep going. */ - another_trap = 1; + ecs->another_trap = 1; break; } } @@ -2220,22 +2265,22 @@ wait_for_inferior () /* Are we stepping to get the inferior out of the dynamic linker's hook (and possibly the dld itself) after catching a shlib event? */ - if (stepping_through_solib_after_catch) + if (ecs->stepping_through_solib_after_catch) { #if defined(SOLIB_ADD) /* Have we reached our destination? If not, keep going. */ - if (SOLIB_IN_DYNAMIC_LINKER (pid, stop_pc)) + if (SOLIB_IN_DYNAMIC_LINKER (ecs->pid, stop_pc)) { - another_trap = 1; + ecs->another_trap = 1; goto keep_going; } #endif /* Else, stop and report the catchpoint(s) whose triggering caused us to begin stepping. */ - stepping_through_solib_after_catch = 0; + ecs->stepping_through_solib_after_catch = 0; bpstat_clear (&stop_bpstat); - stop_bpstat = bpstat_copy (stepping_through_solib_catchpoints); - bpstat_clear (&stepping_through_solib_catchpoints); + stop_bpstat = bpstat_copy (ecs->stepping_through_solib_catchpoints); + bpstat_clear (&ecs->stepping_through_solib_catchpoints); stop_print_frame = 1; goto stop_stepping; } @@ -2260,7 +2305,7 @@ wait_for_inferior () #ifdef HP_OS_BUG trap_expected_after_continue = 1; #endif - break; + goto wfi_break; } } @@ -2303,10 +2348,10 @@ wait_for_inferior () /* We can't update step_sp every time through the loop, because reading the stack pointer would slow down stepping too much. But we can update it every time we leave the step range. */ - update_step_sp = 1; + ecs->update_step_sp = 1; /* Did we just take a signal? */ - if (IN_SIGTRAMP (stop_pc, stop_func_name) + if (IN_SIGTRAMP (stop_pc, ecs->stop_func_name) && !IN_SIGTRAMP (prev_pc, prev_func_name) && INNER_THAN (read_sp (), step_sp)) { @@ -2365,13 +2410,13 @@ wait_for_inferior () code, anyway, so it's OK instead to just single-step out. Note: assuming such trampolines don't exhibit recursion on any platform... */ - find_pc_partial_function (stop_pc, &stop_func_name, - &stop_func_start, - &stop_func_end); + find_pc_partial_function (stop_pc, &ecs->stop_func_name, + &ecs->stop_func_start, + &ecs->stop_func_end); /* Readjust stepping range */ - step_range_start = stop_func_start; - step_range_end = stop_func_end; - stepping_through_sigtramp = 1; + step_range_start = ecs->stop_func_start; + step_range_end = ecs->stop_func_end; + ecs->stepping_through_sigtramp = 1; } } @@ -2384,15 +2429,15 @@ wait_for_inferior () range? */ step_range_end = (step_range_start = prev_pc) + 1; - remove_breakpoints_on_following_step = 1; + ecs->remove_breakpoints_on_following_step = 1; goto keep_going; } - if (stop_pc == stop_func_start /* Quick test */ - || (in_prologue (stop_pc, stop_func_start) && - !IN_SOLIB_RETURN_TRAMPOLINE (stop_pc, stop_func_name)) - || IN_SOLIB_CALL_TRAMPOLINE (stop_pc, stop_func_name) - || stop_func_name == 0) + if (stop_pc == ecs->stop_func_start /* Quick test */ + || (in_prologue (stop_pc, ecs->stop_func_start) && + !IN_SOLIB_RETURN_TRAMPOLINE (stop_pc, ecs->stop_func_name)) + || IN_SOLIB_CALL_TRAMPOLINE (stop_pc, ecs->stop_func_name) + || ecs->stop_func_name == 0) { /* It's a subroutine call. */ @@ -2402,7 +2447,7 @@ wait_for_inferior () supposed to be stepping at the assembly language level ("stepi"). Just stop. */ stop_step = 1; - break; + goto wfi_break; } if (step_over_calls > 0 || IGNORE_HELPER_CALL (stop_pc)) @@ -2416,7 +2461,7 @@ wait_for_inferior () the end of, if we do step into it. */ tmp = SKIP_TRAMPOLINE_CODE (stop_pc); if (tmp != 0) - stop_func_start = tmp; + ecs->stop_func_start = tmp; else { tmp = DYNAMIC_TRAMPOLINE_NEXTPC (stop_pc); @@ -2444,7 +2489,7 @@ wait_for_inferior () { struct symtab_and_line tmp_sal; - tmp_sal = find_pc_line (stop_func_start, 0); + tmp_sal = find_pc_line (ecs->stop_func_start, 0); if (tmp_sal.line != 0) goto step_into_function; } @@ -2491,10 +2536,10 @@ wait_for_inferior () e.g.) and the frame address is likely to be incorrect. No danger of sigtramp recursion. */ - if (stepping_through_sigtramp) + if (ecs->stepping_through_sigtramp) { step_resume_breakpoint->frame = (CORE_ADDR) NULL; - stepping_through_sigtramp = 0; + ecs->stepping_through_sigtramp = 0; } else if (!IN_SOLIB_DYNSYM_RESOLVE_CODE (sr_sal.pc)) step_resume_breakpoint->frame = step_frame_address; @@ -2512,9 +2557,9 @@ wait_for_inferior () s = find_pc_symtab (stop_pc); if (s && s->language != language_asm) - stop_func_start = SKIP_PROLOGUE (stop_func_start); + ecs->stop_func_start = SKIP_PROLOGUE (ecs->stop_func_start); } - sal = find_pc_line (stop_func_start, 0); + ecs->sal = find_pc_line (ecs->stop_func_start, 0); /* Use the step_resume_break to step until the end of the prologue, even if that involves jumps (as it seems to on the vax under 4.2). */ @@ -2525,15 +2570,15 @@ wait_for_inferior () /* no, don't either. It skips any code that's legitimately on the first line. */ #else - if (sal.end && sal.pc != stop_func_start && sal.end < stop_func_end) - stop_func_start = sal.end; + if (ecs->sal.end && ecs->sal.pc != ecs->stop_func_start && ecs->sal.end < ecs->stop_func_end) + ecs->stop_func_start = ecs->sal.end; #endif - if (stop_func_start == stop_pc) + if (ecs->stop_func_start == stop_pc) { /* We are already there: stop now. */ stop_step = 1; - break; + goto wfi_break; } else /* Put the step-breakpoint there and go until there. */ @@ -2541,8 +2586,8 @@ wait_for_inferior () struct symtab_and_line sr_sal; INIT_SAL (&sr_sal); /* initialize to zeroes */ - sr_sal.pc = stop_func_start; - sr_sal.section = find_pc_overlay (stop_func_start); + sr_sal.pc = ecs->stop_func_start; + sr_sal.section = find_pc_overlay (ecs->stop_func_start); /* Do not specify what the fp should be when we stop since on some machines the prologue is where the new fp value is established. */ @@ -2559,19 +2604,19 @@ wait_for_inferior () /* We've wandered out of the step range. */ - sal = find_pc_line (stop_pc, 0); + ecs->sal = find_pc_line (stop_pc, 0); if (step_range_end == 1) { /* It is stepi or nexti. We always want to stop stepping after one instruction. */ stop_step = 1; - break; + goto wfi_break; } /* If we're in the return path from a shared library trampoline, we want to proceed through the trampoline when stepping. */ - if (IN_SOLIB_RETURN_TRAMPOLINE (stop_pc, stop_func_name)) + if (IN_SOLIB_RETURN_TRAMPOLINE (stop_pc, ecs->stop_func_name)) { CORE_ADDR tmp; @@ -2601,25 +2646,25 @@ wait_for_inferior () } } - if (sal.line == 0) + if (ecs->sal.line == 0) { /* We have no line number information. That means to stop stepping (does this always happen right after one instruction, when we do "s" in a function with no line numbers, or can this happen as a result of a return or longjmp?). */ stop_step = 1; - break; + goto wfi_break; } - if ((stop_pc == sal.pc) - && (current_line != sal.line || current_symtab != sal.symtab)) + if ((stop_pc == ecs->sal.pc) + && (ecs->current_line != ecs->sal.line || ecs->current_symtab != ecs->sal.symtab)) { /* We are at the start of a different line. So stop. Note that we don't stop if we step into the middle of a different line. That is said to make things like for (;;) statements work better. */ stop_step = 1; - break; + goto wfi_break; } /* We aren't done stepping. @@ -2629,7 +2674,7 @@ wait_for_inferior () new line in mid-statement, we continue stepping. This makes things like for(;;) statements work better.) */ - if (stop_func_end && sal.end >= stop_func_end) + if (ecs->stop_func_end && ecs->sal.end >= ecs->stop_func_end) { /* If this is the last line of the function, don't keep stepping (it would probably step us out of the function). @@ -2637,13 +2682,13 @@ wait_for_inferior () in which after skipping the prologue we better stop even though we will be in mid-line. */ stop_step = 1; - break; + goto wfi_break; } - step_range_start = sal.pc; - step_range_end = sal.end; + step_range_start = ecs->sal.pc; + step_range_end = ecs->sal.end; step_frame_address = FRAME_FP (get_current_frame ()); - current_line = sal.line; - current_symtab = sal.symtab; + ecs->current_line = ecs->sal.line; + ecs->current_symtab = ecs->sal.symtab; /* In the case where we just stepped out of a function into the middle of a line of the caller, continue stepping, but step_frame_address @@ -2659,7 +2704,7 @@ wait_for_inferior () check_sigtramp2: if (trap_expected - && IN_SIGTRAMP (stop_pc, stop_func_name) + && IN_SIGTRAMP (stop_pc, ecs->stop_func_name) && !IN_SIGTRAMP (prev_pc, prev_func_name) && INNER_THAN (read_sp (), step_sp)) { @@ -2686,8 +2731,8 @@ wait_for_inferior () if (breakpoints_inserted) insert_breakpoints (); - remove_breakpoints_on_following_step = 1; - another_trap = 1; + ecs->remove_breakpoints_on_following_step = 1; + ecs->another_trap = 1; } keep_going: @@ -2708,16 +2753,16 @@ wait_for_inferior () /* Save the pc before execution, to compare with pc after stop. */ prev_pc = read_pc (); /* Might have been DECR_AFTER_BREAK */ - prev_func_start = stop_func_start; /* Ok, since if DECR_PC_AFTER + prev_func_start = ecs->stop_func_start; /* Ok, since if DECR_PC_AFTER BREAK is defined, the original pc would not have been at the start of a function. */ - prev_func_name = stop_func_name; + prev_func_name = ecs->stop_func_name; - if (update_step_sp) + if (ecs->update_step_sp) step_sp = read_sp (); - update_step_sp = 0; + ecs->update_step_sp = 0; /* If we did not do break;, it means we should keep running the inferior and not return to debugger. */ @@ -2727,7 +2772,7 @@ wait_for_inferior () /* We took a signal (which we are supposed to pass through to the inferior, else we'd have done a break above) and we haven't yet gotten our trap. Simply continue. */ - resume (CURRENTLY_STEPPING (), stop_signal); + resume (currently_stepping (ecs), stop_signal); } else { @@ -2746,22 +2791,22 @@ wait_for_inferior () want to hit a breakpoint, pull em out. */ if (step_resume_breakpoint == NULL && through_sigtramp_breakpoint == NULL - && remove_breakpoints_on_following_step) + && ecs->remove_breakpoints_on_following_step) { - remove_breakpoints_on_following_step = 0; + ecs->remove_breakpoints_on_following_step = 0; remove_breakpoints (); breakpoints_inserted = 0; } else if (!breakpoints_inserted && - (through_sigtramp_breakpoint != NULL || !another_trap)) + (through_sigtramp_breakpoint != NULL || !ecs->another_trap)) { breakpoints_failed = insert_breakpoints (); if (breakpoints_failed) - break; + goto wfi_break; breakpoints_inserted = 1; } - trap_expected = another_trap; + trap_expected = ecs->another_trap; /* Do not deliver SIGNAL_TRAP (except when the user explicitly specifies that such a signal should be @@ -2793,10 +2838,36 @@ wait_for_inferior () SHIFT_INST_REGS (); #endif /* SHIFT_INST_REGS */ - resume (CURRENTLY_STEPPING (), stop_signal); + resume (currently_stepping (ecs), stop_signal); + } + + /* Former continues in the main loop goto here. */ + wfi_continue: + /* This used to be at the top of the loop. */ + if (ecs->infwait_state == infwait_normal_state) + { + overlay_cache_invalid = 1; + + /* We have to invalidate the registers BEFORE calling + target_wait because they can be loaded from the target + while in target_wait. This makes remote debugging a bit + more efficient for those targets that provide critical + registers as part of their normal status mechanism. */ + + registers_changed (); + ecs->waiton_pid = -1; + ecs->wp = &(ecs->ws); } + /* This is the old end of the while loop. Let everybody know + we want to wait for the inferior some more and get called + again soon. */ + ecs->wait_some_more = 1; + return; } + /* Former breaks in the main loop goto here. */ +wfi_break: + stop_stepping: if (target_has_execution) { @@ -2816,9 +2887,9 @@ stop_stepping: do { if (target_wait_hook) - parent_pid = target_wait_hook (-1, &w); + parent_pid = target_wait_hook (-1, &(ecs->ws)); else - parent_pid = target_wait (-1, &w); + parent_pid = target_wait (-1, &(ecs->ws)); } while (parent_pid != inferior_pid); } @@ -2827,10 +2898,25 @@ stop_stepping: time, just like we did above if we didn't break out of the loop. */ prev_pc = read_pc (); - prev_func_start = stop_func_start; - prev_func_name = stop_func_name; + prev_func_start = ecs->stop_func_start; + prev_func_name = ecs->stop_func_name; } - do_cleanups (old_cleanups); + /* Let callers know we don't want to wait for the inferior anymore. */ + ecs->wait_some_more = 0; +} + +/* Are we in the middle of stepping? */ + +int +currently_stepping (ecs) + struct execution_control_state *ecs; +{ + return ((through_sigtramp_breakpoint == NULL + && !ecs->handling_longjmp + && ((step_range_end && step_resume_breakpoint == NULL) + || trap_expected)) + || ecs->stepping_through_solib_after_catch + || bpstat_should_step ()); } /* This function returns TRUE if ep is an internal breakpoint @@ -3758,6 +3844,17 @@ of the program stops.", &cmdlist); signal_stop[TARGET_SIGNAL_WINCH] = 0; signal_print[TARGET_SIGNAL_WINCH] = 0; + /* These signals are used internally by user-level thread + implementations. (See signal(5) on Solaris.) Like the above + signals, a healthy program receives and handles them as part of + its normal operation. */ + signal_stop[TARGET_SIGNAL_LWP] = 0; + signal_print[TARGET_SIGNAL_LWP] = 0; + signal_stop[TARGET_SIGNAL_WAITING] = 0; + signal_print[TARGET_SIGNAL_WAITING] = 0; + signal_stop[TARGET_SIGNAL_CANCEL] = 0; + signal_print[TARGET_SIGNAL_CANCEL] = 0; + #ifdef SOLIB_ADD add_show_from_set (add_set_cmd ("stop-on-solib-events", class_support, var_zinteger, @@ -35,19 +35,6 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include "gdb_string.h" -/* Temporary variable for SET_TOP_LEVEL. */ - -static int top_level_val; - -/* Do a setjmp on error_return and quit_return. catch_errors is - generally a cleaner way to do this, but main() would look pretty - ugly if it had to use catch_errors each time. */ - -#define SET_TOP_LEVEL() \ - (((top_level_val = SIGSETJMP (error_return)) \ - ? (PTR) 0 : (PTR) memcpy (quit_return, error_return, sizeof (SIGJMP_BUF))) \ - , top_level_val) - /* If nonzero, display time usage both at startup and for each command. */ int display_time; @@ -56,6 +43,12 @@ int display_time; int display_space; +/* Whether this is the async version or not. The async version is +invoked on the command line with the -nw --async options. In this +version, the usual command_loop is substituted by and event loop which +processes UI events asynchronously. */ +int async = 0; + /* Whether this is the command line version or not */ int tui_version = 0; @@ -185,7 +178,8 @@ main (argc, argv) short option (or arbitrary numbers starting at 10 for those with no equivalent). */ static struct option long_options[] = - { + { + {"async", no_argument, &async, 1}, #if defined(TUI) {"tui", no_argument, &tui_version, 1}, #endif @@ -397,6 +391,10 @@ main (argc, argv) quiet = 1; } + /* Get ready to invoke the event loop instead of the + command_loop. See event-loop.h for more details.*/ + if (async) + async_hook = setup_event_loop; #if defined(TUI) if (tui_version) init_ui_hook = tuiInit; @@ -624,6 +622,12 @@ main (argc, argv) #endif } + /* Call the event loop, if gdb was invoked with the --async + option. Control will never get back to this file, if the event + loop is invoked. See the files event-*.[ch] for details. */ + if (async_hook) + async_hook(); + /* The default command loop. The WIN32 Gui calls this main to set up gdb's state, and has its own command loop. */ diff --git a/gdb/mips-tdep.c b/gdb/mips-tdep.c index 80bf1c4..2d8efdf 100644 --- a/gdb/mips-tdep.c +++ b/gdb/mips-tdep.c @@ -1153,21 +1153,29 @@ heuristic_proc_start (pc) { static int blurb_printed = 0; - if (fence == VM_MIN_ADDRESS) - warning("Hit beginning of text section without finding"); - else - warning("Hit heuristic-fence-post without finding"); + warning ("Warning: GDB can't find the start of the function at 0x%s.", + paddr_nz (pc)); - warning("enclosing function for address 0x%s", paddr_nz (pc)); if (!blurb_printed) { - printf_filtered ("\ -This warning occurs if you are debugging a function without any symbols\n\ -(for example, in a stripped executable). In that case, you may wish to\n\ -increase the size of the search with the `set heuristic-fence-post' command.\n\ -\n\ -Otherwise, you told GDB there was a function where there isn't one, or\n\ -(more likely) you have encountered a bug in GDB.\n"); + /* This actually happens frequently in embedded + development, when you first connect to a board + and your stack pointer and pc are nowhere in + particular. This message needs to give people + in that situation enough information to + determine that it's no big deal. */ + printf_filtered ("\n\ + GDB is unable to find the start of the function at 0x%s\n\ +and thus can't determine the size of that function's stack frame.\n\ +This means that GDB may be unable to access that stack frame, or\n\ +the frames below it.\n\ + This problem is most likely caused by an invalid program counter or\n\ +stack pointer.\n\ + However, if you think GDB should simply search farther back\n\ +from 0x%s for code which looks like the beginning of a\n\ +function, you can increase the range of the search using the `set\n\ +heuristic-fence-post' command.\n", + paddr_nz (pc), paddr_nz (pc)); blurb_printed = 1; } } diff --git a/gdb/target.c b/gdb/target.c index d96514c..fe0e0c0 100644 --- a/gdb/target.c +++ b/gdb/target.c @@ -1258,6 +1258,7 @@ static struct { {"SIG61", "Real-time event 61"}, {"SIG62", "Real-time event 62"}, {"SIG63", "Real-time event 63"}, + {"SIGCANCEL", "LWP internal signal"}, #if defined(MACH) || defined(__MACH__) /* Mach exceptions */ @@ -1446,6 +1447,9 @@ target_signal_from_host (hostsig) #if defined (SIGWAITING) if (hostsig == SIGWAITING) return TARGET_SIGNAL_WAITING; #endif +#if defined (SIGCANCEL) + if (hostsig == SIGCANCEL) return TARGET_SIGNAL_CANCEL; +#endif #if defined (SIGLWP) if (hostsig == SIGLWP) return TARGET_SIGNAL_LWP; #endif @@ -1624,6 +1628,9 @@ target_signal_to_host (oursig) #if defined (SIGWAITING) case TARGET_SIGNAL_WAITING: return SIGWAITING; #endif +#if defined (SIGCANCEL) + case TARGET_SIGNAL_CANCEL: return SIGCANCEL; +#endif #if defined (SIGLWP) case TARGET_SIGNAL_LWP: return SIGLWP; #endif diff --git a/gdb/target.h b/gdb/target.h index 41006ef..30d33a2 100644 --- a/gdb/target.h +++ b/gdb/target.h @@ -106,9 +106,14 @@ enum target_waitkind { signals (insofar as various unices use the same numbers, anyway). It is also the numbering of the GDB remote protocol. Other remote protocols, if they use a different numbering, should make sure to - translate appropriately. */ + translate appropriately. -/* This is based strongly on Unix/POSIX signals for several reasons: + Since these numbers have actually made it out into other software + (stubs, etc.), you mustn't disturb the assigned numbering. If you + need to add new signals here, add them to the end of the explicitly + numbered signals. + + This is based strongly on Unix/POSIX signals for several reasons: (1) This set of signals represents a widely-accepted attempt to represent events of this sort in a portable fashion, (2) we want a signal to make it from wait to child_wait to the user intact, (3) many @@ -205,6 +210,10 @@ enum target_signal { TARGET_SIGNAL_REALTIME_61 = 73, TARGET_SIGNAL_REALTIME_62 = 74, TARGET_SIGNAL_REALTIME_63 = 75, + + /* Used internally by Solaris threads. See signal(5) on Solaris. */ + TARGET_SIGNAL_CANCEL = 76, + #if defined(MACH) || defined(__MACH__) /* Mach exceptions */ TARGET_EXC_BAD_ACCESS, diff --git a/gdb/testsuite/ChangeLog b/gdb/testsuite/ChangeLog index 4a5eec1..c5e2362 100644 --- a/gdb/testsuite/ChangeLog +++ b/gdb/testsuite/ChangeLog @@ -1,3 +1,19 @@ +1999-05-06 Keith Seitz <keiths@cygnus.com> + + * gdb.base/annota2.cc: Include stdio.h. + +Wed May 5 17:44:31 1999 Stan Shebs <shebs@andros.cygnus.com> + + * gdb.base/crossload.exp: Remove, this has been disabled ever + since BFD stopped including all targets, and cross-GDB gets + plenty of testing anyway. + * gdb.base/i486-elf.u, gdb.base/m68k-aout.u, gdb.base/m68k-elf.u, + gdb.base/sparc-aout.u, gdb.base/i860-elf.u, gdb.base/m68k-aout2.u, + gdb.base/mips-ecoff.u, gdb.base/sparc-elf.u: Remove. + * gdb.base/README: Remove, was doc for this. + * gdb.base/Makefile.in (CROSS_EXECUTABLES): Remove, no longer + needed. + 1999-05-04 Elena Zannoni <ezannoni@kwikemart.cygnus.com> * gdb.base/call-ar-st.exp: Fix one regular expression in test diff --git a/gdb/testsuite/gdb.base/Makefile.in b/gdb/testsuite/gdb.base/Makefile.in index a5d6374..11cf1da 100644 --- a/gdb/testsuite/gdb.base/Makefile.in +++ b/gdb/testsuite/gdb.base/Makefile.in @@ -14,10 +14,6 @@ EXECUTABLES = all-types bitfields break \ solib so-impl-ld so-indr-cl \ step-test structs structs2 twice-tmp varargs watchpoint whatis -# uuencoded format to avoid SCCS/RCS problems with binary files. -CROSS_EXECUTABLES = i486-elf i860-elf m68k-elf m68k-aout m68k-aout2 \ - mips-ecoff sparc-aout sparc-elf - MISCELLANEOUS = coremmap.data shr1.sl shr2.sl solib1.sl solib2.sl all: @@ -32,7 +28,7 @@ installcheck: check: clean mostlyclean: - -rm -f *~ *.o a.out xgdb *.x $(CROSS_EXECUTABLES) *.ci *.tmp + -rm -f *~ *.o a.out xgdb *.x *.ci *.tmp -rm -f core core.coremaker coremaker.core corefile $(EXECUTABLES) -rm -f $(MISCELLANEOUS) twice-tmp.c diff --git a/gdb/testsuite/gdb.base/annota2.cc b/gdb/testsuite/gdb.base/annota2.cc index e9d7da03..f8a25f9 100644 --- a/gdb/testsuite/gdb.base/annota2.cc +++ b/gdb/testsuite/gdb.base/annota2.cc @@ -1,3 +1,5 @@ +#include <stdio.h> + class A { public: int x; @@ -33,6 +33,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include "terminal.h" /* For job_control. */ #include "annotate.h" #include "top.h" +#include "event-loop.h" /* readline include files */ #include <readline/readline.h> @@ -70,7 +71,16 @@ static char * line_completion_function PARAMS ((char *, int, char *, int)); static char * readline_line_completion_function PARAMS ((char *, int)); -static void command_loop_marker PARAMS ((int)); +/* NOTE 4/29/99: this function will be static again, after we make the + event loop be the default command loop for gdb, and we merge + event-top.c into this file, top.c */ +/* static */ void command_loop_marker PARAMS ((int)); + +extern void set_async_editing_command PARAMS ((char *, int, struct cmd_list_element *)); + +extern void set_async_annotation_level PARAMS ((char *, int, struct cmd_list_element *)); + +extern void set_async_prompt PARAMS ((char *, int, struct cmd_list_element *)); static void while_command PARAMS ((char *, int)); @@ -139,7 +149,10 @@ static void complete_command PARAMS ((char *, int)); static void do_nothing PARAMS ((int)); #ifdef SIGHUP -static int quit_cover PARAMS ((PTR)); +/* NOTE 4/29/99: This function will be static again, once we modify + gdb to use the event loop as the default command loop and we merge + event-top.c into this file, top.c */ +/* static */ int quit_cover PARAMS ((PTR)); static void disconnect PARAMS ((int)); #endif @@ -586,7 +599,10 @@ int signo; /* Just a little helper function for disconnect(). */ -static int +/* NOTE 4/29/99: This function will be static again, once we modify + gdb to use the event loop as the default command loop and we merge + event-top.c into this file, top.c */ +/* static */ int quit_cover (s) PTR s; { @@ -598,19 +614,31 @@ quit_cover (s) #endif /* defined SIGHUP */ /* Line number we are currently in in a file which is being sourced. */ -static int source_line_number; +/* NOTE 4/29/99: This variable will be static again, once we modify + gdb to use the event loop as the default command loop and we merge + event-top.c into this file, top.c */ +/* static */ int source_line_number; /* Name of the file we are sourcing. */ -static char *source_file_name; +/* NOTE 4/29/99: This variable will be static again, once we modify + gdb to use the event loop as the default command loop and we merge + event-top.c into this file, top.c */ +/* static */ char *source_file_name; /* Buffer containing the error_pre_print used by the source stuff. Malloc'd. */ -static char *source_error; +/* NOTE 4/29/99: This variable will be static again, once we modify + gdb to use the event loop as the default command loop and we merge + event-top.c into this file, top.c */ +/* static */ char *source_error; static int source_error_allocated; /* Something to glom on to the start of error_pre_print if source_file_name is set. */ -static char *source_pre_error; +/* NOTE 4/29/99: This variable will be static again, once we modify + gdb to use the event loop as the default command loop and we merge + event-top.c into this file, top.c */ +/* static */ char *source_pre_error; /* Clean up on error during a "source" command (or execution of a user-defined command). */ @@ -657,7 +685,15 @@ gdb_init (argv0) initialize_utils (); /* Make errors and warnings possible */ initialize_all_files (); init_main (); /* But that omits this file! Do it now */ - init_signals (); + + /* The signal handling mechanism is different depending whether or + not the async version is run. NOTE: in the future we plan to make + the event loop be the default engine of gdb, and this difference + will disappear. */ + if (async_hook) + async_init_signals (); + else + init_signals (); init_proc (); @@ -1293,7 +1329,10 @@ execute_command (p, from_tty) } /* ARGSUSED */ -static void +/* NOTE 4/29/99: This function will be static again, once we modify + gdb to use the event loop as the default command loop and we merge + event-top.c into this file, top.c */ +/* static */ void command_loop_marker (foo) int foo; { @@ -1479,7 +1518,10 @@ gdb_readline (prrompt) substitution. These variables are given default values at the end of this file. */ static int command_editing_p; -static int history_expansion_p; +/* NOTE 4/29/99: This variable will be static again, once we modify + gdb to use the event loop as the default command loop and we merge + event-top.c into this file, top.c */ +/* static */ int history_expansion_p; static int write_history_p; static int history_size; static char *history_filename; @@ -3448,14 +3490,44 @@ init_main () { struct cmd_list_element *c; + /* from event-top.c */ + extern int async_command_editing_p; + extern struct prompts the_prompts; + extern char *async_annotation_suffix; + extern char *new_async_prompt; + + /* If we are running the asynchronous version, + we initialize the prompts differently. */ + if (!async_hook) + { #ifdef DEFAULT_PROMPT - prompt = savestring (DEFAULT_PROMPT, strlen(DEFAULT_PROMPT)); + prompt = savestring (DEFAULT_PROMPT, strlen(DEFAULT_PROMPT)); #else - prompt = savestring ("(gdb) ", 6); + prompt = savestring ("(gdb) ", 6); #endif + } + else + { + /* initialize the prompt stack to a simple "(gdb) " prompt or to + whatever the DEFULAT_PROMPT is. */ + the_prompts.top = 0; + PREFIX(0) = ""; +#ifdef DEFAULT_PROMPT + PROMPT(0) = savestring (DEFAULT_PROMPT, strlen(DEFAULT_PROMPT)); +#else + PROMPT(0) = savestring ("(gdb) ", 6); +#endif + SUFFIX(0) = ""; + /* Set things up for annotation_level > 1, if the user ever decides + to use it. */ + async_annotation_suffix = "prompt"; + /* Set the variable associated with the setshow prompt command. */ + new_async_prompt = savestring (PROMPT (0), strlen (PROMPT (0))); + } /* Set the important stuff up for command editing. */ command_editing_p = 1; + async_command_editing_p = 1; history_expansion_p = 0; write_history_p = 0; @@ -3503,11 +3575,27 @@ The change does not take effect for the program being debugged\n\ until the next time it is started.", &cmdlist); c->completer = filename_completer; - add_show_from_set - (add_set_cmd ("prompt", class_support, var_string, (char *)&prompt, - "Set gdb's prompt", - &setlist), - &showlist); + /* The set prompt command is different depending whether or not the + async version is run. NOTE: this difference is going to + disappear as we make the event loop be the default engine of + gdb. */ + if (!async_hook) + { + add_show_from_set + (add_set_cmd ("prompt", class_support, var_string, (char *)&prompt, + "Set gdb's prompt", + &setlist), + &showlist); + } + else + { + c = add_set_cmd ("prompt", class_support, var_string, + (char *)&new_async_prompt, + "Set gdb's prompt", + &setlist); + add_show_from_set (c, &showlist); + c->function.sfunc = set_async_prompt; + } add_com ("echo", class_support, echo_command, "Print a constant string. Give string as argument.\n\ @@ -3558,13 +3646,30 @@ hitting return."); c->function.sfunc = set_verbose; set_verbose (NULL, 0, c); - add_show_from_set - (add_set_cmd ("editing", class_support, var_boolean, (char *)&command_editing_p, - "Set editing of command lines as they are typed.\n\ + /* The set editing command is different depending whether or not the + async version is run. NOTE: this difference is going to disappear + as we make the event loop be the default engine of gdb. */ + if (!async_hook) + { + add_show_from_set + (add_set_cmd ("editing", class_support, var_boolean, (char *)&command_editing_p, + "Set editing of command lines as they are typed.\n\ Use \"on\" to enable the editing, and \"off\" to disable it.\n\ Without an argument, command line editing is enabled. To edit, use\n\ EMACS-like or VI-like commands like control-P or ESC.", &setlist), - &showlist); + &showlist); + } + else + { + c = add_set_cmd ("editing", class_support, var_boolean, (char *)&async_command_editing_p, + "Set editing of command lines as they are typed.\n\ +Use \"on\" to enable the editing, and \"off\" to disable it.\n\ +Without an argument, command line editing is enabled. To edit, use\n\ +EMACS-like or VI-like commands like control-P or ESC.", &setlist); + + add_show_from_set (c, &showlist); + c->function.sfunc = set_async_editing_command; + } add_prefix_cmd ("history", class_support, set_history, "Generic command for setting command history parameters.", @@ -3664,10 +3769,27 @@ This value is used to set the time limit for gdb to wait for a response\n\ from the target.", &setlist), &showlist); - c = add_set_cmd ("annotate", class_obscure, var_zinteger, - (char *)&annotation_level, "Set annotation_level.\n\ + /* The set annotate command is different depending whether or not + the async version is run. NOTE: this difference is going to + disappear as we make the event loop be the default engine of + gdb. */ + if (!async_hook) + { + c = add_set_cmd ("annotate", class_obscure, var_zinteger, + (char *)&annotation_level, "Set annotation_level.\n\ 0 == normal; 1 == fullname (for use when running under emacs)\n\ 2 == output annotated suitably for use by programs that control GDB.", - &setlist); - c = add_show_from_set (c, &showlist); + &setlist); + c = add_show_from_set (c, &showlist); + } + else + { + c = add_set_cmd ("annotate", class_obscure, var_zinteger, + (char *)&annotation_level, "Set annotation_level.\n\ +0 == normal; 1 == fullname (for use when running under emacs)\n\ +2 == output annotated suitably for use by programs that control GDB.", + &setlist); + add_show_from_set (c, &showlist); + c->function.sfunc = set_async_annotation_level; + } } @@ -41,6 +41,19 @@ extern char gdbinit[]; #define SIGLONGJMP(buf,val) longjmp(buf,val) #endif +/* Temporary variable for SET_TOP_LEVEL. */ + +int top_level_val; + +/* Do a setjmp on error_return and quit_return. catch_errors is + generally a cleaner way to do this, but main() would look pretty + ugly if it had to use catch_errors each time. */ + +#define SET_TOP_LEVEL() \ + (((top_level_val = SIGSETJMP (error_return)) \ + ? (PTR) 0 : (PTR) memcpy (quit_return, error_return, sizeof (SIGJMP_BUF))) \ + , top_level_val) + extern SIGJMP_BUF error_return; extern SIGJMP_BUF quit_return; @@ -55,6 +68,9 @@ extern int quit_confirm PARAMS ((void)); extern void quit_force PARAMS ((char *, int)); extern void quit_command PARAMS ((char *, int)); +extern void setup_event_loop PARAMS ((void)); +extern void async_init_signals PARAMS ((void)); + /* This function returns a pointer to the string that is used by gdb for its command prompt. */ extern char *get_prompt PARAMS((void)); |