From 11cf87416416e13eff634a70b4954fe6a3912720 Mon Sep 17 00:00:00 2001 From: Jason Molenda Date: Tue, 9 Nov 1999 01:23:30 +0000 Subject: [PATCH] import gdb-1999-11-08 snapshot --- gdb/ChangeLog | 228 ++++++++++++++++++ gdb/Makefile.in | 2 +- gdb/NEWS | 6 + gdb/breakpoint.c | 15 +- gdb/config/i386/nm-i386sol2.h | 9 - gdb/config/i386/nm-linux.h | 8 - gdb/config/i960/tm-nindy960.h | 19 +- gdb/config/mcore/tm-mcore.h | 4 +- gdb/config/pa/nm-hppah.h | 5 - gdb/config/sparc/nm-sun4sol2.h | 9 - gdb/corefile.c | 2 +- gdb/d10v-tdep.c | 2 +- gdb/d30v-tdep.c | 2 +- gdb/defs.h | 30 ++- gdb/doc/ChangeLog | 4 + gdb/doc/gdb.texinfo | 19 +- gdb/elfread.c | 2 +- gdb/event-loop.c | 108 ++++----- gdb/gdbserver/low-linux.c | 2 +- gdb/hpux-thread.c | 21 +- gdb/i386-linux-nat.c | 7 + gdb/infcmd.c | 96 +++----- gdb/inferior.h | 20 +- gdb/infrun.c | 126 +++++++--- gdb/kod.c | 1 - gdb/linux-thread.c | 56 +++-- gdb/main.c | 142 ++++++++---- gdb/procfs.c | 50 ++-- gdb/rdi-share/Makefile.in | 2 +- gdb/rdi-share/devsw.c | 4 +- gdb/remote-rdp.c | 2 +- gdb/remote.c | 321 +++++++++++++++++++++----- gdb/serial.c | 2 +- gdb/sol-thread.c | 31 ++- gdb/symfile.c | 7 +- gdb/symmisc.c | 6 +- gdb/target.c | 6 + gdb/target.h | 31 ++- gdb/testsuite/ChangeLog | 41 ++++ gdb/testsuite/gdb.base/annota1.exp | 3 +- gdb/testsuite/gdb.base/break.exp | 2 +- gdb/testsuite/gdb.base/condbreak.exp | 54 ++++- gdb/testsuite/gdb.base/display.exp | 11 +- gdb/testsuite/gdb.base/ena-dis-br.exp | 18 +- gdb/testsuite/gdb.base/funcargs.exp | 242 +++++++++++++++++-- gdb/testsuite/gdb.base/remote.exp | 104 +++++++-- gdb/testsuite/gdb.base/shlib-call.exp | 6 +- gdb/testsuite/lib/gdb.exp | 17 +- gdb/top.c | 62 +++++ gdb/top.h | 13 -- gdb/tui/ChangeLog | 13 ++ gdb/tui/tuiDisassem.c | 19 +- gdb/tui/tuiRegs.c | 6 +- gdb/utils.c | 179 ++++++++------ sim/common/ChangeLog | 13 ++ sim/common/cgen-par.c | 48 ++++ sim/common/cgen-par.h | 15 +- 57 files changed, 1733 insertions(+), 540 deletions(-) diff --git a/gdb/ChangeLog b/gdb/ChangeLog index ed00ee19d47..f75ce8d9ca0 100644 --- a/gdb/ChangeLog +++ b/gdb/ChangeLog @@ -1,3 +1,231 @@ +1999-11-08 Mark Salter + + * utils.c (floatformat_to_doublest): Fix conversion of denormals. + +Mon Nov 8 20:14:13 1999 Andrew Cagney + + * remote.c (get_memory_read_packet_size): For moment limit read + size to PBUFSIZ. + (putpkt_binary): Remove check on packet size. Allocate ``cnt + + 6'' characters for output buffer. + (get_memory_packet_size): When packet size is ``fixed'' and the + size is zero, return MAX_REMOTE_PACKET_SIZE. Check that packets + are at least MIN_REMOTE_PACKET_SIZE. + (set_memory_packet_size): Print usage when ``args'' is NULL. + +Mon Nov 8 18:18:07 1999 Andrew Cagney + + * defs.h, utils.c (gdb_file_deallocate): Delete. + * corefile.c (memory_error): Use make_cleanup_gdb_file_delete. + + * defs.h, utils.c (gdb_file_init_astring): Delete. + + * defs.h, utils.c (tui_file_get_strbuf): Rename + gdb_file_get_strbuf. + (tui_file_adjust_strbuf): Rename gdb_file_adjust_strbuf. + * utils.c (error_stream, error_last_message): Update. + +Mon Nov 8 16:28:00 1999 Andrew Cagney + + * defs.h, utils.c (gdb_fclose): Delete. + * defs.h (make_cleanup_gdb_file): Declare. + * utils.c (make_cleanup_gdb_file_delete, do_gdb_file_delete): New + functions. + + * symmisc.c (maintenance_print_symbols, + maintenance_print_psymbols, maintenance_print_msymbols): Use + make_cleanup_gdb_file_delete. + * serial.c (do_serial_close): Use gdb_file_delete. + +Mon Nov 8 14:16:32 1999 Andrew Cagney + + * defs.h (gdb_file_write_ftype, set_gdb_file_write, + gdb_file_write): Declare. + + * utils.c (struct gdb_file): Add to_write member. + (gdb_file_write, set_gdb_file_write): New functions. + (gdb_file_new): Initialize the write method. + (null_file_write): New function. + (null_file_fputs, null_file_write): ``write'' calls ``fputs'' and + ``fputs'' calls ``write'' when the other is implemented. + (stdio_file_new): Initialize write method. + (stdio_file_write): New function. + + * utils.c (putchar_unfiltered, fputc_unfiltered): Use + gdb_file_write. + +Thu Nov 4 11:59:24 1999 Andrew Cagney + + * remote.c (get_memory_packet_size, set_memory_packet_size, + build_memory_packet_size): New functions. Set / compute / update + the size of a memory read / write packet. + (set_memory_read_packet_size, set_memory_write_packet_size): New + functions. Verify changes to the memory read / write packet size. + (prefered_memory_write_packet_size, + current_memory_write_packet_size, prefered_memory_read_packet_size, + current_memory_read_packet_size): New variables. + (get_memory_read_packet_size, get_memory_write_packet_size): New + functions. Determine the current memory read/write packet size. A + function is needed as ``current_register_packet_size'', a variable + is used in the calculation. + (register_remote_packet_sizes, build_remote_packet_sizes): + Initialize packet sizes according the current architecture. + (remote_fetch_registers, remote_write_bytes, remote_read_bytes, + build_remote_gdbarch_data): Update. + (_initialize_remote): Add the commands ``set remote + memory-read-packet-size'' and ``set remote + memory-write-packet-size''. Deprecate ``set remotepacketsize''. + +Sun Nov 7 18:09:54 1999 Andrew Cagney + + * target.h, target.c (target_load): Replace macro with a function. + + * config/i960/tm-nindy960.h (ADDITIONAL_OPTION_HANDLER): Rewrite + replacing SET_TOP_LEVEL with catch_command_errors. + (nindy_open): Add extern declaration. + + * top.h (top_level_val, SET_TOP_LEVEL): Delete. + * defs.h (catch_command_errors_ftype, catch_command_errors): Add + declarations. + * top.c (struct captured_command_args): Declare. + (do_captured_command, catch_command_errors): New functions. Call + the command function via catch_errors. + (catch_errors): Add more comments. + + * main.c (struct captured_main_args): Define. + (captured_main): New. Rewrite main. Replace SET_TOP_LEVEL with + calls to catch_command_errors. Delete calls to do_cleanups which + are now handled by catch_errors. Call the command loop via + captured_command_loop and catch_errors. + (main): Move code body to captured_main. Call captured_main via + catch_errors. + (captured_command_loop): New function. Wrap call to command_loop. + +1999-11-05 Elena Zannoni + + * procfs.c (unconditionally_kill_inferior) (init_procinfo) + (create_procinfo) (procfs_exit_handler) (proc_set_exec_trap) + (do_attach) (do_detach) (procfs_wait) (set_proc_siginfo) + (procfs_resume) (info_proc_mappings) + (modify_run_on_last_close_flag) (procfs_lwp_creation_handler) + (procfs_thread_alive): Remove unused variables, conditionalize + vars declarations to eliminate compiler warnings. + +Fri Nov 5 16:32:04 1999 Andrew Cagney + + * inferior.h (CALL_DUMMY_ADDRESS, CALL_DUMMY_START_OFFSET, + CALL_DUMMY_BREAKPOINT_OFFSET, CALL_DUMMY_LENGTH, + CALL_DUMMY_STACK_ADJUST, CALL_DUMMY_WORDS, + SIZEOF_CALL_DUMMY_WORDS, PUSH_DUMMY_FRAME, FIX_CALL_DUMMY, + STORE_STRUCT_RETURN), d10v-tdep.c (print_insn), d30v-tdep.c + (print_insn), target.h (SOFTWARE_SINGLE_STEP): Call internal_error + instead of abort. + + * utils.c (stdio_file_delete, stdio_file_flush, stdio_file_fputs, + stdio_file_isatty, tui_file_delete, tui_file_isatty, + tui_file_rewind, tui_file_put, gdb_file_init_astring, + gdb_file_get_strbuf, gdb_file_adjust_strbuf): Call internal_error + instead of error. + +1999-11-04 Kevin Buettner + + * remote.c (build_remote_gdbarch_data): Set remote_address_size... + (_initialize_remote) ...but don't set it here. Also, tie + remote_address_size to the target architecture via call to + register_gdbarch_swap(). + +1999-11-04 Jeff Holcomb + + * remote-rdp.c (send_rdp): Fix typo. + +1999-11-04 Michael Snyder + + * breakpoint.c (commands_command): remove unprotected ref to + args pointer (which may be null). + +1999-11-04 Elena Zannoni + + * infcmd.c (print_return_value): New function. Print return value + from finish command. + (finish_command_continuation): Call print_return_value(). + (finish_command): Ditto. + +1999-11-04 Elena Zannoni + + * infrun.c (handle_inferior_event): Add calls to print_stop_reason() + for end of stepping range cases. + +Thu Nov 4 17:46:36 1999 Andrew Cagney + + * event-loop.c (gdb_do_one_event): Delete SET_TOP_LEVEL call. + Move error code to start_event_loop. + (start_event_loop): Call gdb_do_one_event via catch_errors. + Handle caught errors. + +Thu Nov 4 17:36:27 1999 Andrew Cagney + + * breakpoint.c (get_number): Delete static declaration. + +1999-11-03 Michael Snyder + + * breakpoint.c (map_breakpoint_numbers): use a match count + instead of a goto. + +1999-11-03 Nick Clifton + + * config/mcore/tm-mcore.h (TARGET_BYTE_ORDER_DEFAULT): Change to + little endian. + +1999-11-02 Michael Snyder + + * target.h (target_new_objfile) replace macro with function pointer + hook. Any module needing notification of new objfiles may claim + this hook. Multiple notification clients must cooperate by saving + the previous pointer (if any) and calling it. + * sol-thread.c (_initialize_sol_thread): point new_objfile hook at + sol_thread_new_objfile. Save old pointer if any. + (sol_thread_new_objfile): call old owner of event hook if any. + * hpux-thread.c (_initialize_hpux_thread, hpux_thread_new_objfile): + ditto. + * linux-thread.c (_initialize_linux_thread, linux_thread_new_objfile): + ditto. + symfile.c (symbol_file_add, clear_symtab_users) call the new + function pointer hook, instead of the macro. + * config/sparc/nm-sun4sol2.h: remove define of target_new_objfile. + * config/pa/nm-hppah.h: ditto. + * config/i386/nm-i386sol2.h: ditto. + * config/i386/nm-linux.h: ditto. + +1999-11-02 Tom Tromey + + * NEWS: Mention breakpoint ranges. + +1999-11-02 Fernando Nasser + + * rdi-share/devsw.c (openLogFile): Change a call to setlinebuf() + to an equivalent call to setvbuf() to prevent an unresolved + reference when building on cygwin. + +1999-11-02 Elena Zannoni + + * infrun.c (inferior_stop_reason): New enum, explicitly name the + resons for which the inferior stops. + (handle_inferior_event): Case TARGET_WAITKIND_EXITED: replace + printf's with call to print_stop_reason(). Case + TARGET_WAITKIND_SIGNALLED: Same. When stopped by random signal: + Same. + (print_stop_reason): New static function. Print relevant messages + when stopping. + +1999-11-02 Fernando Nasser + + * rdi-share/Makefile.in: Rename dependency from bytesex.o to + angel_bytesex.o. + +1999-11-02 Fernando Nasser + + * kod.c: Remove prototype for show_kod() which is no longer used. + 1999-11-01 Michael Snyder Tom Tromey diff --git a/gdb/Makefile.in b/gdb/Makefile.in index a24ca7954f0..8686020c56b 100644 --- a/gdb/Makefile.in +++ b/gdb/Makefile.in @@ -229,7 +229,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 = 19991101 +VERSION = 19991108 DIST=gdb LINT=/usr/5bin/lint diff --git a/gdb/NEWS b/gdb/NEWS index d8db0c5d5be..40778833dba 100644 --- a/gdb/NEWS +++ b/gdb/NEWS @@ -48,6 +48,12 @@ The command ``set remotebinarydownload'' command has been replaced by ``set remote X-packet''. Other commands in ``set remote'' family include ``set remote P-packet''. +* Breakpoint commands accept ranges. + +The breakpoint commands ``enable'', ``disable'', and ``delete'' now +accept a range of breakpoints, e.g. ``5-7''. The tracepoint command +``tracepoint passcount'' also accepts a range of tracepoints. + *** Changes in GDB-4.18: * New native configurations diff --git a/gdb/breakpoint.c b/gdb/breakpoint.c index 2f75e605eb1..ca7bb08cdf4 100644 --- a/gdb/breakpoint.c +++ b/gdb/breakpoint.c @@ -471,6 +471,7 @@ get_number_trailer (pp, trailer) return retval; } + /* Like get_number_trailer, but don't allow a trailer. */ int get_number (pp) @@ -632,8 +633,6 @@ commands_command (arg, from_tty) p = arg; bnum = get_number (&p); - if (bnum == 0) - error ("bad breakpoint number: '%s'", arg); if (p && *p) error ("Unexpected extra arguments following breakpoint number."); @@ -2070,9 +2069,9 @@ print_it_typical (bs) /* Fall through, we don't deal with these types of breakpoints here. */ + case bp_finish: case bp_none: case bp_until: - case bp_finish: case bp_longjmp: case bp_longjmp_resume: case bp_step_resume: @@ -2116,7 +2115,6 @@ print_bp_stop_message (bpstat bs) } } - /* Print a message indicating what happened. This is called from normal_stop(). The input to this routine is the head of the bpstat list - a list of the eventpoints that caused this stop. This @@ -6610,12 +6608,14 @@ map_breakpoint_numbers (args, function) char *p1; register int num; register struct breakpoint *b, *tmp; + int match; if (p == 0) error_no_arg ("one or more breakpoint numbers"); while (*p) { + match = 0; p1 = p; num = get_number_or_range (&p1); @@ -6629,13 +6629,14 @@ map_breakpoint_numbers (args, function) if (b->number == num) { struct breakpoint *related_breakpoint = b->related_breakpoint; + match = 1; function (b); if (related_breakpoint) function (related_breakpoint); - goto win; + break; } - printf_unfiltered ("No breakpoint number %d.\n", num); - win: + if (match == 0) + printf_unfiltered ("No breakpoint number %d.\n", num); } p = p1; } diff --git a/gdb/config/i386/nm-i386sol2.h b/gdb/config/i386/nm-i386sol2.h index 05ab0663c0f..8ccc9107001 100644 --- a/gdb/config/i386/nm-i386sol2.h +++ b/gdb/config/i386/nm-i386sol2.h @@ -20,12 +20,3 @@ #include "nm-sysv4.h" -#ifdef HAVE_THREAD_DB_LIB - -struct objfile; - -#define target_new_objfile(OBJFILE) sol_thread_new_objfile (OBJFILE) - -void sol_thread_new_objfile PARAMS ((struct objfile * objfile)); - -#endif diff --git a/gdb/config/i386/nm-linux.h b/gdb/config/i386/nm-linux.h index df964f44d48..1ce0a3082ff 100644 --- a/gdb/config/i386/nm-linux.h +++ b/gdb/config/i386/nm-linux.h @@ -76,14 +76,6 @@ i386_remove_watchpoint PARAMS ((int pid, CORE_ADDR addr, int len)); /* Support for the glibc linuxthreads package. */ -#ifdef __STDC__ -struct objfile; -#endif - -extern void -linuxthreads_new_objfile PARAMS ((struct objfile *objfile)); -#define target_new_objfile(OBJFILE) linuxthreads_new_objfile (OBJFILE) - extern char * linuxthreads_pid_to_str PARAMS ((int pid)); #define target_pid_to_str(PID) linuxthreads_pid_to_str (PID) diff --git a/gdb/config/i960/tm-nindy960.h b/gdb/config/i960/tm-nindy960.h index 7a20af3db5a..d57a6974c38 100644 --- a/gdb/config/i960/tm-nindy960.h +++ b/gdb/config/i960/tm-nindy960.h @@ -60,13 +60,18 @@ extern char *nindy_ttyname; /* Name of serial port to talk to nindy */ /* If specified on the command line, open tty for talking to nindy, and download the executable file if one was specified. */ -#define ADDITIONAL_OPTION_HANDLER \ - if (!SET_TOP_LEVEL () && nindy_ttyname) { \ - nindy_open (nindy_ttyname, !batch); \ - if (!SET_TOP_LEVEL () && execarg) { \ - target_load (execarg, !batch); \ - } \ - } +extern void nindy_open (char *name, int from_tty); +#define ADDITIONAL_OPTION_HANDLER \ + if (nindy_ttyname != NULL) \ + { \ + if (catch_command_errors (nindy_open, nindy_ttyname, \ + !batch, RETURN_MASK_ALL)) \ + { \ + if (execarg != NULL) \ + catch_command_errors (target_load, execarg, !batch, \ + RETURN_MASK_ALL); \ + } \ + } /* If configured for i960 target, we take control before main loop and demand that we configure for a nindy target. */ diff --git a/gdb/config/mcore/tm-mcore.h b/gdb/config/mcore/tm-mcore.h index 69329b419f2..ddf5d90f03b 100644 --- a/gdb/config/mcore/tm-mcore.h +++ b/gdb/config/mcore/tm-mcore.h @@ -18,8 +18,8 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* The mcore is big endian */ -#define TARGET_BYTE_ORDER_DEFAULT BIG_ENDIAN +/* The mcore is little endian (by default) */ +#define TARGET_BYTE_ORDER_DEFAULT LITTLE_ENDIAN /* All registers are 32 bits */ #define REGISTER_SIZE 4 diff --git a/gdb/config/pa/nm-hppah.h b/gdb/config/pa/nm-hppah.h index 269593f0b8a..7b277d12246 100644 --- a/gdb/config/pa/nm-hppah.h +++ b/gdb/config/pa/nm-hppah.h @@ -279,11 +279,6 @@ extern int hppa_resume_execd_vforking_child_to_get_parent_vfork PARAMS ((void)); #ifdef HAVE_HPUX_THREAD_SUPPORT -struct objfile; - -void hpux_thread_new_objfile PARAMS ((struct objfile * objfile)); -#define target_new_objfile(OBJFILE) hpux_thread_new_objfile (OBJFILE) - extern char *hpux_pid_to_str PARAMS ((int pid)); #define target_pid_to_str(PID) hpux_pid_to_str (PID) diff --git a/gdb/config/sparc/nm-sun4sol2.h b/gdb/config/sparc/nm-sun4sol2.h index 8baf8935d2d..6e9e74fbf26 100644 --- a/gdb/config/sparc/nm-sun4sol2.h +++ b/gdb/config/sparc/nm-sun4sol2.h @@ -30,12 +30,3 @@ #define PRSVADDR_BROKEN -#ifdef HAVE_THREAD_DB_LIB - -struct objfile; - -#define target_new_objfile(OBJFILE) sol_thread_new_objfile (OBJFILE) - -void sol_thread_new_objfile PARAMS ((struct objfile * objfile)); - -#endif diff --git a/gdb/corefile.c b/gdb/corefile.c index 7f94c3d0987..3a5ef9aa340 100644 --- a/gdb/corefile.c +++ b/gdb/corefile.c @@ -237,7 +237,7 @@ memory_error (status, memaddr) CORE_ADDR memaddr; { GDB_FILE *tmp_stream = tui_sfileopen (130); - make_cleanup ((make_cleanup_func) gdb_file_deallocate, &tmp_stream); + make_cleanup_gdb_file_delete (tmp_stream); error_begin (); diff --git a/gdb/d10v-tdep.c b/gdb/d10v-tdep.c index fa8b080e84d..aecbea5edc5 100644 --- a/gdb/d10v-tdep.c +++ b/gdb/d10v-tdep.c @@ -1312,7 +1312,7 @@ print_insn (memaddr, stream) { /* If there's no disassembler, something is very wrong. */ if (tm_print_insn == NULL) - abort (); + internal_error ("print_insn: no disassembler"); if (TARGET_BYTE_ORDER == BIG_ENDIAN) tm_print_insn_info.endian = BFD_ENDIAN_BIG; diff --git a/gdb/d30v-tdep.c b/gdb/d30v-tdep.c index d66fefbbe11..00e0c025c92 100644 --- a/gdb/d30v-tdep.c +++ b/gdb/d30v-tdep.c @@ -1187,7 +1187,7 @@ print_insn (memaddr, stream) { /* If there's no disassembler, something is very wrong. */ if (tm_print_insn == NULL) - abort (); + internal_error ("print_insn: no disassembler"); if (TARGET_BYTE_ORDER == BIG_ENDIAN) tm_print_insn_info.endian = BFD_ENDIAN_BIG; diff --git a/gdb/defs.h b/gdb/defs.h index fb0eb7a5ccb..39142bb463b 100644 --- a/gdb/defs.h +++ b/gdb/defs.h @@ -299,6 +299,9 @@ extern struct cleanup *make_cleanup (make_cleanup_func, void *); extern struct cleanup *make_cleanup_freeargv (char **); +struct gdb_file; +extern struct cleanup *make_cleanup_gdb_file_delete (struct gdb_file *); + extern struct cleanup *make_final_cleanup (make_cleanup_func, void *); extern struct cleanup *make_my_cleanup (struct cleanup **, @@ -392,6 +395,11 @@ extern struct gdb_file *gdb_file_new (void); typedef void (gdb_file_flush_ftype) (struct gdb_file * stream); extern void set_gdb_file_flush (struct gdb_file *stream, gdb_file_flush_ftype * flush); +/* NOTE: Both fputs and write methods are available. Default + implementations that mapping one onto the other are included. */ +typedef void (gdb_file_write_ftype) (struct gdb_file * stream, const char *buf, long length_buf); +extern void set_gdb_file_write (struct gdb_file *stream, gdb_file_write_ftype *fputs); + typedef void (gdb_file_fputs_ftype) (const char *, struct gdb_file * stream); extern void set_gdb_file_fputs (struct gdb_file *stream, gdb_file_fputs_ftype * fputs); @@ -428,6 +436,8 @@ extern void gdb_file_rewind (struct gdb_file *stream); extern int gdb_file_isatty (GDB_FILE *); +extern void gdb_file_write (struct gdb_file *file, const char *buf, long length_buf); + /* NOTE: copies left to right */ extern void gdb_file_put (struct gdb_file *src, struct gdb_file *dest); @@ -471,13 +481,10 @@ extern void printf_unfiltered (const char *, ...) ATTR_FORMAT (printf, 1, 2); /* #if defined (TUI) */ /* DEPRECATED: Only the TUI should use these methods. */ -extern GDB_FILE *gdb_file_init_astring (int); extern struct gdb_file *tui_fileopen (FILE *); extern struct gdb_file *tui_sfileopen (int); -extern void gdb_fclose (GDB_FILE **); -extern void gdb_file_deallocate (GDB_FILE **); -extern char *gdb_file_get_strbuf (GDB_FILE *); -extern void gdb_file_adjust_strbuf (int, GDB_FILE *); +extern char *tui_file_get_strbuf (struct gdb_file *); +extern void tui_file_adjust_strbuf (int, struct gdb_file *); /* #endif */ extern void print_spaces (int, GDB_FILE *); @@ -847,9 +854,22 @@ typedef int return_mask; extern NORETURN void return_to_top_level (enum return_reason) ATTR_NORETURN; +/* If CATCH_ERRORS_FTYPE throws an error, catch_errors() returns zero + otherwize the result from CATCH_ERRORS_FTYPE is returned. It is + probably useful for CATCH_ERRORS_FTYPE to always return a non-zero + value. It's unfortunate that, catch_errors() does not return an + indication of the exact exception that it caught - quit_flag might + help. */ + typedef int (catch_errors_ftype) (PTR); extern int catch_errors (catch_errors_ftype *, PTR, char *, return_mask); +/* Template to catch_errors() that wraps calls to command + functions. */ + +typedef void (catch_command_errors_ftype) (char *, int); +extern int catch_command_errors (catch_command_errors_ftype *func, char *command, int from_tty, return_mask); + extern void warning_begin (void); extern void warning (const char *, ...) ATTR_FORMAT (printf, 1, 2); diff --git a/gdb/doc/ChangeLog b/gdb/doc/ChangeLog index cfb80b494df..45e1cdbe262 100644 --- a/gdb/doc/ChangeLog +++ b/gdb/doc/ChangeLog @@ -1,3 +1,7 @@ +1999-11-05 Stan Shebs + + * gdb.texinfo: Clarify regular expressions used in rbreak. + 1999-10-15 Kevin Buettner * gdbint.texinfo (MEMORY_INSERT_BREAKPOINT, diff --git a/gdb/doc/gdb.texinfo b/gdb/doc/gdb.texinfo index 316d58c3142..b4ad4e3afc1 100644 --- a/gdb/doc/gdb.texinfo +++ b/gdb/doc/gdb.texinfo @@ -2229,14 +2229,19 @@ See also @ref{Conditions, ,Break conditions}. @kindex rbreak @cindex regular expression @item rbreak @var{regex} -@c FIXME what kind of regexp? Set breakpoints on all functions matching the regular expression -@var{regex}. This command -sets an unconditional breakpoint on all matches, printing a list of all -breakpoints it set. Once these breakpoints are set, they are treated -just like the breakpoints set with the @code{break} command. You can -delete them, disable them, or make them conditional the same way as any -other breakpoint. +@var{regex}. This command sets an unconditional breakpoint on all +matches, printing a list of all breakpoints it set. Once these +breakpoints are set, they are treated just like the breakpoints set with +the @code{break} command. You can delete them, disable them, or make +them conditional the same way as any other breakpoint. + +The syntax of the regular expression is the standard one used with tools +like @file{grep}. Note that this is different from the syntax used by +shells, so for instance @code{foo*} matches all functions that include +an @code{fo} followed by zero or more @code{o}s. There is an implicit +@code{.*} leading and trailing the regular expression you supply, so to +match only functions that begin with @code{foo}, use @code{^foo}. When debugging C++ programs, @code{rbreak} is useful for setting breakpoints on overloaded functions that are not members of any special diff --git a/gdb/elfread.c b/gdb/elfread.c index afb043de1f1..d63d16a30fa 100644 --- a/gdb/elfread.c +++ b/gdb/elfread.c @@ -375,7 +375,7 @@ elf_symtab_read (objfile, dynamic) if (sym->section == &bfd_abs_section) { /* This is a hack to get the minimal symbol type - right for Irix 5, which has absolute adresses + right for Irix 5, which has absolute addresses with special section indices for dynamic symbols. */ unsigned short shndx = ((elf_symbol_type *) sym)->internal_elf_sym.st_shndx; diff --git a/gdb/event-loop.c b/gdb/event-loop.c index c3bbf01ec14..7e3e02c890c 100644 --- a/gdb/event-loop.c +++ b/gdb/event-loop.c @@ -256,7 +256,7 @@ static void create_file_handler (int fd, int mask, handler_func * proc, gdb_clie static void invoke_async_signal_handler (void); static void handle_file_event (int event_file_desc); static int gdb_wait_for_event (void); -static int gdb_do_one_event (void); +static int gdb_do_one_event (void *data); static int check_async_ready (void); static void async_queue_event (gdb_event * event_ptr, queue_position position); static gdb_event *create_file_event (int fd); @@ -388,52 +388,61 @@ process_event (void) /* Process one high level event. If nothing is ready at this time, wait for something to happen (via gdb_wait_for_event), then process - it. Returns 1 if something was done otherwise returns 0 (this can - happen if there are no event sources to wait for). */ + it. Returns >0 if something was done otherwise returns <0 (this + can happen if there are no event sources to wait for). If an error + occures catch_errors() which calls this function returns zero. */ + static int -gdb_do_one_event (void) +gdb_do_one_event (void *data) { - int result = 0; - - while (1) + /* Any events already waiting in the queue? */ + if (process_event ()) { - if (!SET_TOP_LEVEL ()) - { - /* Any events already waiting in the queue? */ - if (process_event ()) - { - result = 1; - break; - } - - /* Are any timers that are ready? If so, put an event on the queue. */ - poll_timers (); - - /* Wait for a new event. If gdb_wait_for_event returns -1, - we should get out because this means that there are no - event sources left. This will make the event loop stop, - and the application exit. */ - - result = gdb_wait_for_event (); - if (result < 0) - { - result = 0; - break; - } + return 1; + } + + /* Are any timers that are ready? If so, put an event on the queue. */ + poll_timers (); + + /* Wait for a new event. If gdb_wait_for_event returns -1, + we should get out because this means that there are no + event sources left. This will make the event loop stop, + and the application exit. */ + + if (gdb_wait_for_event () < 0) + { + return -1; + } + + /* Handle any new events occurred while waiting. */ + if (process_event ()) + { + return 1; + } + + /* If gdb_wait_for_event has returned 1, it means that one + event has been handled. We break out of the loop. */ + return 1; +} - /* Handle any new events occurred while waiting. */ - if (process_event ()) - { - result = 1; - break; - } +/* Start up the event loop. This is the entry point to the event loop + from the command loop. */ - /* If gdb_wait_for_event has returned 1, it means that one - event has been handled. We break out of the loop. */ - if (result) - break; - } /* end of if !set_top_level */ - else +void +start_event_loop (void) +{ + /* Loop until there is nothing to do. This is the entry point to the + event loop engine. gdb_do_one_event, called via catch_errors() + will process one event for each invocation. It blocks waits for + an event and then processes it. >0 when an event is processed, 0 + when catch_errors() caught an error and <0 when there are no + longer any event sources registered. */ + while (1) + { + int result = catch_errors (gdb_do_one_event, 0, "", RETURN_MASK_ALL); + if (result < 0) + break; + if (result == 0) { /* FIXME: this should really be a call to a hook that is interface specific, because interfaces can display the @@ -443,21 +452,6 @@ gdb_do_one_event (void) whether display the prompt or not. */ } } - return result; -} - - -/* Start up the event loop. This is the entry point to the event loop - from the command loop. */ -void -start_event_loop (void) -{ - /* Loop until there is something to do. This is the entry point to - the event loop engine. gdb_do_one_event will process one event - for each invocation. It always returns 1, unless there are no - more event sources registered. In this case it returns 0. */ - while (gdb_do_one_event () != 0) - ; /* We are done with the event loop. There are no more event sources to listen to. So we exit GDB. */ diff --git a/gdb/gdbserver/low-linux.c b/gdb/gdbserver/low-linux.c index b17e7558e42..b9573b34e14 100644 --- a/gdb/gdbserver/low-linux.c +++ b/gdb/gdbserver/low-linux.c @@ -492,7 +492,7 @@ static int u_offsets[] = -1, /* Not available: ITC */ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - PT_AR_PFS, + PT_CR_IFS, /* was PT_AR_PFS, but it seemed bogus */ PT_AR_LC, -1, /* Not available: EC, the Epilog Count register */ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, diff --git a/gdb/hpux-thread.c b/gdb/hpux-thread.c index 8d70bd8e5d9..28a8d2de9da 100644 --- a/gdb/hpux-thread.c +++ b/gdb/hpux-thread.c @@ -520,6 +520,13 @@ hpux_thread_create_inferior (exec_file, allargs, env) those variables don't show up until the library gets mapped and the symbol table is read in. */ +/* This new_objfile event is now managed by a chained function pointer. + * It is the callee's responsability to call the next client on the chain. + */ + +/* Saved pointer to previous owner of the new_objfile event. */ +static void (*target_new_objfile_chain) PARAMS ((struct objfile *)); + void hpux_thread_new_objfile (objfile) struct objfile *objfile; @@ -529,25 +536,28 @@ hpux_thread_new_objfile (objfile) if (!objfile) { hpux_thread_active = 0; - - return; + goto quit; } ms = lookup_minimal_symbol ("cma__g_known_threads", NULL, objfile); if (!ms) - return; + goto quit; P_cma__g_known_threads = SYMBOL_VALUE_ADDRESS (ms); ms = lookup_minimal_symbol ("cma__g_current_thread", NULL, objfile); if (!ms) - return; + goto quit; P_cma__g_current_thread = SYMBOL_VALUE_ADDRESS (ms); hpux_thread_active = 1; +quit: + /* Call predecessor on chain, if any. */ + if (target_new_objfile_chain) + target_new_objfile_chain (objfile); } /* Clean up after the inferior dies. */ @@ -638,4 +648,7 @@ _initialize_hpux_thread () add_target (&hpux_thread_ops); child_suppress_run = 1; + /* Hook into new_objfile notification. */ + target_new_objfile_chain = target_new_objfile_hook; + target_new_objfile_hook = hpux_thread_new_objfile; } diff --git a/gdb/i386-linux-nat.c b/gdb/i386-linux-nat.c index 65731533271..15debfcfb59 100644 --- a/gdb/i386-linux-nat.c +++ b/gdb/i386-linux-nat.c @@ -325,6 +325,13 @@ store_fpregs () /* Transfering floating-point and SSE registers to and from GDB. */ +/* PTRACE_GETXFPREGS is a Cygnus invention, since we wrote our own + Linux kernel patch for SSE support. That patch may or may not + actually make it into the official distribution. If you find that + years have gone by since this code was added, and Linux isn't using + PTRACE_GETXFPREGS, that means that our patch didn't make it, and + you can delete this code. */ + #ifdef HAVE_PTRACE_GETXFPREGS static void supply_xfpregset (struct user_xfpregs_struct *xfpregs) diff --git a/gdb/infcmd.c b/gdb/infcmd.c index 6a55a362b2f..ac093ed09e5 100644 --- a/gdb/infcmd.c +++ b/gdb/infcmd.c @@ -49,6 +49,8 @@ void registers_info PARAMS ((char *, int)); void continue_command PARAMS ((char *, int)); +static void print_return_value (int struct_return, struct type *value_type); + static void finish_command_continuation PARAMS ((struct continuation_arg *)); static void until_next_command PARAMS ((int)); @@ -869,6 +871,37 @@ until_command (arg, from_tty) } +/* Print the result of a function at the end of a 'finish' command. */ +static void +print_return_value (int structure_return, struct type *value_type) +{ + register value_ptr value; + + if (!structure_return) + { + value = value_being_returned (value_type, stop_registers, structure_return); + printf_filtered ("Value returned is $%d = ", record_latest_value (value)); + value_print (value, gdb_stdout, 0, Val_no_prettyprint); + printf_filtered ("\n"); + } + else + { + /* We cannot determine the contents of the structure because + it is on the stack, and we don't know where, since we did not + initiate the call, as opposed to the call_function_by_hand case */ +#ifdef VALUE_RETURNED_FROM_STACK + value = 0; + printf_filtered ("Value returned has type: %s.", TYPE_NAME (value_type)); + printf_filtered (" Cannot determine contents\n"); +#else + value = value_being_returned (value_type, stop_registers, structure_return); + printf_filtered ("Value returned is $%d = ", record_latest_value (value)); + value_print (value, gdb_stdout, 0, Val_no_prettyprint); + printf_filtered ("\n"); +#endif + } +} + /* Stuff that needs to be done by the finish command after the target has stopped. In asynchronous mode, we wait for the target to stop in the call to poll or select in the event loop, so it is impossible to @@ -891,7 +924,6 @@ finish_command_continuation (arg) && function != 0) { struct type *value_type; - register value_ptr val; CORE_ADDR funcaddr; int struct_return; @@ -908,38 +940,11 @@ finish_command_continuation (arg) funcaddr = BLOCK_START (SYMBOL_BLOCK_VALUE (function)); struct_return = using_struct_return (value_of_variable (function, NULL), - funcaddr, check_typedef (value_type), - BLOCK_GCC_COMPILED (SYMBOL_BLOCK_VALUE (function))); + BLOCK_GCC_COMPILED (SYMBOL_BLOCK_VALUE (function))); - if (!struct_return) - { - val = value_being_returned (value_type, stop_registers, struct_return); - printf_filtered ("Value returned is $%d = ", record_latest_value (val)); - value_print (val, gdb_stdout, 0, Val_no_prettyprint); - printf_filtered ("\n"); - } - else - { - /* We cannot determine the contents of the structure because - it is on the stack, and we don't know where, since we did not - initiate the call, as opposed to the call_function_by_hand case */ -#ifdef VALUE_RETURNED_FROM_STACK - val = 0; - printf_filtered ("Value returned has type: %s.", - TYPE_NAME (value_type)); - printf_filtered (" Cannot determine contents\n"); -#else - val = value_being_returned (value_type, stop_registers, - struct_return); - printf_filtered ("Value returned is $%d = ", - record_latest_value (val)); - value_print (val, gdb_stdout, 0, Val_no_prettyprint); - printf_filtered ("\n"); -#endif - - } + print_return_value (struct_return, value_type); } do_exec_cleanups (ALL_CLEANUPS); } @@ -1044,7 +1049,6 @@ finish_command (arg, from_tty) && function != 0) { struct type *value_type; - register value_ptr val; CORE_ADDR funcaddr; int struct_return; @@ -1064,35 +1068,7 @@ finish_command (arg, from_tty) check_typedef (value_type), BLOCK_GCC_COMPILED (SYMBOL_BLOCK_VALUE (function))); - if (!struct_return) - { - val = - value_being_returned (value_type, stop_registers, struct_return); - printf_filtered ("Value returned is $%d = ", - record_latest_value (val)); - value_print (val, gdb_stdout, 0, Val_no_prettyprint); - printf_filtered ("\n"); - } - else - { - /* We cannot determine the contents of the structure - because it is on the stack, and we don't know - where, since we did not initiate the call, as - opposed to the call_function_by_hand case */ -#ifdef VALUE_RETURNED_FROM_STACK - val = 0; - printf_filtered ("Value returned has type: %s.", - TYPE_NAME (value_type)); - printf_filtered (" Cannot determine contents\n"); -#else - val = value_being_returned (value_type, stop_registers, - struct_return); - printf_filtered ("Value returned is $%d = ", - record_latest_value (val)); - value_print (val, gdb_stdout, 0, Val_no_prettyprint); - printf_filtered ("\n"); -#endif - } + print_return_value (struct_return, value_type); } do_cleanups (old_chain); } diff --git a/gdb/inferior.h b/gdb/inferior.h index b0a6fa62c02..38c9ed62544 100644 --- a/gdb/inferior.h +++ b/gdb/inferior.h @@ -395,20 +395,20 @@ extern int attach_flag; #endif /* No CALL_DUMMY_LOCATION. */ #if !defined (CALL_DUMMY_ADDRESS) -#define CALL_DUMMY_ADDRESS() (abort (), 0) /* anything to abort GDB */ +#define CALL_DUMMY_ADDRESS() (internal_error ("CALL_DUMMY_ADDRESS"), 0) #endif #if !defined (CALL_DUMMY_START_OFFSET) -#define CALL_DUMMY_START_OFFSET (abort (), 0) /* anything to abort GDB */ +#define CALL_DUMMY_START_OFFSET (internal_error ("CALL_DUMMY_START_OFFSET"), 0) #endif #if !defined (CALL_DUMMY_BREAKPOINT_OFFSET) #define CALL_DUMMY_BREAKPOINT_OFFSET_P (0) -#define CALL_DUMMY_BREAKPOINT_OFFSET (abort (), 0) /* anything to abort GDB */ +#define CALL_DUMMY_BREAKPOINT_OFFSET (internal_error ("CALL_DUMMY_BREAKPOINT_OFFSET"), 0) #endif #if !defined CALL_DUMMY_BREAKPOINT_OFFSET_P #define CALL_DUMMY_BREAKPOINT_OFFSET_P (1) #endif #if !defined (CALL_DUMMY_LENGTH) -#define CALL_DUMMY_LENGTH (abort (), 0) /* anything to abort GDB */ +#define CALL_DUMMY_LENGTH (internal_error ("CALL_DUMMY_LENGTH"), 0) #endif #if defined (CALL_DUMMY_STACK_ADJUST) @@ -417,7 +417,7 @@ extern int attach_flag; #endif #endif #if !defined (CALL_DUMMY_STACK_ADJUST) -#define CALL_DUMMY_STACK_ADJUST (abort (), 0) +#define CALL_DUMMY_STACK_ADJUST (internal_error ("CALL_DUMMY_STACK_ADJUST"), 0) #endif #if !defined (CALL_DUMMY_STACK_ADJUST_P) #define CALL_DUMMY_STACK_ADJUST_P (0) @@ -436,7 +436,7 @@ extern int attach_flag; extern LONGEST call_dummy_words[]; #define CALL_DUMMY_WORDS (call_dummy_words) #else -#define CALL_DUMMY_WORDS (abort (), (void*) 0) /* anything to abort GDB */ +#define CALL_DUMMY_WORDS (internal_error ("CALL_DUMMY_WORDS"), (void*) 0) #endif #endif @@ -445,20 +445,20 @@ extern LONGEST call_dummy_words[]; extern int sizeof_call_dummy_words; #define SIZEOF_CALL_DUMMY_WORDS (sizeof_call_dummy_words) #else -#define SIZEOF_CALL_DUMMY_WORDS (abort (), 0) /* anything to abort GDB */ +#define SIZEOF_CALL_DUMMY_WORDS (internal_error ("SIZEOF_CALL_DUMMY_WORDS"), 0) #endif #endif #if !defined PUSH_DUMMY_FRAME -#define PUSH_DUMMY_FRAME (abort ()) +#define PUSH_DUMMY_FRAME (internal_error ("PUSH_DUMMY_FRAME"), 0) #endif #if !defined FIX_CALL_DUMMY -#define FIX_CALL_DUMMY(a1,a2,a3,a4,a5,a6,a7) (abort ()) +#define FIX_CALL_DUMMY(a1,a2,a3,a4,a5,a6,a7) (internal_error ("FIX_CALL_DUMMY"), 0) #endif #if !defined STORE_STRUCT_RETURN -#define STORE_STRUCT_RETURN(a1,a2) (abort ()) +#define STORE_STRUCT_RETURN(a1,a2) (internal_error ("STORE_STRUCT_RETURN"), 0) #endif diff --git a/gdb/infrun.c b/gdb/infrun.c index 527bb2ddbb6..c00da0a882b 100644 --- a/gdb/infrun.c +++ b/gdb/infrun.c @@ -1160,6 +1160,24 @@ enum infwait_states infwait_nonstep_watch_state }; +/* Why did the inferior stop? Used to print the appropriate messages + to the interface from within handle_inferior_event(). */ +enum inferior_stop_reason +{ + /* We don't know why. */ + STOP_UNKNOWN, + /* Step, next, nexti, stepi finished. */ + END_STEPPING_RANGE, + /* Found breakpoint. */ + BREAKPOINT_HIT, + /* Inferior terminated by signal. */ + SIGNAL_EXITED, + /* Inferior exited. */ + EXITED, + /* Inferior received signal, and user asked to be notified. */ + SIGNAL_RECEIVED +}; + /* 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. */ @@ -1202,6 +1220,7 @@ static void step_over_function (struct execution_control_state *ecs); static void stop_stepping (struct execution_control_state *ecs); static void prepare_to_wait (struct execution_control_state *ecs); static void keep_going (struct execution_control_state *ecs); +static void print_stop_reason (enum inferior_stop_reason stop_reason, int stop_info); /* Wait for control to return from inferior to debugger. If inferior gets a signal, we may decide to start it up again @@ -1499,12 +1518,7 @@ handle_inferior_event (struct execution_control_state *ecs) case TARGET_WAITKIND_EXITED: target_terminal_ours (); /* Must do this before mourn anyway */ - annotate_exited (ecs->ws.value.integer); - if (ecs->ws.value.integer) - printf_filtered ("\nProgram exited with code 0%o.\n", - (unsigned int) ecs->ws.value.integer); - else - printf_filtered ("\nProgram exited normally.\n"); + print_stop_reason (EXITED, ecs->ws.value.integer); /* Record the exit code in the convenience variable $_exitcode, so that the user can inspect this again later. */ @@ -1522,7 +1536,6 @@ handle_inferior_event (struct execution_control_state *ecs) stop_print_frame = 0; stop_signal = ecs->ws.value.sig; target_terminal_ours (); /* Must do this before mourn anyway */ - annotate_signalled (); /* This looks pretty bogus to me. Doesn't TARGET_WAITKIND_SIGNALLED mean it is already dead? This has been here since GDB 2.8, so @@ -1531,18 +1544,7 @@ handle_inferior_event (struct execution_control_state *ecs) rather than trying to change it here --kingdon, 5 Dec 1994. */ target_kill (); /* kill mourns as well */ - printf_filtered ("\nProgram terminated with signal "); - annotate_signal_name (); - printf_filtered ("%s", target_signal_to_name (stop_signal)); - annotate_signal_name_end (); - printf_filtered (", "); - annotate_signal_string (); - printf_filtered ("%s", target_signal_to_string (stop_signal)); - annotate_signal_string_end (); - printf_filtered (".\n"); - - printf_filtered ("The program no longer exists.\n"); - gdb_flush (gdb_stdout); + print_stop_reason (SIGNAL_EXITED, stop_signal); singlestep_breakpoints_inserted_p = 0; /*SOFTWARE_SINGLE_STEP_P */ stop_stepping (ecs); return; @@ -2182,17 +2184,7 @@ handle_inferior_event (struct execution_control_state *ecs) { printed = 1; target_terminal_ours_for_output (); - annotate_signal (); - printf_filtered ("\nProgram received signal "); - annotate_signal_name (); - printf_filtered ("%s", target_signal_to_name (stop_signal)); - annotate_signal_name_end (); - printf_filtered (", "); - annotate_signal_string (); - printf_filtered ("%s", target_signal_to_string (stop_signal)); - annotate_signal_string_end (); - printf_filtered (".\n"); - gdb_flush (gdb_stdout); + print_stop_reason (SIGNAL_RECEIVED, stop_signal); } if (signal_stop[stop_signal]) { @@ -2704,6 +2696,7 @@ handle_inferior_event (struct execution_control_state *ecs) supposed to be stepping at the assembly language level ("stepi"). Just stop. */ stop_step = 1; + print_stop_reason (END_STEPPING_RANGE, 0); stop_stepping (ecs); return; } @@ -2775,6 +2768,7 @@ handle_inferior_event (struct execution_control_state *ecs) /* It is stepi or nexti. We always want to stop stepping after one instruction. */ stop_step = 1; + print_stop_reason (END_STEPPING_RANGE, 0); stop_stepping (ecs); return; } @@ -2820,6 +2814,7 @@ handle_inferior_event (struct execution_control_state *ecs) 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; + print_stop_reason (END_STEPPING_RANGE, 0); stop_stepping (ecs); return; } @@ -2832,6 +2827,7 @@ handle_inferior_event (struct execution_control_state *ecs) That is said to make things like for (;;) statements work better. */ stop_step = 1; + print_stop_reason (END_STEPPING_RANGE, 0); stop_stepping (ecs); return; } @@ -2851,6 +2847,7 @@ handle_inferior_event (struct execution_control_state *ecs) in which after skipping the prologue we better stop even though we will be in mid-line. */ stop_step = 1; + print_stop_reason (END_STEPPING_RANGE, 0); stop_stepping (ecs); return; } @@ -2957,6 +2954,7 @@ step_into_function (struct execution_control_state *ecs) { /* We are already there: stop now. */ stop_step = 1; + print_stop_reason (END_STEPPING_RANGE, 0); stop_stepping (ecs); return; } @@ -3192,6 +3190,74 @@ prepare_to_wait (struct execution_control_state *ecs) soon. */ ecs->wait_some_more = 1; } + +/* Print why the inferior has stopped. We always print something when + the inferior exits, or receives a signal. The rest of the cases are + dealt with later on in normal_stop() and print_it_typical(). Ideally + there should be a call to this function from handle_inferior_event() + each time stop_stepping() is called.*/ +static void +print_stop_reason (enum inferior_stop_reason stop_reason, int stop_info) +{ + switch (stop_reason) + { + case STOP_UNKNOWN: + /* We don't deal with these cases from handle_inferior_event() + yet. */ + break; + case END_STEPPING_RANGE: + /* We are done with a step/next/si/ni command. */ + /* For now print nothing. */ + break; + case BREAKPOINT_HIT: + /* We found a breakpoint. */ + /* For now print nothing. */ + break; + case SIGNAL_EXITED: + /* The inferior was terminated by a signal. */ + annotate_signalled (); + printf_filtered ("\nProgram terminated with signal "); + annotate_signal_name (); + printf_filtered ("%s", target_signal_to_name (stop_info)); + annotate_signal_name_end (); + printf_filtered (", "); + annotate_signal_string (); + printf_filtered ("%s", target_signal_to_string (stop_info)); + annotate_signal_string_end (); + printf_filtered (".\n"); + + printf_filtered ("The program no longer exists.\n"); + gdb_flush (gdb_stdout); + break; + case EXITED: + /* The inferior program is finished. */ + annotate_exited (stop_info); + if (stop_info) + printf_filtered ("\nProgram exited with code 0%o.\n", + (unsigned int) stop_info); + else + printf_filtered ("\nProgram exited normally.\n"); + break; + case SIGNAL_RECEIVED: + /* Signal received. The signal table tells us to print about + it. */ + annotate_signal (); + printf_filtered ("\nProgram received signal "); + annotate_signal_name (); + printf_filtered ("%s", target_signal_to_name (stop_info)); + annotate_signal_name_end (); + printf_filtered (", "); + annotate_signal_string (); + printf_filtered ("%s", target_signal_to_string (stop_info)); + annotate_signal_string_end (); + printf_filtered (".\n"); + gdb_flush (gdb_stdout); + break; + default: + internal_error ("print_stop_reason: unrecognized enum value"); + break; + } +} /* Here to return control to GDB when the inferior stops for real. diff --git a/gdb/kod.c b/gdb/kod.c index cbe093fd419..e9b5ebc0890 100644 --- a/gdb/kod.c +++ b/gdb/kod.c @@ -31,7 +31,6 @@ void _initialize_kod (void); /* Prototypes for local functions. */ -static void show_kod (char *, int); static void info_kod_command (char *, int); static void load_kod_library (char *); diff --git a/gdb/linux-thread.c b/gdb/linux-thread.c index 26e45e04693..de5cdd74a04 100644 --- a/gdb/linux-thread.c +++ b/gdb/linux-thread.c @@ -831,11 +831,19 @@ update_stop_threads (test_pid) do_cleanups (old_chain); } -/* This routine is called whenever a new symbol table is read in, or when all - symbol tables are removed. libpthread can only be initialized when it - finds the right variables in libpthread.so. Since it's a shared library, - those variables don't show up until the library gets mapped and the symbol - table is read in. */ +/* This routine is called whenever a new symbol table is read in, or + when all symbol tables are removed. linux-thread event handling + can only be initialized when we find the right variables in + libpthread.so. Since it's a shared library, those variables don't + show up until the library gets mapped and the symbol table is read + in. */ + +/* This new_objfile event is now managed by a chained function pointer. + * It is the callee's responsability to call the next client on the chain. + */ + +/* Saved pointer to previous owner of the new_objfile event. */ +static void (*target_new_objfile_chain) PARAMS ((struct objfile *)); void linuxthreads_new_objfile (objfile) @@ -853,17 +861,17 @@ linuxthreads_new_objfile (objfile) /* Indicate that we don't know anything's address any more. */ linuxthreads_max = 0; - return; + goto quit; } /* If we've already found our variables in another objfile, don't bother looking for them again. */ if (linuxthreads_max) - return; + goto quit; if (! lookup_minimal_symbol ("__pthread_initial_thread", NULL, objfile)) /* This object file isn't the pthreads library. */ - return; + goto quit; if ((ms = lookup_minimal_symbol ("__pthread_threads_debug", NULL, objfile)) == NULL) @@ -874,7 +882,7 @@ This program seems to use POSIX threads, but the thread library used\n\ does not support debugging. This may make using GDB difficult. Don't\n\ set breakpoints or single-step through code that might be executed by\n\ any thread other than the main thread."); - return; + goto quit; } linuxthreads_debug = SYMBOL_VALUE_ADDRESS (ms); @@ -888,7 +896,7 @@ any thread other than the main thread."); fprintf_unfiltered (gdb_stderr, "Unable to find linuxthreads symbol \"%s\"\n", "__pthread_sizeof_handle"); - return; + goto quit; } if ((ms = lookup_minimal_symbol ("__pthread_offsetof_descr", @@ -900,7 +908,7 @@ any thread other than the main thread."); fprintf_unfiltered (gdb_stderr, "Unable to find linuxthreads symbol \"%s\"\n", "__pthread_offsetof_descr"); - return; + goto quit; } if ((ms = lookup_minimal_symbol ("__pthread_offsetof_pid", @@ -912,11 +920,11 @@ any thread other than the main thread."); fprintf_unfiltered (gdb_stderr, "Unable to find linuxthreads symbol \"%s\"\n", "__pthread_offsetof_pid"); - return; + goto quit; } if (! find_all_signal_vars (objfile)) - return; + goto quit; /* Read adresses of internal structures to access */ if ((ms = lookup_minimal_symbol ("__pthread_handles", @@ -925,7 +933,7 @@ any thread other than the main thread."); fprintf_unfiltered (gdb_stderr, "Unable to find linuxthreads symbol \"%s\"\n", "__pthread_handles"); - return; + goto quit; } linuxthreads_handles = SYMBOL_VALUE_ADDRESS (ms); @@ -935,7 +943,7 @@ any thread other than the main thread."); fprintf_unfiltered (gdb_stderr, "Unable to find linuxthreads symbol \"%s\"\n", "__pthread_handles_num"); - return; + goto quit; } linuxthreads_num = SYMBOL_VALUE_ADDRESS (ms); @@ -945,7 +953,7 @@ any thread other than the main thread."); fprintf_unfiltered (gdb_stderr, "Unable to find linuxthreads symbol \"%s\"\n", "__pthread_manager_thread"); - return; + goto quit; } linuxthreads_manager = SYMBOL_VALUE_ADDRESS (ms) + linuxthreads_offset_pid; @@ -955,7 +963,7 @@ any thread other than the main thread."); fprintf_unfiltered (gdb_stderr, "Unable to find linuxthreads symbol \"%s\"\n", "__pthread_initial_thread"); - return; + goto quit; } linuxthreads_initial = SYMBOL_VALUE_ADDRESS (ms) + linuxthreads_offset_pid; @@ -970,7 +978,7 @@ any thread other than the main thread."); fprintf_unfiltered (gdb_stderr, "Unable to find linuxthreads symbol \"%s\"\n", "__pthread_threads_max"); - return; + goto quit; } /* Allocate gdb internal structures */ @@ -989,6 +997,11 @@ any thread other than the main thread."); update_stop_threads (inferior_pid); linuxthreads_attach_pending = 0; } + +quit: + /* Call predecessor on chain, if any. */ + if (target_new_objfile_chain) + target_new_objfile_chain (objfile); } /* If we have switched threads from a one that stopped at breakpoint, @@ -1635,6 +1648,13 @@ _initialize_linuxthreads () add_target (&linuxthreads_ops); child_suppress_run = 1; + /* Hook onto the "new_objfile" event. + * If someone else is already hooked onto the event, + * then make sure he will be called after we are. + */ + target_new_objfile_chain = target_new_objfile_hook; + target_new_objfile_hook = linuxthreads_new_objfile; + /* Attach SIGCHLD handler */ sact.sa_handler = sigchld_handler; sigemptyset (&sact.sa_mask); diff --git a/gdb/main.c b/gdb/main.c index 96df49c9815..42485c0e6d3 100644 --- a/gdb/main.c +++ b/gdb/main.c @@ -82,11 +82,44 @@ extern char *external_editor_command; #include /* for cygwin32_conv_to_posix_path */ #endif -int -main (argc, argv) - int argc; - char **argv; +/* Call command_loop. If it happens to return, pass that through as a + non-zero return status. */ + +static int +captured_command_loop (void *data) { + if (command_loop_hook == NULL) + command_loop (); + else + command_loop_hook (); + /* FIXME: cagney/1999-11-05: A correct command_loop() implementaton + would clean things up (restoring the cleanup chain) to the state + they were just prior to the call. Technically, this means that + the do_cleanups() below is redundant. Unfortunatly, many FUNC's + are not that well behaved. do_cleanups should either be replaced + with a do_cleanups call (to cover the problem) or an assertion + check to detect bad FUNCs code. */ + do_cleanups (ALL_CLEANUPS); + /* If the command_loop returned, normally (rather than threw an + error) we try to quit. If the quit is aborted, catch_errors() + which called this catch the signal and restart the command + loop. */ + quit_command (NULL, instream == stdin); + return 1; +} + +struct captured_main_args + { + int argc; + char **argv; + }; + +static int +captured_main (void *data) +{ + struct captured_main_args *context = data; + int argc = context->argc; + char **argv = context->argv; int count; static int quiet = 0; static int batch = 0; @@ -139,12 +172,6 @@ main (argc, argv) alloca (4 - i); #endif - /* If error() is called from initialization code, just exit */ - if (SET_TOP_LEVEL ()) - { - exit (1); - } - cmdsize = 1; cmdarg = (char **) xmalloc (cmdsize * sizeof (*cmdarg)); ncmd = 0; @@ -470,10 +497,8 @@ main (argc, argv) if (!inhibit_gdbinit) { - if (!SET_TOP_LEVEL ()) - source_command (homeinit, 0); + catch_command_errors (source_command, homeinit, 0, RETURN_MASK_ALL); } - do_cleanups (ALL_CLEANUPS); /* Do stats; no need to do them elsewhere since we'll only need them if homedir is set. Make sure that they are @@ -491,41 +516,30 @@ main (argc, argv) /* Now perform all the actions indicated by the arguments. */ if (cdarg != NULL) { - if (!SET_TOP_LEVEL ()) - { - cd_command (cdarg, 0); - } + catch_command_errors (cd_command, cdarg, 0, RETURN_MASK_ALL); } - do_cleanups (ALL_CLEANUPS); for (i = 0; i < ndir; i++) - if (!SET_TOP_LEVEL ()) - directory_command (dirarg[i], 0); + catch_command_errors (directory_command, dirarg[i], 0, RETURN_MASK_ALL); free ((PTR) dirarg); - do_cleanups (ALL_CLEANUPS); if (execarg != NULL && symarg != NULL && STREQ (execarg, symarg)) { - /* The exec file and the symbol-file are the same. If we can't open - it, better only print one error message. */ - if (!SET_TOP_LEVEL ()) - { - exec_file_command (execarg, !batch); - symbol_file_command (symarg, 0); - } + /* The exec file and the symbol-file are the same. If we can't + open it, better only print one error message. + catch_command_errors returns non-zero on success! */ + if (catch_command_errors (exec_file_command, execarg, !batch, RETURN_MASK_ALL)) + catch_command_errors (symbol_file_command, symarg, 0, RETURN_MASK_ALL); } else { if (execarg != NULL) - if (!SET_TOP_LEVEL ()) - exec_file_command (execarg, !batch); + catch_command_errors (exec_file_command, execarg, !batch, RETURN_MASK_ALL); if (symarg != NULL) - if (!SET_TOP_LEVEL ()) - symbol_file_command (symarg, 0); + catch_command_errors (symbol_file_command, symarg, 0, RETURN_MASK_ALL); } - do_cleanups (ALL_CLEANUPS); /* After the symbol file has been read, print a newline to get us beyond the copyright line... But errors should still set off @@ -538,17 +552,16 @@ main (argc, argv) if (corearg != NULL) { - if (!SET_TOP_LEVEL ()) - core_file_command (corearg, !batch); - else if (isdigit (corearg[0]) && !SET_TOP_LEVEL ()) - attach_command (corearg, !batch); + if (catch_command_errors (core_file_command, corearg, !batch, RETURN_MASK_ALL) == 0) + { + /* See if the core file is really a PID. */ + if (isdigit (corearg[0])) + catch_command_errors (attach_command, corearg, !batch, RETURN_MASK_ALL); + } } - do_cleanups (ALL_CLEANUPS); if (ttyarg != NULL) - if (!SET_TOP_LEVEL ()) - tty_command (ttyarg, !batch); - do_cleanups (ALL_CLEANUPS); + catch_command_errors (tty_command, ttyarg, !batch, RETURN_MASK_ALL); #ifdef ADDITIONAL_OPTION_HANDLER ADDITIONAL_OPTION_HANDLER; @@ -566,14 +579,15 @@ main (argc, argv) || memcmp ((char *) &homebuf, (char *) &cwdbuf, sizeof (struct stat))) if (!inhibit_gdbinit) { - if (!SET_TOP_LEVEL ()) - source_command (gdbinit, 0); + catch_command_errors (source_command, gdbinit, 0, RETURN_MASK_ALL); } - do_cleanups (ALL_CLEANUPS); for (i = 0; i < ncmd; i++) { - if (!SET_TOP_LEVEL ()) +#if 0 + /* NOTE: cagney/1999-11-03: SET_TOP_LEVEL() was a macro that + expanded into a call to setjmp(). */ + if (!SET_TOP_LEVEL ()) /* NB: This is #if 0'd out */ { /* NOTE: I am commenting this out, because it is not clear where this feature is used. It is very old and @@ -586,6 +600,8 @@ main (argc, argv) source_command (cmdarg[i], !batch); do_cleanups (ALL_CLEANUPS); } +#endif + catch_command_errors (source_command, cmdarg[i], !batch, RETURN_MASK_ALL); } free ((PTR) cmdarg); @@ -632,6 +648,11 @@ main (argc, argv) The WIN32 Gui calls this main to set up gdb's state, and has its own command loop. */ #if !defined _WIN32 || defined __GNUC__ + /* GUIs generally have their own command loop, mainloop, or + whatever. This is a good place to gain control because many + error conditions will end up here via longjmp(). */ +#if 0 + /* FIXME: cagney/1999-11-06: The original main loop was like: */ while (1) { if (!SET_TOP_LEVEL ()) @@ -647,11 +668,40 @@ main (argc, argv) quit_command ((char *) 0, instream == stdin); } } - /* No exit -- exit is through quit_command. */ + /* NOTE: If the command_loop() returned normally, the loop would + attempt to exit by calling the function quit_command(). That + function would either call exit() or throw an error returning + control to SET_TOP_LEVEL. */ + /* NOTE: The function do_cleanups() was called once each time round + the loop. The usefulness of the call isn't clear. If an error + was thrown, everything would have already been cleaned up. If + command_loop() returned normally and quit_command() was called, + either exit() or error() (again cleaning up) would be called. */ +#endif + /* NOTE: cagney/1999-11-07: There is probably no reason for not + moving this loop and the code found in captured_command_loop() + into the command_loop() proper. The main thing holding back that + change - SET_TOP_LEVEL() - has been eliminated. */ + while (1) + { + catch_errors (captured_command_loop, 0, "", RETURN_MASK_ALL); + } #endif + /* No exit -- exit is through quit_command. */ +} +int +main (int argc, char **argv) +{ + int top_level_val; + struct captured_main_args args; + args.argc = argc; + args.argv = argv; + catch_errors (captured_main, &args, "", RETURN_MASK_ALL); + return 0; } + /* Don't use *_filtered for printing help. We don't want to prompt for continue no matter how small the screen or how much we're going to print. */ diff --git a/gdb/procfs.c b/gdb/procfs.c index 83e58db0e45..4f1c54f0d08 100644 --- a/gdb/procfs.c +++ b/gdb/procfs.c @@ -2003,7 +2003,6 @@ unconditionally_kill_inferior (pi) struct procinfo *pi; { int ppid; - struct proc_ctl pctl; ppid = pi->prstatus.pr_ppid; @@ -2231,8 +2230,9 @@ init_procinfo (pid, kill) { struct procinfo *pi = (struct procinfo *) xmalloc (sizeof (struct procinfo)); +#ifdef UNIXWARE struct sig_ctl sctl; - struct flt_ctl fctl; +#endif /* UNIXWARE */ memset ((char *) pi, 0, sizeof (*pi)); if (!open_proc_file (pid, pi, O_RDWR, 1)) @@ -2313,8 +2313,9 @@ create_procinfo (pid) int pid; { struct procinfo *pi; - struct sig_ctl sctl; +#ifdef PROCFS_USE_READ_WRITE struct flt_ctl fctl; +#endif pi = find_procinfo (pid, 1); if (pi != NULL) @@ -2381,7 +2382,9 @@ procfs_exit_handler (pi, syscall_num, why, rtnvalp, statvalp) int *statvalp; { struct procinfo *temp_pi, *next_pi; +#if defined (UNIXWARE) || defined (PROCFS_USE_READ_WRITE) struct proc_ctl pctl; +#endif #ifdef UNIXWARE pctl.cmd = PCRUN; @@ -2913,7 +2916,9 @@ proc_set_exec_trap () #ifdef PR_ASYNC { long pr_flags; +#ifdef PROCFS_USE_READ_WRITE struct proc_ctl pctl; +#endif /* Solaris needs this to make procfs treat all threads seperately. Without this, all threads halt whenever something happens to any thread. Since @@ -3250,8 +3255,9 @@ do_attach (pid) int pid; { struct procinfo *pi; - struct sig_ctl sctl; +#ifdef PROCFS_USE_READ_WRITE struct flt_ctl fctl; +#endif int nlwp, *lwps; pi = init_procinfo (pid, 0); @@ -3285,7 +3291,9 @@ do_attach (pid) pi->was_stopped = 0; if (1 || query ("Process is currently running, stop it? ")) { +#ifdef PROCFS_USE_READ_WRITE long cmd; +#endif /* Make it run again when we close it. */ modify_run_on_last_close_flag (pi->ctl_fd, 1); #ifdef PROCFS_USE_READ_WRITE @@ -3447,8 +3455,9 @@ do_detach (signal) if (signal || (THE_PR_LWP (pi->prstatus).pr_flags & (PR_STOPPED | PR_ISTOP))) { +#ifdef PROCFS_USE_READ_WRITE long cmd; - struct proc_ctl pctl; +#endif if (signal || !pi->was_stopped || query ("Was stopped when attached, make it runnable again? ")) @@ -3516,7 +3525,6 @@ procfs_wait (pid, ourstatus) int checkerr = 0; int rtnval = -1; struct procinfo *pi; - struct proc_ctl pctl; scan_again: @@ -3783,7 +3791,9 @@ set_proc_siginfo (pip, signo) { struct siginfo newsiginfo; struct siginfo *sip; +#if defined (UNIXWARE) || defined (PROCFS_USE_READ_WRITE) struct sigi_ctl sictl; +#endif #ifdef PROCFS_DONT_PIOCSSIG_CURSIG /* With Alpha OSF/1 procfs, the kernel gets really confused if it @@ -3844,7 +3854,9 @@ procfs_resume (pid, step, signo) { int signal_to_pass; struct procinfo *pi, *procinfo, *next_pi; +#if defined (UNIXWARE) || defined (PROCFS_USE_READ_WRITE) struct proc_ctl pctl; +#endif pi = find_procinfo (pid == -1 ? inferior_pid : pid, 0); @@ -4791,7 +4803,9 @@ info_proc_mappings (pip, summary) int nmap; struct prmap *prmaps; struct prmap *prmap; +#ifdef PROCFS_USE_READ_WRITE struct stat sbuf; +#endif if (!summary) { @@ -5116,7 +5130,9 @@ modify_inherit_on_fork_flag (fd, flag) long pr_flags; #endif int retval = 0; +#ifdef PROCFS_USE_READ_WRITE struct proc_ctl pctl; +#endif #if defined (PIOCSET) || defined (PCSET) /* New method */ pr_flags = PR_FORK; @@ -5192,7 +5208,9 @@ modify_run_on_last_close_flag (fd, flag) long pr_flags; #endif int retval = 0; +#ifdef PROCFS_USE_READ_WRITE struct proc_ctl pctl; +#endif #if defined (PIOCSET) || defined (PCSET) /* New method */ pr_flags = PR_RLC; @@ -5473,7 +5491,9 @@ procfs_lwp_creation_handler (pi, syscall_num, why, rtnvalp, statvalp) { int lwp_id; struct procinfo *childpi; +#ifdef UNIXWARE struct proc_ctl pctl; +#endif /* We've just detected the completion of an lwp_create system call. Now we need to setup a procinfo struct for this thread, and notify the thread @@ -5781,14 +5801,16 @@ procfs_thread_alive (pid) { next_pi = pi->next; if (pi->pid == pid) - if (procfs_read_status (pi)) /* alive */ - return 1; - else - /* defunct (exited) */ - { - close_proc_file (pi); - return 0; - } + { + if (procfs_read_status (pi)) /* alive */ + return 1; + else + /* defunct (exited) */ + { + close_proc_file (pi); + return 0; + } + } } return 0; } diff --git a/gdb/rdi-share/Makefile.in b/gdb/rdi-share/Makefile.in index a24e1afb9bb..617b4c4d01c 100644 --- a/gdb/rdi-share/Makefile.in +++ b/gdb/rdi-share/Makefile.in @@ -94,7 +94,7 @@ CPPFLAGS = @CPPFLAGS@ LDFLAGS = @LDFLAGS@ LIBS = @LIBS@ libangsd_a_LIBADD = -libangsd_a_OBJECTS = ardi.o bytesex.o crc.o devsw.o drivers.o \ +libangsd_a_OBJECTS = ardi.o angel_bytesex.o crc.o devsw.o drivers.o \ etherdrv.o hostchan.o hsys.o logging.o msgbuild.o params.o rx.o \ serdrv.o serpardr.o tx.o unixcomm.o AR = ar diff --git a/gdb/rdi-share/devsw.c b/gdb/rdi-share/devsw.c index 51ac29e9c98..b48c337ccf0 100644 --- a/gdb/rdi-share/devsw.c +++ b/gdb/rdi-share/devsw.c @@ -47,7 +47,9 @@ static void openLogFile () perror ("fopen"); } else - setlinebuf (angelDebugLogFile); + /* The following line is equivalent to: */ + /* setlinebuf (angelDebugLogFile); */ + setvbuf(angelDebugLogFile, (char *)NULL, _IOLBF, 0); time (&t); fprintf (angelDebugLogFile,"ADP log file opened at %s\n",asctime(localtime(&t))); diff --git a/gdb/remote-rdp.c b/gdb/remote-rdp.c index ef45ca36852..7a0e53c5df9 100644 --- a/gdb/remote-rdp.c +++ b/gdb/remote-rdp.c @@ -480,7 +480,7 @@ send_rdp (char *template,...) abort (); } } - va_end (args); + va_end (alist); if (dst != buf) abort (); diff --git a/gdb/remote.c b/gdb/remote.c index cd4eda0a083..e63813628a3 100644 --- a/gdb/remote.c +++ b/gdb/remote.c @@ -280,28 +280,6 @@ static serial_t remote_desc = NULL; to denote that the target is in kernel mode. */ static int cisco_kernel_mode = 0; -/* Maximum number of bytes to read/write at once. The value here - is chosen to fill up a packet (the headers account for the 32). */ -#define MAXBUFBYTES(N) (((N)-32)/2) - -/* Having this larger than 400 causes us to be incompatible with m68k-stub.c - and i386-stub.c. Normally, no one would notice because it only matters - for writing large chunks of memory (e.g. in downloads). Also, this needs - to be more than 400 if required to hold the registers (see below, where - we round it up based on REGISTER_BYTES). */ -/* Round up PBUFSIZ to hold all the registers, at least. */ -#define PBUFSIZ ((REGISTER_BYTES > MAXBUFBYTES (400)) \ - ? (REGISTER_BYTES * 2 + 32) \ - : 400) - - -/* This variable sets the number of bytes to be written to the target - in a single packet. Normally PBUFSIZ is satisfactory, but some - targets need smaller values (perhaps because the receiving end - is slow). */ - -static int remote_write_size; - /* This variable sets the number of bits in an address that are to be sent in a memory ("M" or "m") packet. Normally, after stripping leading zeros, the entire address would be sent. This variable @@ -315,18 +293,226 @@ static int remote_write_size; static int remote_address_size; -/* This is the size (in chars) of the first response to the `g' command. This - is used to limit the size of the memory read and write commands to prevent - stub buffers from overflowing. The size does not include headers and - trailers, it is only the payload size. */ - -static int remote_register_buf_size = 0; - /* Tempoary to track who currently owns the terminal. See target_async_terminal_* for more details. */ static int remote_async_terminal_ours_p; + +/* This is the size (in chars) of the first response to the ``g'' + packet. It is used as a heuristic when determining the maximum + size of memory-read and memory-write packets. A target will + typically only reserve a buffer large enough to hold the ``g'' + packet. The size does not include packet overhead (headers and + trailers). */ + +static long actual_register_packet_size; + +/* This is the maximum size (in chars) of a non read/write packet. It + is also used as a cap on the size of read/write packets. */ + +static long remote_packet_size; +/* compatibility. */ +#define PBUFSIZ (remote_packet_size) + +/* User configurable variables for the number of characters in a + memory read/write packet. MIN (PBUFSIZ, g-packet-size) is the + default. Some targets need smaller values (fifo overruns, et.al.) + and some users need larger values (speed up transfers). The + variables ``preferred_*'' (the user request), ``current_*'' (what + was actually set) and ``forced_*'' (Positive - a soft limit, + negative - a hard limit). */ + +struct memory_packet_config +{ + char *name; + long size; + int fixed_p; +}; + +/* Compute the current size of a read/write packet. Since this makes + use of ``actual_register_packet_size'' the computation is dynamic. */ + +static long +get_memory_packet_size (struct memory_packet_config *config) +{ + /* NOTE: The somewhat arbitrary 16k comes from the knowledge (folk + law?) that some hosts don't cope very well with large alloca() + calls. Eventually the alloca() code will be replaced by calls to + xmalloc() and make_cleanups() allowing this restriction to either + be lifted or removed. */ +#ifndef MAX_REMOTE_PACKET_SIZE +#define MAX_REMOTE_PACKET_SIZE 16384 +#endif + /* NOTE: 16 is just chosen at random. */ +#ifndef MIN_REMOTE_PACKET_SIZE +#define MIN_REMOTE_PACKET_SIZE 16 +#endif + long what_they_get; + if (config->fixed_p) + { + if (config->size <= 0) + what_they_get = MAX_REMOTE_PACKET_SIZE; + else + what_they_get = config->size; + } + else + { + what_they_get = remote_packet_size; + /* Limit the packet to the size specified by the user. */ + if (config->size > 0 + && what_they_get > config->size) + what_they_get = config->size; + /* Limit it to the size of the targets ``g'' response. */ + if (actual_register_packet_size > 0 + && what_they_get > actual_register_packet_size) + what_they_get = actual_register_packet_size; + } + if (what_they_get > MAX_REMOTE_PACKET_SIZE) + what_they_get = MAX_REMOTE_PACKET_SIZE; + if (what_they_get < MIN_REMOTE_PACKET_SIZE) + what_they_get = MIN_REMOTE_PACKET_SIZE; + return what_they_get; +} + +/* Update the size of a read/write packet. If they user wants + something really big then do a sanity check. */ + +static void +set_memory_packet_size (char *args, struct memory_packet_config *config) +{ + int fixed_p = config->fixed_p; + long size = config->size; + if (args == NULL) + error ("Argument required (integer, `fixed' or `limited')."); + else if (strcmp (args, "hard") == 0 + || strcmp (args, "fixed") == 0) + fixed_p = 1; + else if (strcmp (args, "soft") == 0 + || strcmp (args, "limit") == 0) + fixed_p = 0; + else + { + char *end; + size = strtoul (args, &end, 0); + if (args == end) + error ("Invalid %s (bad syntax).", config->name); +#if 0 + /* Instead of explicitly capping the size of a packet to + MAX_REMOTE_PACKET_SIZE or dissallowing it, the user is + instead allowed to set the size to something arbitrarily + large. */ + if (size > MAX_REMOTE_PACKET_SIZE) + error ("Invalid %s (too large).", config->name); +#endif + } + /* Extra checks? */ + if (fixed_p && !config->fixed_p) + { + if (! query ("The target may not be able to correctly handle a %s\n" + "of %ld bytes. Change the packet size? ", + config->name, size)) + error ("Packet size not changed."); + } + /* Update the config. */ + config->fixed_p = fixed_p; + config->size = size; +} + +static void +show_memory_packet_size (struct memory_packet_config *config) +{ + printf_filtered ("The %s is %ld. ", config->name, config->size); + if (config->fixed_p) + printf_filtered ("Packets are fixed at %ld bytes.\n", + get_memory_packet_size (config)); + else + printf_filtered ("Packets are limited to %ld bytes.\n", + get_memory_packet_size (config)); +} + +static struct memory_packet_config memory_write_packet_config = +{ + "memory-write-packet-size", +}; + +static void +set_memory_write_packet_size (char *args, int from_tty) +{ + set_memory_packet_size (args, &memory_write_packet_config); +} + +static void +show_memory_write_packet_size (char *args, int from_tty) +{ + show_memory_packet_size (&memory_write_packet_config); +} + +static long +get_memory_write_packet_size (void) +{ + return get_memory_packet_size (&memory_write_packet_config); +} + +static struct memory_packet_config memory_read_packet_config = +{ + "memory-read-packet-size", +}; + +static void +set_memory_read_packet_size (char *args, int from_tty) +{ + set_memory_packet_size (args, &memory_read_packet_config); +} + +static void +show_memory_read_packet_size (char *args, int from_tty) +{ + show_memory_packet_size (&memory_read_packet_config); +} + +static long +get_memory_read_packet_size (void) +{ + long size = get_memory_packet_size (&memory_read_packet_config); + /* FIXME: cagney/1999-11-07: Functions like getpkt() need to get an + extra buffer size argument before the memory read size can be + increased beyond PBUFSIZ. */ + if (size > PBUFSIZ) + size = PBUFSIZ; + return size; +} + +/* Register packet size initialization. Since the bounds change when + the architecture changes (namely REGISTER_BYTES) this all needs to + be multi-arched. */ + +static void +register_remote_packet_sizes (void) +{ + REGISTER_GDBARCH_SWAP (remote_packet_size); + REGISTER_GDBARCH_SWAP (actual_register_packet_size); +} + +static void +build_remote_packet_sizes (void) +{ + /* Maximum number of characters in a packet. This default m68k-stub.c and + i386-stub.c stubs. */ + remote_packet_size = 400; + /* Should REGISTER_BYTES needs more space than the default, adjust + the size accordingly. Remember that each byte is encoded as two + characters. 32 is the overhead for the packet header / + footer. NOTE: cagney/1999-10-26: I suspect that 8 + (``$NN:G...#NN'') is a better guess, the below has been padded a + little. */ + if (REGISTER_BYTES > ((remote_packet_size - 32) / 2)) + remote_packet_size = (REGISTER_BYTES * 2 + 32); + + /* This one is filled in when a ``g'' packet is received. */ + actual_register_packet_size = 0; +} + /* Generic configuration support for packets the stub optionally supports. Allows the user to specify the use of the packet as well as allowing GDB to auto-detect support in the remote stub. */ @@ -2749,8 +2935,11 @@ remote_fetch_registers (regno) sprintf (buf, "g"); remote_send (buf); - if (remote_register_buf_size == 0) - remote_register_buf_size = strlen (buf); + /* Save the size of the packet sent to us by the target. Its used + as a heuristic when determining the max size of packets that the + target can safely receive. */ + if (actual_register_packet_size == 0) + actual_register_packet_size = strlen (buf); /* Unimplemented registers read as all bits zero. */ memset (regs, 0, REGISTER_BYTES); @@ -3095,9 +3284,7 @@ remote_write_bytes (CORE_ADDR memaddr, char *myaddr, int len) check_binary_download (memaddr); /* Determine the max packet size. */ - max_buf_size = min (remote_write_size, PBUFSIZ); - if (remote_register_buf_size != 0) - max_buf_size = min (max_buf_size, remote_register_buf_size); + max_buf_size = get_memory_write_packet_size (); buf = alloca (max_buf_size + 1); /* Subtract header overhead from max payload size - $M,:#nn */ @@ -3228,15 +3415,13 @@ remote_read_bytes (memaddr, myaddr, len) char *myaddr; int len; { - char *buf = alloca (PBUFSIZ); + char *buf; int max_buf_size; /* Max size of packet output buffer */ int origlen; - /* Chop the transfer down if necessary */ - - max_buf_size = min (remote_write_size, PBUFSIZ); - if (remote_register_buf_size != 0) - max_buf_size = min (max_buf_size, remote_register_buf_size); + /* Create a buffer big enough for this packet. */ + max_buf_size = get_memory_read_packet_size (); + buf = alloca (max_buf_size); origlen = len; while (len > 0) @@ -3477,7 +3662,7 @@ putpkt_binary (buf, cnt) { int i; unsigned char csum = 0; - char *buf2 = alloca (PBUFSIZ); + char *buf2 = alloca (cnt + 6); char *junkbuf = alloca (PBUFSIZ); int ch; @@ -3487,9 +3672,6 @@ putpkt_binary (buf, cnt) /* Copy the packet into buffer BUF2, encapsulating it and giving it a checksum. */ - if (cnt > BUFSIZ - 5) /* Prosanity check */ - abort (); - p = buf2; *p++ = '$'; @@ -5220,7 +5402,11 @@ set_remote_cmd (args, from_tty) static void build_remote_gdbarch_data () { + build_remote_packet_sizes (); + + /* Cisco stuff */ tty_input = xmalloc (PBUFSIZ); + remote_address_size = TARGET_PTR_BIT; } void @@ -5228,16 +5414,16 @@ _initialize_remote () { static struct cmd_list_element *remote_set_cmdlist; static struct cmd_list_element *remote_show_cmdlist; + struct cmd_list_element *tmpcmd; /* architecture specific data */ build_remote_gdbarch_data (); register_gdbarch_swap (&tty_input, sizeof (&tty_input), NULL); + register_remote_packet_sizes (); + register_gdbarch_swap (&remote_address_size, + sizeof (&remote_address_size), NULL); register_gdbarch_swap (NULL, 0, build_remote_gdbarch_data); - /* runtime constants - we retain the value of remote_write_size - across architecture swaps. */ - remote_write_size = PBUFSIZ; - init_remote_ops (); add_target (&remote_ops); @@ -5298,14 +5484,39 @@ terminating `#' character and checksum.", &setlist), &showlist); - add_show_from_set - (add_set_cmd ("remotewritesize", no_class, - var_integer, (char *) &remote_write_size, - "Set the maximum number of bytes per memory write packet.\n", - &setlist), - &showlist); + /* Install commands for configuring memory read/write packets. */ + + add_cmd ("remotewritesize", no_class, set_memory_write_packet_size, + "Set the maximum number of bytes per memory write packet (deprecated).\n", + &setlist); + add_cmd ("remotewritesize", no_class, set_memory_write_packet_size, + "Show the maximum number of bytes per memory write packet (deprecated).\n", + &showlist); + add_cmd ("memory-write-packet-size", no_class, + set_memory_write_packet_size, + "Set the maximum number of bytes per memory-write packet.\n" + "Specify the number of bytes in a packet or 0 (zero) for the\n" + "default packet size. The actual limit is further reduced\n" + "dependent on the target. Specify ``fixed'' to disable the\n" + "further restriction and ``limit'' to enable that restriction\n", + &remote_set_cmdlist); + add_cmd ("memory-read-packet-size", no_class, + set_memory_read_packet_size, + "Set the maximum number of bytes per memory-read packet.\n" + "Specify the number of bytes in a packet or 0 (zero) for the\n" + "default packet size. The actual limit is further reduced\n" + "dependent on the target. Specify ``fixed'' to disable the\n" + "further restriction and ``limit'' to enable that restriction\n", + &remote_set_cmdlist); + add_cmd ("memory-write-packet-size", no_class, + show_memory_write_packet_size, + "Show the maximum number of bytes per memory-write packet.\n", + &remote_show_cmdlist); + add_cmd ("memory-read-packet-size", no_class, + show_memory_read_packet_size, + "Show the maximum number of bytes per memory-read packet.\n", + &remote_show_cmdlist); - remote_address_size = TARGET_PTR_BIT; add_show_from_set (add_set_cmd ("remoteaddresssize", class_obscure, var_integer, (char *) &remote_address_size, diff --git a/gdb/serial.c b/gdb/serial.c index 2d73226761c..e33e2ef72d2 100644 --- a/gdb/serial.c +++ b/gdb/serial.c @@ -288,7 +288,7 @@ do_serial_close (serial_t scb, int really_close) serial_current_type = 0; /* XXX - What if serial_logfp == gdb_stdout or gdb_stderr? */ - gdb_fclose (&serial_logfp); + gdb_file_delete (serial_logfp); serial_logfp = NULL; } diff --git a/gdb/sol-thread.c b/gdb/sol-thread.c index 68cde8a7605..218ab38f34c 100644 --- a/gdb/sol-thread.c +++ b/gdb/sol-thread.c @@ -857,6 +857,13 @@ sol_thread_create_inferior (exec_file, allargs, env) those variables don't show up until the library gets mapped and the symbol table is read in. */ +/* This new_objfile event is now managed by a chained function pointer. + * It is the callee's responsability to call the next client on the chain. + */ + +/* Saved pointer to previous owner of the new_objfile event. */ +static void (*target_new_objfile_chain) PARAMS ((struct objfile *)); + void sol_thread_new_objfile (objfile) struct objfile *objfile; @@ -866,13 +873,12 @@ sol_thread_new_objfile (objfile) if (!objfile) { sol_thread_active = 0; - - return; + goto quit; } /* don't do anything if init failed to resolve the libthread_db library */ if (!procfs_suppress_run) - return; + goto quit; /* Now, initialize the thread debugging library. This needs to be done after the shared libraries are located because it needs information from the @@ -880,15 +886,25 @@ sol_thread_new_objfile (objfile) val = p_td_init (); if (val != TD_OK) - error ("target_new_objfile: td_init: %s", td_err_string (val)); + { + warning ("sol_thread_new_objfile: td_init: %s", td_err_string (val)); + goto quit; + } val = p_td_ta_new (&main_ph, &main_ta); if (val == TD_NOLIBTHREAD) - return; + goto quit; else if (val != TD_OK) - error ("target_new_objfile: td_ta_new: %s", td_err_string (val)); + { + warning ("sol_thread_new_objfile: td_ta_new: %s", td_err_string (val)); + goto quit; + } sol_thread_active = 1; +quit: + /* Call predecessor on chain, if any. */ + if (target_new_objfile_chain) + target_new_objfile_chain (objfile); } /* Clean up after the inferior dies. */ @@ -1698,6 +1714,9 @@ _initialize_sol_thread () memcpy (&core_ops, &sol_core_ops, sizeof (struct target_ops)); add_target (&core_ops); + /* Hook into new_objfile notification. */ + target_new_objfile_chain = target_new_objfile_hook; + target_new_objfile_hook = sol_thread_new_objfile; return; die: diff --git a/gdb/symfile.c b/gdb/symfile.c index c7271686523..80f99029503 100644 --- a/gdb/symfile.c +++ b/gdb/symfile.c @@ -66,6 +66,7 @@ extern int hp_cxx_exception_support_initialized; int (*ui_load_progress_hook) (const char *section, unsigned long num); void (*pre_add_symbol_hook) PARAMS ((char *)); void (*post_add_symbol_hook) PARAMS ((void)); +void (*target_new_objfile_hook) PARAMS ((struct objfile *)); /* Global variables owned by this file */ int readnow_symbol_files; /* Read full symbols immediately */ @@ -920,7 +921,8 @@ symbol_file_add (name, from_tty, addrs, mainline, flags) new_symfile_objfile (objfile, mainline, from_tty); - target_new_objfile (objfile); + if (target_new_objfile_hook) + target_new_objfile_hook (objfile); return (objfile); } @@ -2096,7 +2098,8 @@ clear_symtab_users () current_source_symtab = 0; current_source_line = 0; clear_pc_function_cache (); - target_new_objfile (NULL); + if (target_new_objfile_hook) + target_new_objfile_hook (NULL); } /* clear_symtab_users_once: diff --git a/gdb/symmisc.c b/gdb/symmisc.c index 2bf70c247d3..dbf64f79b0b 100644 --- a/gdb/symmisc.c +++ b/gdb/symmisc.c @@ -543,7 +543,7 @@ Arguments missing: an output file name and an optional symbol file name"); outfile = gdb_fopen (filename, FOPEN_WT); if (outfile == 0) perror_with_name (filename); - make_cleanup ((make_cleanup_func) gdb_fclose, (char *) &outfile); + make_cleanup_gdb_file_delete (outfile); immediate_quit++; ALL_SYMTABS (objfile, s) @@ -780,7 +780,7 @@ maintenance_print_psymbols (args, from_tty) outfile = gdb_fopen (filename, FOPEN_WT); if (outfile == 0) perror_with_name (filename); - make_cleanup ((make_cleanup_func) gdb_fclose, &outfile); + make_cleanup_gdb_file_delete (outfile); immediate_quit++; ALL_PSYMTABS (objfile, ps) @@ -928,7 +928,7 @@ maintenance_print_msymbols (args, from_tty) outfile = gdb_fopen (filename, FOPEN_WT); if (outfile == 0) perror_with_name (filename); - make_cleanup ((make_cleanup_func) gdb_fclose, &outfile); + make_cleanup_gdb_file_delete (outfile); immediate_quit++; ALL_OBJFILES (objfile) diff --git a/gdb/target.c b/gdb/target.c index aa8f28d163b..3a6e423d75a 100644 --- a/gdb/target.c +++ b/gdb/target.c @@ -272,6 +272,12 @@ target_ignore () { } +void +target_load (char *arg, int from_tty) +{ + (*current_target.to_load) (arg, from_tty); +} + /* ARGSUSED */ static int nomemory (memaddr, myaddr, len, write, t) diff --git a/gdb/target.h b/gdb/target.h index 7fc9e8642ba..9a853cfaa6c 100644 --- a/gdb/target.h +++ b/gdb/target.h @@ -755,8 +755,7 @@ print_section_info PARAMS ((struct target_ops *, bfd *)); not only bring new code into the target process, but also to update GDB's symbol tables to match. */ -#define target_load(arg, from_tty) \ - (*current_target.to_load) (arg, from_tty) +extern void target_load (char *arg, int from_tty); /* Look up a symbol in the target's symbol table. NAME is the symbol name. ADDRP is a CORE_ADDR * pointing to where the value of the symbol @@ -1063,10 +1062,30 @@ extern char *normal_pid_to_str PARAMS ((int pid)); extern char *normal_pid_to_str PARAMS ((int pid)); #endif +/* + * New Objfile Event Hook: + * + * Sometimes a GDB component wants to get notified whenever a new + * objfile is loaded. Mainly this is used by thread-debugging + * implementations that need to know when symbols for the target + * thread implemenation are available. + * + * The old way of doing this is to define a macro 'target_new_objfile' + * that points to the function that you want to be called on every + * objfile/shlib load. + * + * The new way is to grab the function pointer, 'target_new_objfile_hook', + * and point it to the function that you want to be called on every + * objfile/shlib load. + * + * If multiple clients are willing to be cooperative, they can each + * save a pointer to the previous value of target_new_objfile_hook + * before modifying it, and arrange for their function to call the + * previous function in the chain. In that way, multiple clients + * can receive this notification (something like with signal handlers). + */ -#ifndef target_new_objfile -#define target_new_objfile(OBJFILE) -#endif +extern void (*target_new_objfile_hook) PARAMS ((struct objfile *)); #ifndef target_pid_or_tid_to_str #define target_pid_or_tid_to_str(ID) \ @@ -1338,7 +1357,7 @@ extern void push_remote_target PARAMS ((char *name, int from_tty)); #ifndef SOFTWARE_SINGLE_STEP_P #define SOFTWARE_SINGLE_STEP_P 0 -#define SOFTWARE_SINGLE_STEP(sig,bp_p) abort () +#define SOFTWARE_SINGLE_STEP(sig,bp_p) (internal_error ("SOFTWARE_SINGLE_STEP"), 0) #endif /* SOFTWARE_SINGLE_STEP_P */ /* Blank target vector entries are initialized to target_ignore. */ diff --git a/gdb/testsuite/ChangeLog b/gdb/testsuite/ChangeLog index 28b724cd153..ea2809835a2 100644 --- a/gdb/testsuite/ChangeLog +++ b/gdb/testsuite/ChangeLog @@ -1,3 +1,44 @@ +Mon Nov 8 23:07:09 1999 Andrew Cagney + + * gdb.base/remote.exp: Test ``set remote memory-write-packet-sized + {limit,fixed}''. Test ``set download-write-size''. + +Sun Nov 7 17:37:01 1999 Andrew Cagney + + * gdb.base/funcargs.exp: Rewrite stack traceback checks using + gdb_expect_list. + +Fri Nov 5 18:40:52 1999 Andrew Cagney + + * lib/gdb.exp (gdb_expect_list): Return a success/fail indication. + +1999-11-03 Mark Salter + + * gdb.base/break.exp: Fix "stub continue" pattern. + +1999-11-03 Jim Blandy + + * gdb.base/shlib-call.exp ("next to shr1"): Fix test name. + +1999-11-02 Jim Blandy + + * gdb.base/display.exp ("finish"): Add timeout clause. + + * gdb.base/condbreak.exp ("run until breakpoint at marker1"): Add + plain prompt clause, so this doesn't have to time out in order to + fail. + + * gdb.base/condbreak.exp, gdb.base/ena-dis-br.exp: XFAIL if the + breakpoint hit messages include an address. + + * gdb.base/display.exp: Don't forget to escape parens in regular + expressions. Unix regexp notatation sucks. + +1999-11-02 Elena Zannoni + + * gdb.base/annota1.exp: Test for annotate-signalled: change output + order for 'signalled' message. + 1999-11-01 Stan Shebs From Jimmy Guo : diff --git a/gdb/testsuite/gdb.base/annota1.exp b/gdb/testsuite/gdb.base/annota1.exp index 9b4fce6f6fe..9791a9c4e27 100644 --- a/gdb/testsuite/gdb.base/annota1.exp +++ b/gdb/testsuite/gdb.base/annota1.exp @@ -420,7 +420,7 @@ gdb_expect { # send_gdb "signal SIGTRAP\n" gdb_expect { - -re ".*\032\032post-prompt\r\nContinuing with signal SIGTRAP.\r\n\r\n\032\032starting\r\n\r\n\032\032frames-invalid\r\n\r\n\032\032signalled\r\n\r\n\032\032frames-invalid\r\n\r\nProgram terminated with signal \r\n\032\032signal-name\r\nSIGTRAP\r\n\032\032signal-name-end\r\n, \r\n\032\032signal-string\r\nTrace.breakpoint trap\r\n\032\032signal-string-end\r\n.\r\nThe program no longer exists.\r\n\r\n\032\032stopped\r\n$gdb_prompt$" \ + -re ".*\032\032post-prompt\r\nContinuing with signal SIGTRAP.\r\n\r\n\032\032starting\r\n\r\n\032\032frames-invalid\r\n\r\n\032\032frames-invalid\r\n\r\n\032\032signalled\r\n\r\nProgram terminated with signal \r\n\032\032signal-name\r\nSIGTRAP\r\n\032\032signal-name-end\r\n, \r\n\032\032signal-string\r\nTrace.breakpoint trap\r\n\032\032signal-string-end\r\n.\r\nThe program no longer exists.\r\n\r\n\032\032stopped\r\n$gdb_prompt$" \ { pass "signal sent" } -re ".*$gdb_prompt$" { fail "signal sent" } timeout { fail "signal sent (timeout)" } @@ -443,7 +443,6 @@ if [ regexp "core not found" $exec_output] { } } - # restore the original prompt for the rest of the testsuite set gdb_prompt $old_gdb_prompt diff --git a/gdb/testsuite/gdb.base/break.exp b/gdb/testsuite/gdb.base/break.exp index d5b2af3d3af..a3d54eda657 100644 --- a/gdb/testsuite/gdb.base/break.exp +++ b/gdb/testsuite/gdb.base/break.exp @@ -166,7 +166,7 @@ if ![target_info exists use_gdb_stub] { } } else { if ![target_info exists gdb_stub] { - gdb_test continue "Continuing\\..*Breakpoint \[0-9\]+, main \\(argc=.*, argv=.*, envp=.*\\) at .*$srcfile:75.*75\[\t \]+if .argc.*\{" "stub continue" + gdb_test continue ".*Continuing\\..*Breakpoint \[0-9\]+, main \\(argc=.*, argv=.*, envp=.*\\) at .*$srcfile:75.*75\[\t \]+if .argc.*\{.*" "stub continue" } } diff --git a/gdb/testsuite/gdb.base/condbreak.exp b/gdb/testsuite/gdb.base/condbreak.exp index ae0858bf52b..e73f2ab1429 100644 --- a/gdb/testsuite/gdb.base/condbreak.exp +++ b/gdb/testsuite/gdb.base/condbreak.exp @@ -143,8 +143,58 @@ gdb_test "continue" "Continuing\\..*Breakpoint \[0-9\]+, main \\(argc=.*, argv=. # # run until the breakpoint at marker1 # -gdb_test "continue" "Continuing\\..*Breakpoint \[0-9\]+, marker1 \\(\\) at .*$srcfile:4\[38\].*4\[38\]\[\t \]+.*" \ - "run until breakpoint at marker1" +# If the inferior stops at the first instruction of a source line, GDB +# won't print the actual PC value; the source line is enough to +# exactly specify the PC. But if the inferior is instead stopped in +# the midst of a source line, GDB will include the PC in the +# breakpoint hit message. This way, GDB always provides the exact +# stop location, but avoids clutter when possible. +# +# Suppose you have a function written completely on one source line, like: +# int foo (int x) { return 0; } +# Setting a breakpoint at `foo' actually places the breakpoint after +# foo's prologue. +# +# GCC's STABS writer always emits a line entry attributing the +# prologue instructions to the line containing the function's open +# brace, even if the first user instruction is also on that line. +# This means that, in the case of a one-line function, you will get +# two line entries in the debug info for the same line: one at the +# function's entry point, and another at the first user instruction. +# GDB preserves these duplicated line entries, and prefers the later +# one; thus, when the program stops after the prologue, at the first +# user instruction, GDB's search finds the second line entry, decides +# that the PC is indeed at the beginning of a source line, and doesn't +# print an address in the breakpoint hit message. +# +# GCC's Dwarf2 writer, on the other hand, squeezes out duplicate line +# entries, so GDB considers the source line to begin at the start of +# the function's prologue. Thus, if the program stops at the +# breakpoint, GDB will decide that the PC is not at the beginning of a +# source line, and will print an address. +# +# I think the Dwarf2 writer's behavior is arguably correct, but not +# helpful. If the user sets a breakpoint at that source line, they +# want that breakpoint to fall after the prologue. Identifying the +# prologue's code with the opening brace is nice, but it shouldn't +# take precedence over real code. +# +# Until the Dwarf2 writer gets fixed, I'm going to XFAIL its behavior. +send_gdb "continue\n" +gdb_expect { + -re "Continuing\\..*Breakpoint \[0-9\]+, marker1 \\(\\) at .*$srcfile:4\[38\].*4\[38\]\[\t \]+.*" { + pass "run until breakpoint at marker1" + } + -re "Continuing\\..*Breakpoint \[0-9\]+, $hex in marker1 \\(\\) at .*$srcfile:4\[38\].*4\[38\]\[\t \]+.*" { + xfail "run until breakpoint at marker1" + } + -re "$gdb_prompt $" { + fail "run until breakpoint at marker1" + } + timeout { + fail "(timeout) run until breakpoint at marker1" + } +} # # run until the breakpoint at marker2 diff --git a/gdb/testsuite/gdb.base/display.exp b/gdb/testsuite/gdb.base/display.exp index 7a3519ed190..b502dc66433 100644 --- a/gdb/testsuite/gdb.base/display.exp +++ b/gdb/testsuite/gdb.base/display.exp @@ -136,14 +136,21 @@ gdb_test "c" ".*Breakpoint 4.*" "watch off" # "do_vars". send_gdb "finish\n" gdb_expect { - -re ".*do_loops();.*$gdb_prompt $" { + -re ".*do_loops\\(\\);.*$gdb_prompt $" { send_gdb "step\n" exp_continue } -re ".*do_vars.*$gdb_prompt $" { pass "finish" } - default { fail "finish" ; gdb_suppress_tests; } + -re ".*$gdb_prompt $" { + fail "finish" + gdb_suppress_tests + } + timeout { + fail "(timeout) finish" + gdb_suppress_tests + } } gdb_test "s" ".*do_vars.*.*27.*" diff --git a/gdb/testsuite/gdb.base/ena-dis-br.exp b/gdb/testsuite/gdb.base/ena-dis-br.exp index f7be9868e89..5cc1ba0d4e2 100644 --- a/gdb/testsuite/gdb.base/ena-dis-br.exp +++ b/gdb/testsuite/gdb.base/ena-dis-br.exp @@ -97,10 +97,14 @@ gdb_expect { timeout {fail "(timeout) info break marker1"} } +# See the comments in condbreak.exp for "run until breakpoint at marker1" +# for an explanation of the xfail below. send_gdb "continue\n" gdb_expect { -re "Breakpoint \[0-9\]*, marker1.*$gdb_prompt $"\ {pass "continue to break marker1"} + -re "Breakpoint \[0-9\]*, $hex in marker1.*$gdb_prompt $"\ + {xfail "continue to break marker1"} -re "$gdb_prompt $"\ {fail "continue to break marker1"} timeout {fail "(timeout) continue to break marker1"} @@ -141,10 +145,14 @@ gdb_expect { timeout {fail "(timeout) info auto-disabled break marker2"} } +# See the comments in condbreak.exp for "run until breakpoint at marker1" +# for an explanation of the xfail below. send_gdb "continue\n" gdb_expect { -re "Breakpoint \[0-9\]*, marker2.*$gdb_prompt $"\ {pass "continue to auto-disabled break marker2"} + -re "Breakpoint \[0-9\]*, $hex in marker2.*$gdb_prompt $"\ + {xfail "continue to auto-disabled break marker2"} -re "$gdb_prompt $"\ {fail "continue to auto-disabled break marker2"} timeout {fail "(timeout) continue to auto-disabled break marker2"} @@ -325,13 +333,17 @@ gdb_expect { gdb_continue_to_end "no stop at ignored break marker1" rerun_to_main +# See the comments in condbreak.exp for "run until breakpoint at marker1" +# for an explanation of the xfail below. send_gdb "continue\n" gdb_expect { -re "Breakpoint \[0-9\]*, marker1.*$gdb_prompt $"\ - {pass "continue to break marker1"} + {pass "continue to break marker1, 2nd time"} + -re "Breakpoint \[0-9\]*, $hex in marker1.*$gdb_prompt $"\ + {xfail "continue to break marker1, 2nd time"} -re "$gdb_prompt $"\ - {fail "continue to break marker1"} - timeout {fail "(timeout) continue to break marker1"} + {fail "continue to break marker1, 2nd time"} + timeout {fail "(timeout) continue to break marker1, 2nd time"} } # Verify that we can specify both an ignore count and an auto-delete. diff --git a/gdb/testsuite/gdb.base/funcargs.exp b/gdb/testsuite/gdb.base/funcargs.exp index baa4ab6d5a9..d8f58c49ec1 100644 --- a/gdb/testsuite/gdb.base/funcargs.exp +++ b/gdb/testsuite/gdb.base/funcargs.exp @@ -527,7 +527,12 @@ $gdb_prompt $" { gdb_continue call6b if {$hp_cc_compiler} {setup_xfail hppa2.0w-*-*} - if [gdb_test "backtrace 100" ".* call6b \\(s=1, i=2, l=3, f=4, d=5, uc=98 'b', us=6, ui=7, ul=8\\) .*\[\r\n\]*.* call6a \\(c=97 'a', s=1, i=2, l=3, f=4, d=5, uc=98 'b', us=6, ui=7, ul=8\\) .*\[\r\n\].* main \\(.*\\) .*\[\r\n\]" "backtrace from call6b"] { + send_gdb "backtrace 100\n" + if [gdb_expect_list "backtrace from call6b" ".*$gdb_prompt $" { + ".*\[\r\n\]#0 .* call6b \\(s=1, i=2, l=3, f=4, d=5, uc=98 'b', us=6, ui=7, ul=8\\) " + ".*\[\r\n\]#1 .* call6a \\(c=97 'a', s=1, i=2, l=3, f=4, d=5, uc=98 'b', us=6, ui=7, ul=8\\) " + ".*\[\r\n\]#2 .* main \\(.*\\) " + } ] { gdb_suppress_tests; } @@ -537,7 +542,13 @@ $gdb_prompt $" { gdb_continue call6c if {$hp_cc_compiler} {setup_xfail hppa2.0w-*-*} - if [gdb_test "backtrace 100" ".* call6c \\(i=2, l=3, f=4, d=5, uc=98 'b', us=6, ui=7, ul=8\\) .*\[\r\n\].* call6b \\(s=1, i=2, l=3, f=4, d=5, uc=98 'b', us=6, ui=7, ul=8\\) .*\[\r\n\].* call6a \\(c=97 'a', s=1, i=2, l=3, f=4, d=5, uc=98 'b', us=6, ui=7, ul=8\\) .*\[\r\n].* main \\(.*\\) .*" "backtrace from call6c"] { + send_gdb "backtrace 100\n" + if [gdb_expect_list "backtrace from call6c" ".*$gdb_prompt $" { + ".*\[\r\n\]#0 .* call6c \\(i=2, l=3, f=4, d=5, uc=98 'b', us=6, ui=7, ul=8\\) " + ".*\[\r\n\]#1 .* call6b \\(s=1, i=2, l=3, f=4, d=5, uc=98 'b', us=6, ui=7, ul=8\\) " + ".*\[\r\n\]#2 .* call6a \\(c=97 'a', s=1, i=2, l=3, f=4, d=5, uc=98 'b', us=6, ui=7, ul=8\\) " + ".*\[\r\n\]#3 .* main \\(.*\\) " + } ] { gdb_suppress_tests; } # Continue; should stop at call6d and print actual arguments. @@ -546,7 +557,14 @@ $gdb_prompt $" { gdb_continue call6d if {$hp_cc_compiler} {setup_xfail hppa2.0w-*-*} - if [gdb_test "backtrace 100" ".* call6d \\(l=3, f=4, d=5, uc=98 'b', us=6, ui=7, ul=8\\) .*\[\r\n\].* call6c \\(i=2, l=3, f=4, d=5, uc=98 'b', us=6, ui=7, ul=8\\) .*\[\r\n\].* call6b \\(s=1, i=2, l=3, f=4, d=5, uc=98 'b', us=6, ui=7, ul=8\\) .*\[\r\n\].* call6a \\(c=97 'a', s=1, i=2, l=3, f=4, d=5, uc=98 'b', us=6, ui=7, ul=8\\) .*\[\r\n].* main \\(.*\\) .*" "backtrace from call6d"] { + send_gdb "backtrace 100\n" + if [gdb_expect_list "backtrace from call6d" ".*$gdb_prompt $" { + ".*\[\r\n\]#0 .* call6d \\(l=3, f=4, d=5, uc=98 'b', us=6, ui=7, ul=8\\) " + ".*\[\r\n\]#1 .* call6c \\(i=2, l=3, f=4, d=5, uc=98 'b', us=6, ui=7, ul=8\\) " + ".*\[\r\n\]#2 .* call6b \\(s=1, i=2, l=3, f=4, d=5, uc=98 'b', us=6, ui=7, ul=8\\) " + ".*\[\r\n\]#3 .* call6a \\(c=97 'a', s=1, i=2, l=3, f=4, d=5, uc=98 'b', us=6, ui=7, ul=8\\) " + ".*\[\r\n\]#4 .* main \\(.*\\) " + } ] { gdb_suppress_tests; } @@ -556,7 +574,15 @@ $gdb_prompt $" { gdb_continue call6e if {$hp_cc_compiler} {setup_xfail hppa2.0w-*-*} - if [gdb_test "backtrace 100" ".* call6e \\(f=4, d=5, uc=98 'b', us=6, ui=7, ul=8\\) .*\[\r\n\].* call6d \\(l=3, f=4, d=5, uc=98 'b', us=6, ui=7, ul=8\\) .*\[\r\n\].* call6c \\(i=2, l=3, f=4, d=5, uc=98 'b', us=6, ui=7, ul=8\\) .*\[\r\n\].* call6b \\(s=1, i=2, l=3, f=4, d=5, uc=98 'b', us=6, ui=7, ul=8\\) .*\[\r\n\].* call6a \\(c=97 'a', s=1, i=2, l=3, f=4, d=5, uc=98 'b', us=6, ui=7, ul=8\\) .*\[\r\n].* main \\(.*\\) .*" "backtrace from call6e"] { + send_gdb "backtrace 100\n" + if [gdb_expect_list "backtrace from call6e" ".*$gdb_prompt $" { + ".*\[\r\n\]#0 .* call6e \\(f=4, d=5, uc=98 'b', us=6, ui=7, ul=8\\) " + ".*\[\r\n\]#1 .* call6d \\(l=3, f=4, d=5, uc=98 'b', us=6, ui=7, ul=8\\) " + ".*\[\r\n\]#2 .* call6c \\(i=2, l=3, f=4, d=5, uc=98 'b', us=6, ui=7, ul=8\\) " + ".*\[\r\n\]#3 .* call6b \\(s=1, i=2, l=3, f=4, d=5, uc=98 'b', us=6, ui=7, ul=8\\) " + ".*\[\r\n\]#4 .* call6a \\(c=97 'a', s=1, i=2, l=3, f=4, d=5, uc=98 'b', us=6, ui=7, ul=8\\) " + ".*\[\r\n\]#5 .* main \\(.*\\) " + } ] { gdb_suppress_tests; } @@ -566,7 +592,16 @@ $gdb_prompt $" { gdb_continue call6f if {$hp_cc_compiler} {setup_xfail hppa2.0w-*-*} - if [gdb_test "backtrace 100" ".* call6f \\(d=5, uc=98 'b', us=6, ui=7, ul=8\\) .*\[\r\n\].* call6e \\(f=4, d=5, uc=98 'b', us=6, ui=7, ul=8\\) .*\[\r\n\].* call6d \\(l=3, f=4, d=5, uc=98 'b', us=6, ui=7, ul=8\\) .*\[\r\n\].* call6c \\(i=2, l=3, f=4, d=5, uc=98 'b', us=6, ui=7, ul=8\\) .*\[\r\n\].* call6b \\(s=1, i=2, l=3, f=4, d=5, uc=98 'b', us=6, ui=7, ul=8\\) .*\[\r\n\].* call6a \\(c=97 'a', s=1, i=2, l=3, f=4, d=5, uc=98 'b', us=6, ui=7, ul=8\\) .*\[\r\n].* main \\(.*\\) .*" "backtrace from call6f"] { + send_gdb "backtrace 100\n" + if [gdb_expect_list "backtrace from call6f" ".*$gdb_prompt $" { + ".*\[\r\n\]#0 .* call6f \\(d=5, uc=98 'b', us=6, ui=7, ul=8\\) " + ".*\[\r\n\]#1 .* call6e \\(f=4, d=5, uc=98 'b', us=6, ui=7, ul=8\\) " + ".*\[\r\n\]#2 .* call6d \\(l=3, f=4, d=5, uc=98 'b', us=6, ui=7, ul=8\\) " + ".*\[\r\n\]#3 .* call6c \\(i=2, l=3, f=4, d=5, uc=98 'b', us=6, ui=7, ul=8\\) " + ".*\[\r\n\]#4 .* call6b \\(s=1, i=2, l=3, f=4, d=5, uc=98 'b', us=6, ui=7, ul=8\\) " + ".*\[\r\n\]#5 .* call6a \\(c=97 'a', s=1, i=2, l=3, f=4, d=5, uc=98 'b', us=6, ui=7, ul=8\\) " + ".*\[\r\n\]#6 .* main \\(.*\\) " + } ] { gdb_suppress_tests; } @@ -576,7 +611,17 @@ $gdb_prompt $" { gdb_continue call6g if {$hp_cc_compiler} {setup_xfail hppa2.0w-*-*} - if [gdb_test "backtrace 100" ".* call6g \\(uc=98 'b', us=6, ui=7, ul=8\\) .*\[\r\n\].* call6f \\(d=5, uc=98 'b', us=6, ui=7, ul=8\\) .*\[\r\n\].* call6e \\(f=4, d=5, uc=98 'b', us=6, ui=7, ul=8\\) .*\[\r\n\].* call6d \\(l=3, f=4, d=5, uc=98 'b', us=6, ui=7, ul=8\\) .*\[\r\n\].* call6c \\(i=2, l=3, f=4, d=5, uc=98 'b', us=6, ui=7, ul=8\\) .*\[\r\n\].* call6b \\(s=1, i=2, l=3, f=4, d=5, uc=98 'b', us=6, ui=7, ul=8\\) .*\[\r\n\].* call6a \\(c=97 'a', s=1, i=2, l=3, f=4, d=5, uc=98 'b', us=6, ui=7, ul=8\\) .*\[\r\n].* main \\(.*\\) .*" "backtrace from call6g"] { + send_gdb "backtrace 100\n" + if [gdb_expect_list "backtrace from call6g" ".*$gdb_prompt $" { + ".*\[\r\n\]#0 .* call6g \\(uc=98 'b', us=6, ui=7, ul=8\\) " + ".*\[\r\n\]#1 .* call6f \\(d=5, uc=98 'b', us=6, ui=7, ul=8\\) " + ".*\[\r\n\]#2 .* call6e \\(f=4, d=5, uc=98 'b', us=6, ui=7, ul=8\\) " + ".*\[\r\n\]#3 .* call6d \\(l=3, f=4, d=5, uc=98 'b', us=6, ui=7, ul=8\\) " + ".*\[\r\n\]#4 .* call6c \\(i=2, l=3, f=4, d=5, uc=98 'b', us=6, ui=7, ul=8\\) " + ".*\[\r\n\]#5 .* call6b \\(s=1, i=2, l=3, f=4, d=5, uc=98 'b', us=6, ui=7, ul=8\\) " + ".*\[\r\n\]#6 .* call6a \\(c=97 'a', s=1, i=2, l=3, f=4, d=5, uc=98 'b', us=6, ui=7, ul=8\\) " + ".*\[\r\n\]#7 .* main \\(.*\\) " + } ] { gdb_suppress_tests; } @@ -586,7 +631,18 @@ $gdb_prompt $" { gdb_continue call6h if {$hp_cc_compiler} {setup_xfail hppa2.0w-*-*} - if [gdb_test "backtrace 100" ".* call6h \\(us=6, ui=7, ul=8\\) .*\[\r\n\].* call6g \\(uc=98 'b', us=6, ui=7, ul=8\\) .*\[\r\n\].* call6f \\(d=5, uc=98 'b', us=6, ui=7, ul=8\\) .*\[\r\n\].* call6e \\(f=4, d=5, uc=98 'b', us=6, ui=7, ul=8\\) .*\[\r\n\].* call6d \\(l=3, f=4, d=5, uc=98 'b', us=6, ui=7, ul=8\\) .*\[\r\n\].* call6c \\(i=2, l=3, f=4, d=5, uc=98 'b', us=6, ui=7, ul=8\\) .*\[\r\n\].* call6b \\(s=1, i=2, l=3, f=4, d=5, uc=98 'b', us=6, ui=7, ul=8\\) .*\[\r\n\].* call6a \\(c=97 'a', s=1, i=2, l=3, f=4, d=5, uc=98 'b', us=6, ui=7, ul=8\\) .*\[\r\n].* main \\(.*\\) .*" "backtrace from call6h"] { + send_gdb "backtrace 100\n" + if [gdb_expect_list "backtrace from call6h" ".*$gdb_prompt $" { + ".*\[\r\n\]#0 .* call6h \\(us=6, ui=7, ul=8\\) " + ".*\[\r\n\]#1 .* call6g \\(uc=98 'b', us=6, ui=7, ul=8\\) " + ".*\[\r\n\]#2 .* call6f \\(d=5, uc=98 'b', us=6, ui=7, ul=8\\) " + ".*\[\r\n\]#3 .* call6e \\(f=4, d=5, uc=98 'b', us=6, ui=7, ul=8\\) " + ".*\[\r\n\]#4 .* call6d \\(l=3, f=4, d=5, uc=98 'b', us=6, ui=7, ul=8\\) " + ".*\[\r\n\]#5 .* call6c \\(i=2, l=3, f=4, d=5, uc=98 'b', us=6, ui=7, ul=8\\) " + ".*\[\r\n\]#6 .* call6b \\(s=1, i=2, l=3, f=4, d=5, uc=98 'b', us=6, ui=7, ul=8\\) " + ".*\[\r\n\]#7 .* call6a \\(c=97 'a', s=1, i=2, l=3, f=4, d=5, uc=98 'b', us=6, ui=7, ul=8\\) " + ".*\[\r\n\]#8 .* main \\(.*\\) " + } ] { gdb_suppress_tests; } @@ -603,7 +659,19 @@ $gdb_prompt $" { gdb_continue call6i if {$hp_cc_compiler} {setup_xfail hppa2.0w-*-*} - if [gdb_test "backtrace 100" ".* call6i \\(ui=7, ul=8\\) .*\[\r\n\].* call6h \\(us=6, ui=7, ul=8\\) .*\[\r\n\].* call6g \\(uc=98 'b', us=6, ui=7, ul=8\\) .*\[\r\n\].* call6f \\(d=5, uc=98 'b', us=6, ui=7, ul=8\\) .*\[\r\n\].* call6e \\(f=4, d=5, uc=98 'b', us=6, ui=7, ul=8\\) .*\[\r\n\].* call6d \\(l=3, f=4, d=5, uc=98 'b', us=6, ui=7, ul=8\\) .*\[\r\n\].* call6c \\(i=2, l=3, f=4, d=5, uc=98 'b', us=6, ui=7, ul=8\\) .*\[\r\n\].* call6b \\(s=1, i=2, l=3, f=4, d=5, uc=98 'b', us=6, ui=7, ul=8\\) .*\[\r\n\].* call6a \\(c=97 'a', s=1, i=2, l=3, f=4, d=5, uc=98 'b', us=6, ui=7, ul=8\\) .*\[\r\n].* main \\(.*\\) .*" "backtrace from call6i"] { + send_gdb "backtrace 100\n" + if [gdb_expect_list "backtrace from call6i" ".*$gdb_prompt $" { + ".*\[\r\n\]#0 .* call6i \\(ui=7, ul=8\\) " + ".*\[\r\n\]#1 .* call6h \\(us=6, ui=7, ul=8\\) " + ".*\[\r\n\]#2 .* call6g \\(uc=98 'b', us=6, ui=7, ul=8\\) " + ".*\[\r\n\]#3 .* call6f \\(d=5, uc=98 'b', us=6, ui=7, ul=8\\) " + ".*\[\r\n\]#4 .* call6e \\(f=4, d=5, uc=98 'b', us=6, ui=7, ul=8\\) " + ".*\[\r\n\]#5 .* call6d \\(l=3, f=4, d=5, uc=98 'b', us=6, ui=7, ul=8\\) " + ".*\[\r\n\]#6 .* call6c \\(i=2, l=3, f=4, d=5, uc=98 'b', us=6, ui=7, ul=8\\) " + ".*\[\r\n\]#7 .* call6b \\(s=1, i=2, l=3, f=4, d=5, uc=98 'b', us=6, ui=7, ul=8\\) " + ".*\[\r\n\]#8 .* call6a \\(c=97 'a', s=1, i=2, l=3, f=4, d=5, uc=98 'b', us=6, ui=7, ul=8\\) " + ".*\[\r\n\]#9 .* main \\(.*\\) " + } ] { gdb_suppress_tests; } @@ -613,7 +681,20 @@ $gdb_prompt $" { gdb_continue call6j if {$hp_cc_compiler} {setup_xfail hppa2.0w-*-*} - if [gdb_test "backtrace 100" ".* call6j \\(ul=8\\) .*\[\r\n\].* call6i \\(ui=7, ul=8\\) .*\[\r\n\].* call6h \\(us=6, ui=7, ul=8\\) .*\[\r\n\].* call6g \\(uc=98 'b', us=6, ui=7, ul=8\\) .*\[\r\n\].* call6f \\(d=5, uc=98 'b', us=6, ui=7, ul=8\\) .*\[\r\n\].* call6e \\(f=4, d=5, uc=98 'b', us=6, ui=7, ul=8\\) .*\[\r\n\].* call6d \\(l=3, f=4, d=5, uc=98 'b', us=6, ui=7, ul=8\\) .*\[\r\n\].* call6c \\(i=2, l=3, f=4, d=5, uc=98 'b', us=6, ui=7, ul=8\\) .*\[\r\n\].* call6b \\(s=1, i=2, l=3, f=4, d=5, uc=98 'b', us=6, ui=7, ul=8\\) .*\[\r\n\].* call6a \\(c=97 'a', s=1, i=2, l=3, f=4, d=5, uc=98 'b', us=6, ui=7, ul=8\\) .*\[\r\n].* main \\(.*\\) .*" "backtrace from call6j"] { + send_gdb "backtrace 100\n" + if [gdb_expect_list "backtrace from call6j" ".*$gdb_prompt $" { + ".*\[\r\n\]#0 .* call6j \\(ul=8\\) " + ".*\[\r\n\]#1 .* call6i \\(ui=7, ul=8\\) " + ".*\[\r\n\]#2 .* call6h \\(us=6, ui=7, ul=8\\) " + ".*\[\r\n\]#3 .* call6g \\(uc=98 'b', us=6, ui=7, ul=8\\) " + ".*\[\r\n\]#4 .* call6f \\(d=5, uc=98 'b', us=6, ui=7, ul=8\\) " + ".*\[\r\n\]#5 .* call6e \\(f=4, d=5, uc=98 'b', us=6, ui=7, ul=8\\) " + ".*\[\r\n\]#6 .* call6d \\(l=3, f=4, d=5, uc=98 'b', us=6, ui=7, ul=8\\) " + ".*\[\r\n\]#7 .* call6c \\(i=2, l=3, f=4, d=5, uc=98 'b', us=6, ui=7, ul=8\\) " + ".*\[\r\n\]#8 .* call6b \\(s=1, i=2, l=3, f=4, d=5, uc=98 'b', us=6, ui=7, ul=8\\) " + ".*\[\r\n\]#9 .* call6a \\(c=97 'a', s=1, i=2, l=3, f=4, d=5, uc=98 'b', us=6, ui=7, ul=8\\) " + ".*\[\r\n\]#10 .* main \\(.*\\) " + } ] { gdb_suppress_tests; } @@ -625,7 +706,21 @@ $gdb_prompt $" { gdb_continue call6k if {$hp_cc_compiler} {setup_xfail hppa2.0w-*-*} - if [gdb_test "backtrace 100" ".* call6k \\(\\) .*\[\r\n\].* call6j \\(ul=8\\) .*\[\r\n\].* call6i \\(ui=7, ul=8\\) .*\[\r\n\].* call6h \\(us=6, ui=7, ul=8\\) .*\[\r\n\].* call6g \\(uc=98 'b', us=6, ui=7, ul=8\\) .*\[\r\n\].* call6f \\(d=5, uc=98 'b', us=6, ui=7, ul=8\\) .*\[\r\n\].* call6e \\(f=4, d=5, uc=98 'b', us=6, ui=7, ul=8\\) .*\[\r\n\].* call6d \\(l=3, f=4, d=5, uc=98 'b', us=6, ui=7, ul=8\\) .*\[\r\n\].* call6c \\(i=2, l=3, f=4, d=5, uc=98 'b', us=6, ui=7, ul=8\\) .*\[\r\n\].* call6b \\(s=1, i=2, l=3, f=4, d=5, uc=98 'b', us=6, ui=7, ul=8\\) .*\[\r\n\].* call6a \\(c=97 'a', s=1, i=2, l=3, f=4, d=5, uc=98 'b', us=6, ui=7, ul=8\\) .*\[\r\n].* main \\(.*\\) .*" "backtrace from call6k"] { + send_gdb "backtrace 100\n" + if [gdb_expect_list "backtrace from call6k" ".*$gdb_prompt $" { + ".*\[\r\n\]#0 .* call6k \\(\\) " + ".*\[\r\n\]#1 .* call6j \\(ul=8\\) " + ".*\[\r\n\]#2 .* call6i \\(ui=7, ul=8\\) " + ".*\[\r\n\]#3 .* call6h \\(us=6, ui=7, ul=8\\) " + ".*\[\r\n\]#4 .* call6g \\(uc=98 'b', us=6, ui=7, ul=8\\) " + ".*\[\r\n\]#5 .* call6f \\(d=5, uc=98 'b', us=6, ui=7, ul=8\\) " + ".*\[\r\n\]#6 .* call6e \\(f=4, d=5, uc=98 'b', us=6, ui=7, ul=8\\) " + ".*\[\r\n\]#7 .* call6d \\(l=3, f=4, d=5, uc=98 'b', us=6, ui=7, ul=8\\) " + ".*\[\r\n\]#8 .* call6c \\(i=2, l=3, f=4, d=5, uc=98 'b', us=6, ui=7, ul=8\\) " + ".*\[\r\n\]#9 .* call6b \\(s=1, i=2, l=3, f=4, d=5, uc=98 'b', us=6, ui=7, ul=8\\) " + ".*\[\r\n\]#10 .* call6a \\(c=97 'a', s=1, i=2, l=3, f=4, d=5, uc=98 'b', us=6, ui=7, ul=8\\) " + ".*\[\r\n\]#11 .* main \\(.*\\) " + } ] { gdb_suppress_tests; } gdb_stop_suppressing_tests; @@ -699,43 +794,99 @@ $gdb_prompt $" { if {$gcc_compiled} then { setup_xfail "rs6000-*-*" } - gdb_test "backtrace 100" ".* call7b \\(i=2, s=1, l=3, f=4, uc=98 'b', d=5, us=6, ul=8, ui=7, c=97 'a'\\) .*\[\r\n\].* call7a \\(c=97 'a', i=2, s=1, l=3, f=4, uc=98 'b', d=5, us=6, ul=8, ui=7\\) .*\[\r\n\].* main \\(.*\\) .*\[\r\n\].*" "backtrace from call7b" + send_gdb "backtrace 100\n" + gdb_expect_list "backtrace from call7b" ".*$gdb_prompt $" { + ".*\[\r\n\]#0 .* call7b \\(i=2, s=1, l=3, f=4, uc=98 'b', d=5, us=6, ul=8, ui=7, c=97 'a'\\) " + ".*\[\r\n\]#1 .* call7a \\(c=97 'a', i=2, s=1, l=3, f=4, uc=98 'b', d=5, us=6, ul=8, ui=7\\) " + ".*\[\r\n\]#2 .* main \\(.*\\) " + } # Continue; should stop at call7c and print actual arguments. # Print backtrace. gdb_continue call7c - gdb_test "backtrace 100" ".* call7c \\(s=1, l=3, f=4, uc=98 'b', d=5, us=6, ul=8, ui=7, c=97 'a', i=2\\) .*\[\r\n\].* call7b \\(i=2, s=1, l=3, f=4, uc=98 'b', d=5, us=6, ul=8, ui=7, c=97 'a'\\) .*\[\r\n\].* call7a \\(c=97 'a', i=2, s=1, l=3, f=4, uc=98 'b', d=5, us=6, ul=8, ui=7\\) .*\[\r\n\].* main \\(.*\\) .*\[\r\n\].*" "backtrace from call7c" + send_gdb "backtrace 100\n" + gdb_expect_list "backtrace from call7c" ".*$gdb_prompt $" { + ".*\[\r\n\]#0 .* call7c \\(s=1, l=3, f=4, uc=98 'b', d=5, us=6, ul=8, ui=7, c=97 'a', i=2\\) " + ".*\[\r\n\]#1 .* call7b \\(i=2, s=1, l=3, f=4, uc=98 'b', d=5, us=6, ul=8, ui=7, c=97 'a'\\) " + ".*\[\r\n\]#2 .* call7a \\(c=97 'a', i=2, s=1, l=3, f=4, uc=98 'b', d=5, us=6, ul=8, ui=7\\) " + ".*\[\r\n\]#3 .* main \\(.*\\) " + } # Continue; should stop at call7d and print actual arguments. # Print backtrace. gdb_continue call7d - gdb_test "backtrace 100" ".* call7d \\(l=3, f=4, uc=98 'b', d=5, us=6, ul=8, ui=7, c=97 'a', i=2, s=1\\) .*\[\r\n\].* call7c \\(s=1, l=3, f=4, uc=98 'b', d=5, us=6, ul=8, ui=7, c=97 'a', i=2\\) .*\[\r\n\].* call7b \\(i=2, s=1, l=3, f=4, uc=98 'b', d=5, us=6, ul=8, ui=7, c=97 'a'\\) .*\[\r\n\].* call7a \\(c=97 'a', i=2, s=1, l=3, f=4, uc=98 'b', d=5, us=6, ul=8, ui=7\\) .*\[\r\n\].* main \\(.*\\) .*\[\r\n\].*" "backtrace from call7d" + send_gdb "backtrace 100\n" + gdb_expect_list "backtrace from call7d" ".*$gdb_prompt $" { + ".*\[\r\n\]#0 .* call7d \\(l=3, f=4, uc=98 'b', d=5, us=6, ul=8, ui=7, c=97 'a', i=2, s=1\\) " + ".*\[\r\n\]#1 .* call7c \\(s=1, l=3, f=4, uc=98 'b', d=5, us=6, ul=8, ui=7, c=97 'a', i=2\\) " + ".*\[\r\n\]#2 .* call7b \\(i=2, s=1, l=3, f=4, uc=98 'b', d=5, us=6, ul=8, ui=7, c=97 'a'\\) " + ".*\[\r\n\]#3 .* call7a \\(c=97 'a', i=2, s=1, l=3, f=4, uc=98 'b', d=5, us=6, ul=8, ui=7\\) " + ".*\[\r\n\]#4 .* main \\(.*\\) " + } gdb_continue call7e - gdb_test "backtrace 100" ".* call7e \\(f=4, uc=98 'b', d=5, us=6, ul=8, ui=7, c=97 'a', i=2, s=1, l=3\\) .*\[\r\n\].* call7d \\(l=3, f=4, uc=98 'b', d=5, us=6, ul=8, ui=7, c=97 'a', i=2, s=1\\) .*\[\r\n\].* call7c \\(s=1, l=3, f=4, uc=98 'b', d=5, us=6, ul=8, ui=7, c=97 'a', i=2\\) .*\[\r\n\].* call7b \\(i=2, s=1, l=3, f=4, uc=98 'b', d=5, us=6, ul=8, ui=7, c=97 'a'\\) .*\[\r\n\].* call7a \\(c=97 'a', i=2, s=1, l=3, f=4, uc=98 'b', d=5, us=6, ul=8, ui=7\\) .*\[\r\n\].* main \\(.*\\) .*\[\r\n\].*" "backtrace from call7e" + send_gdb "backtrace 100\n" + gdb_expect_list "backtrace from call7e" ".*$gdb_prompt $" { + ".*\[\r\n\]#0 .* call7e \\(f=4, uc=98 'b', d=5, us=6, ul=8, ui=7, c=97 'a', i=2, s=1, l=3\\) " + ".*\[\r\n\]#1 .* call7d \\(l=3, f=4, uc=98 'b', d=5, us=6, ul=8, ui=7, c=97 'a', i=2, s=1\\) " + ".*\[\r\n\]#2 .* call7c \\(s=1, l=3, f=4, uc=98 'b', d=5, us=6, ul=8, ui=7, c=97 'a', i=2\\) " + ".*\[\r\n\]#3 .* call7b \\(i=2, s=1, l=3, f=4, uc=98 'b', d=5, us=6, ul=8, ui=7, c=97 'a'\\) " + ".*\[\r\n\]#4 .* call7a \\(c=97 'a', i=2, s=1, l=3, f=4, uc=98 'b', d=5, us=6, ul=8, ui=7\\) " + ".*\[\r\n\]#5 .* main \\(.*\\) " + } # Continue; should stop at call7f and print actual arguments. # Print backtrace. gdb_continue call7f - gdb_test "backtrace 100" ".* call7f \\(uc=98 'b', d=5, us=6, ul=8, ui=7, c=97 'a', i=2, s=1, l=3, f=4\\) .*\[\r\n\].* call7e \\(f=4, uc=98 'b', d=5, us=6, ul=8, ui=7, c=97 'a', i=2, s=1, l=3\\) .*\[\r\n\].* call7d \\(l=3, f=4, uc=98 'b', d=5, us=6, ul=8, ui=7, c=97 'a', i=2, s=1\\) .*\[\r\n\].* call7c \\(s=1, l=3, f=4, uc=98 'b', d=5, us=6, ul=8, ui=7, c=97 'a', i=2\\) .*\[\r\n\].* call7b \\(i=2, s=1, l=3, f=4, uc=98 'b', d=5, us=6, ul=8, ui=7, c=97 'a'\\) .*\[\r\n\].* call7a \\(c=97 'a', i=2, s=1, l=3, f=4, uc=98 'b', d=5, us=6, ul=8, ui=7\\) .*\[\r\n\].* main \\(.*\\) .*\[\r\n\].*" "backtrace from call7f" + send_gdb "backtrace 100\n" + gdb_expect_list "backtrace from call7f" ".*$gdb_prompt $" { + ".*\[\r\n\]#0 .* call7f \\(uc=98 'b', d=5, us=6, ul=8, ui=7, c=97 'a', i=2, s=1, l=3, f=4\\) " + ".*\[\r\n\]#1 .* call7e \\(f=4, uc=98 'b', d=5, us=6, ul=8, ui=7, c=97 'a', i=2, s=1, l=3\\) " + ".*\[\r\n\]#2 .* call7d \\(l=3, f=4, uc=98 'b', d=5, us=6, ul=8, ui=7, c=97 'a', i=2, s=1\\) " + ".*\[\r\n\]#3 .* call7c \\(s=1, l=3, f=4, uc=98 'b', d=5, us=6, ul=8, ui=7, c=97 'a', i=2\\) " + ".*\[\r\n\]#4 .* call7b \\(i=2, s=1, l=3, f=4, uc=98 'b', d=5, us=6, ul=8, ui=7, c=97 'a'\\) " + ".*\[\r\n\]#5 .* call7a \\(c=97 'a', i=2, s=1, l=3, f=4, uc=98 'b', d=5, us=6, ul=8, ui=7\\) " + ".*\[\r\n\]#6 .* main \\(.*\\) " + } # Continue; should stop at call7g and print actual arguments. # Print backtrace. gdb_continue call7g - gdb_test "backtrace 100" ".* call7g \\(d=5, us=6, ul=8, ui=7, c=97 'a', i=2, s=1, l=3, f=4, uc=98 'b'\\) .*\[\r\n\].* call7f \\(uc=98 'b', d=5, us=6, ul=8, ui=7, c=97 'a', i=2, s=1, l=3, f=4\\) .*\[\r\n\].* call7e \\(f=4, uc=98 'b', d=5, us=6, ul=8, ui=7, c=97 'a', i=2, s=1, l=3\\) .*\[\r\n\].* call7d \\(l=3, f=4, uc=98 'b', d=5, us=6, ul=8, ui=7, c=97 'a', i=2, s=1\\) .*\[\r\n\].* call7c \\(s=1, l=3, f=4, uc=98 'b', d=5, us=6, ul=8, ui=7, c=97 'a', i=2\\) .*\[\r\n\].* call7b \\(i=2, s=1, l=3, f=4, uc=98 'b', d=5, us=6, ul=8, ui=7, c=97 'a'\\) .*\[\r\n\].* call7a \\(c=97 'a', i=2, s=1, l=3, f=4, uc=98 'b', d=5, us=6, ul=8, ui=7\\) .*\[\r\n\].* main \\(.*\\) .*\[\r\n\].*" "backtrace from call7g" + send_gdb "backtrace 100\n" + gdb_expect_list "backtrace from call7g" ".*$gdb_prompt $" { + ".*\[\r\n\]#0 .* call7g \\(d=5, us=6, ul=8, ui=7, c=97 'a', i=2, s=1, l=3, f=4, uc=98 'b'\\) " + ".*\[\r\n\]#1 .* call7f \\(uc=98 'b', d=5, us=6, ul=8, ui=7, c=97 'a', i=2, s=1, l=3, f=4\\) " + ".*\[\r\n\]#2 .* call7e \\(f=4, uc=98 'b', d=5, us=6, ul=8, ui=7, c=97 'a', i=2, s=1, l=3\\) " + ".*\[\r\n\]#3 .* call7d \\(l=3, f=4, uc=98 'b', d=5, us=6, ul=8, ui=7, c=97 'a', i=2, s=1\\) " + ".*\[\r\n\]#4 .* call7c \\(s=1, l=3, f=4, uc=98 'b', d=5, us=6, ul=8, ui=7, c=97 'a', i=2\\) " + ".*\[\r\n\]#5 .* call7b \\(i=2, s=1, l=3, f=4, uc=98 'b', d=5, us=6, ul=8, ui=7, c=97 'a'\\) " + ".*\[\r\n\]#6 .* call7a \\(c=97 'a', i=2, s=1, l=3, f=4, uc=98 'b', d=5, us=6, ul=8, ui=7\\) " + ".*\[\r\n\]#7 .* main \\(.*\\) " + } gdb_continue call7h - gdb_test "backtrace 100" ".* call7h \\(us=6, ul=8, ui=7, c=97 'a', i=2, s=1, l=3, f=4, uc=98 'b', d=5\\) .*\[\r\n\].* call7g \\(d=5, us=6, ul=8, ui=7, c=97 'a', i=2, s=1, l=3, f=4, uc=98 'b'\\) .*\[\r\n\].* call7f \\(uc=98 'b', d=5, us=6, ul=8, ui=7, c=97 'a', i=2, s=1, l=3, f=4\\) .*\[\r\n\].* call7e \\(f=4, uc=98 'b', d=5, us=6, ul=8, ui=7, c=97 'a', i=2, s=1, l=3\\) .*\[\r\n\].* call7d \\(l=3, f=4, uc=98 'b', d=5, us=6, ul=8, ui=7, c=97 'a', i=2, s=1\\) .*\[\r\n\].* call7c \\(s=1, l=3, f=4, uc=98 'b', d=5, us=6, ul=8, ui=7, c=97 'a', i=2\\) .*\[\r\n\].* call7b \\(i=2, s=1, l=3, f=4, uc=98 'b', d=5, us=6, ul=8, ui=7, c=97 'a'\\) .*\[\r\n\].* call7a \\(c=97 'a', i=2, s=1, l=3, f=4, uc=98 'b', d=5, us=6, ul=8, ui=7\\) .*\[\r\n\].* main \\(.*\\) .*\[\r\n\].*" "backtrace from call7h" + send_gdb "backtrace 100\n" + gdb_expect_list "backtrace from call7h" ".*$gdb_prompt $" { + ".*\[\r\n\]#0 .* call7h \\(us=6, ul=8, ui=7, c=97 'a', i=2, s=1, l=3, f=4, uc=98 'b', d=5\\) " + ".*\[\r\n\]#1 .* call7g \\(d=5, us=6, ul=8, ui=7, c=97 'a', i=2, s=1, l=3, f=4, uc=98 'b'\\) " + ".*\[\r\n\]#2 .* call7f \\(uc=98 'b', d=5, us=6, ul=8, ui=7, c=97 'a', i=2, s=1, l=3, f=4\\) " + ".*\[\r\n\]#3 .* call7e \\(f=4, uc=98 'b', d=5, us=6, ul=8, ui=7, c=97 'a', i=2, s=1, l=3\\) " + ".*\[\r\n\]#4 .* call7d \\(l=3, f=4, uc=98 'b', d=5, us=6, ul=8, ui=7, c=97 'a', i=2, s=1\\) " + ".*\[\r\n\]#5 .* call7c \\(s=1, l=3, f=4, uc=98 'b', d=5, us=6, ul=8, ui=7, c=97 'a', i=2\\) " + ".*\[\r\n\]#6 .* call7b \\(i=2, s=1, l=3, f=4, uc=98 'b', d=5, us=6, ul=8, ui=7, c=97 'a'\\) " + ".*\[\r\n\]#7 .* call7a \\(c=97 'a', i=2, s=1, l=3, f=4, uc=98 'b', d=5, us=6, ul=8, ui=7\\) " + ".*\[\r\n\]#8 .* main \\(.*\\) " + } # monitor only allows 8 breakpoints; w89k board allows 10, so # break them up into two groups. @@ -749,14 +900,39 @@ $gdb_prompt $" { gdb_continue call7i - gdb_test "backtrace 100" ".* call7i \\(ul=8, ui=7, c=97 'a', i=2, s=1, l=3, f=4, uc=98 'b', d=5, us=6\\) .*\[\r\n\].* call7h \\(us=6, ul=8, ui=7, c=97 'a', i=2, s=1, l=3, f=4, uc=98 'b', d=5\\) .*\[\r\n\].* call7g \\(d=5, us=6, ul=8, ui=7, c=97 'a', i=2, s=1, l=3, f=4, uc=98 'b'\\) .*\[\r\n\].* call7f \\(uc=98 'b', d=5, us=6, ul=8, ui=7, c=97 'a', i=2, s=1, l=3, f=4\\) .*\[\r\n\].* call7e \\(f=4, uc=98 'b', d=5, us=6, ul=8, ui=7, c=97 'a', i=2, s=1, l=3\\) .*\[\r\n\].* call7d \\(l=3, f=4, uc=98 'b', d=5, us=6, ul=8, ui=7, c=97 'a', i=2, s=1\\) .*\[\r\n\].* call7c \\(s=1, l=3, f=4, uc=98 'b', d=5, us=6, ul=8, ui=7, c=97 'a', i=2\\) .*\[\r\n\].* call7b \\(i=2, s=1, l=3, f=4, uc=98 'b', d=5, us=6, ul=8, ui=7, c=97 'a'\\) .*\[\r\n\].* call7a \\(c=97 'a', i=2, s=1, l=3, f=4, uc=98 'b', d=5, us=6, ul=8, ui=7\\) .*\[\r\n\].* main \\(.*\\) .*\[\r\n\].*" "backtrace from call7i" + send_gdb "backtrace 100\n" + gdb_expect_list "backtrace from call7i" ".*$gdb_prompt $" { + ".*\[\r\n\]#0 .* call7i \\(ul=8, ui=7, c=97 'a', i=2, s=1, l=3, f=4, uc=98 'b', d=5, us=6\\) " + ".*\[\r\n\]#1 .* call7h \\(us=6, ul=8, ui=7, c=97 'a', i=2, s=1, l=3, f=4, uc=98 'b', d=5\\) " + ".*\[\r\n\]#2 .* call7g \\(d=5, us=6, ul=8, ui=7, c=97 'a', i=2, s=1, l=3, f=4, uc=98 'b'\\) " + ".*\[\r\n\]#3 .* call7f \\(uc=98 'b', d=5, us=6, ul=8, ui=7, c=97 'a', i=2, s=1, l=3, f=4\\) " + ".*\[\r\n\]#4 .* call7e \\(f=4, uc=98 'b', d=5, us=6, ul=8, ui=7, c=97 'a', i=2, s=1, l=3\\) " + ".*\[\r\n\]#5 .* call7d \\(l=3, f=4, uc=98 'b', d=5, us=6, ul=8, ui=7, c=97 'a', i=2, s=1\\) " + ".*\[\r\n\]#6 .* call7c \\(s=1, l=3, f=4, uc=98 'b', d=5, us=6, ul=8, ui=7, c=97 'a', i=2\\) " + ".*\[\r\n\]#7 .* call7b \\(i=2, s=1, l=3, f=4, uc=98 'b', d=5, us=6, ul=8, ui=7, c=97 'a'\\) " + ".*\[\r\n\]#8 .* call7a \\(c=97 'a', i=2, s=1, l=3, f=4, uc=98 'b', d=5, us=6, ul=8, ui=7\\) " + ".*\[\r\n\]#9 .* main \\(.*\\) " + } # Continue; should stop at call7j and print actual arguments. # Print backtrace. gdb_continue call7j - gdb_test "backtrace 100" ".* call7j \\(ui=7, c=97 'a', i=2, s=1, l=3, f=4, uc=98 'b', d=5, us=6, ul=8\\) .*\[\r\n\].* call7i \\(ul=8, ui=7, c=97 'a', i=2, s=1, l=3, f=4, uc=98 'b', d=5, us=6\\) .*\[\r\n\].* call7h \\(us=6, ul=8, ui=7, c=97 'a', i=2, s=1, l=3, f=4, uc=98 'b', d=5\\) .*\[\r\n\].* call7g \\(d=5, us=6, ul=8, ui=7, c=97 'a', i=2, s=1, l=3, f=4, uc=98 'b'\\) .*\[\r\n\].* call7f \\(uc=98 'b', d=5, us=6, ul=8, ui=7, c=97 'a', i=2, s=1, l=3, f=4\\) .*\[\r\n\].* call7e \\(f=4, uc=98 'b', d=5, us=6, ul=8, ui=7, c=97 'a', i=2, s=1, l=3\\) .*\[\r\n\].* call7d \\(l=3, f=4, uc=98 'b', d=5, us=6, ul=8, ui=7, c=97 'a', i=2, s=1\\) .*\[\r\n\].* call7c \\(s=1, l=3, f=4, uc=98 'b', d=5, us=6, ul=8, ui=7, c=97 'a', i=2\\) .*\[\r\n\].* call7b \\(i=2, s=1, l=3, f=4, uc=98 'b', d=5, us=6, ul=8, ui=7, c=97 'a'\\) .*\[\r\n\].* call7a \\(c=97 'a', i=2, s=1, l=3, f=4, uc=98 'b', d=5, us=6, ul=8, ui=7\\) .*\[\r\n\].* main \\(.*\\) .*\[\r\n\].*" "backtrace from call7j" + send_gdb "backtrace 100\n" + gdb_expect_list "backtrace from call7j" ".*$gdb_prompt $" { + ".*\[\r\n\]#0 .* call7j \\(ui=7, c=97 'a', i=2, s=1, l=3, f=4, uc=98 'b', d=5, us=6, ul=8\\) " + ".*\[\r\n\]#1 .* call7i \\(ul=8, ui=7, c=97 'a', i=2, s=1, l=3, f=4, uc=98 'b', d=5, us=6\\) " + ".*\[\r\n\]#2 .* call7h \\(us=6, ul=8, ui=7, c=97 'a', i=2, s=1, l=3, f=4, uc=98 'b', d=5\\) " + ".*\[\r\n\]#3 .* call7g \\(d=5, us=6, ul=8, ui=7, c=97 'a', i=2, s=1, l=3, f=4, uc=98 'b'\\) " + ".*\[\r\n\]#4 .* call7f \\(uc=98 'b', d=5, us=6, ul=8, ui=7, c=97 'a', i=2, s=1, l=3, f=4\\) " + ".*\[\r\n\]#5 .* call7e \\(f=4, uc=98 'b', d=5, us=6, ul=8, ui=7, c=97 'a', i=2, s=1, l=3\\) " + ".*\[\r\n\]#6 .* call7d \\(l=3, f=4, uc=98 'b', d=5, us=6, ul=8, ui=7, c=97 'a', i=2, s=1\\) " + ".*\[\r\n\]#7 .* call7c \\(s=1, l=3, f=4, uc=98 'b', d=5, us=6, ul=8, ui=7, c=97 'a', i=2\\) " + ".*\[\r\n\]#8 .* call7b \\(i=2, s=1, l=3, f=4, uc=98 'b', d=5, us=6, ul=8, ui=7, c=97 'a'\\) " + ".*\[\r\n\]#9 .* call7a \\(c=97 'a', i=2, s=1, l=3, f=4, uc=98 'b', d=5, us=6, ul=8, ui=7\\) " + ".*\[\r\n\]#10 .* main \\(.*\\) " + } # Continue; should stop at call7k and print actual arguments. # Print backtrace. @@ -764,7 +940,21 @@ $gdb_prompt $" { gdb_continue call7k if {!$gcc_compiled} then { setup_xfail "mips-sgi-irix*" } - gdb_test "backtrace 100" ".* call7k \\(c=97 'a', i=2, s=1, l=3, f=4, uc=98 'b', d=5, us=6, ul=8, ui=7\\) .*\[\r\n\].* call7j \\(ui=7, c=97 'a', i=2, s=1, l=3, f=4, uc=98 'b', d=5, us=6, ul=8\\) .*\[\r\n\].* call7i \\(ul=8, ui=7, c=97 'a', i=2, s=1, l=3, f=4, uc=98 'b', d=5, us=6\\) .*\[\r\n\].* call7h \\(us=6, ul=8, ui=7, c=97 'a', i=2, s=1, l=3, f=4, uc=98 'b', d=5\\) .*\[\r\n\].* call7g \\(d=5, us=6, ul=8, ui=7, c=97 'a', i=2, s=1, l=3, f=4, uc=98 'b'\\) .*\[\r\n\].* call7f \\(uc=98 'b', d=5, us=6, ul=8, ui=7, c=97 'a', i=2, s=1, l=3, f=4\\) .*\[\r\n\].* call7e \\(f=4, uc=98 'b', d=5, us=6, ul=8, ui=7, c=97 'a', i=2, s=1, l=3\\) .*\[\r\n\].* call7d \\(l=3, f=4, uc=98 'b', d=5, us=6, ul=8, ui=7, c=97 'a', i=2, s=1\\) .*\[\r\n\].* call7c \\(s=1, l=3, f=4, uc=98 'b', d=5, us=6, ul=8, ui=7, c=97 'a', i=2\\) .*\[\r\n\].* call7b \\(i=2, s=1, l=3, f=4, uc=98 'b', d=5, us=6, ul=8, ui=7, c=97 'a'\\) .*\[\r\n\].* call7a \\(c=97 'a', i=2, s=1, l=3, f=4, uc=98 'b', d=5, us=6, ul=8, ui=7\\) .*\[\r\n\].* main \\(.*\\) .*\[\r\n\].*" "backtrace from call7k" + send_gdb "backtrace 100\n" + gdb_expect_list "backtrace from call7k" ".*$gdb_prompt $" { + ".*\[\r\n\]#0 .* call7k \\(c=97 'a', i=2, s=1, l=3, f=4, uc=98 'b', d=5, us=6, ul=8, ui=7\\) " + ".*\[\r\n\]#1 .* call7j \\(ui=7, c=97 'a', i=2, s=1, l=3, f=4, uc=98 'b', d=5, us=6, ul=8\\) " + ".*\[\r\n\]#2 .* call7i \\(ul=8, ui=7, c=97 'a', i=2, s=1, l=3, f=4, uc=98 'b', d=5, us=6\\) " + ".*\[\r\n\]#3 .* call7h \\(us=6, ul=8, ui=7, c=97 'a', i=2, s=1, l=3, f=4, uc=98 'b', d=5\\) " + ".*\[\r\n\]#4 .* call7g \\(d=5, us=6, ul=8, ui=7, c=97 'a', i=2, s=1, l=3, f=4, uc=98 'b'\\) " + ".*\[\r\n\]#5 .* call7f \\(uc=98 'b', d=5, us=6, ul=8, ui=7, c=97 'a', i=2, s=1, l=3, f=4\\) " + ".*\[\r\n\]#6 .* call7e \\(f=4, uc=98 'b', d=5, us=6, ul=8, ui=7, c=97 'a', i=2, s=1, l=3\\) " + ".*\[\r\n\]#7 .* call7d \\(l=3, f=4, uc=98 'b', d=5, us=6, ul=8, ui=7, c=97 'a', i=2, s=1\\) " + ".*\[\r\n\]#8 .* call7c \\(s=1, l=3, f=4, uc=98 'b', d=5, us=6, ul=8, ui=7, c=97 'a', i=2\\) " + ".*\[\r\n\]#9 .* call7b \\(i=2, s=1, l=3, f=4, uc=98 'b', d=5, us=6, ul=8, ui=7, c=97 'a'\\) " + ".*\[\r\n\]#10 .* call7a \\(c=97 'a', i=2, s=1, l=3, f=4, uc=98 'b', d=5, us=6, ul=8, ui=7\\) " + ".*\[\r\n\]#11 .* main \\(.*\\) " + } gdb_stop_suppressing_tests; } @@ -795,7 +985,17 @@ proc recursive_structs_by_value {} { # The a29k fails all of these tests, perhaps because the prologue # code is broken. setup_xfail "a29k-*-udi" - gdb_test "backtrace 100" ".* hitbottom \\(\\) .*\[\r\n\].* recurse \\(a=\{s = 0, i = 0, l = 0\}, depth=0\\) .*\[\r\n\].* recurse \\(a=\{s = 1, i = 1, l = 1\}, depth=1\\) .*\[\r\n\].* recurse \\(a=\{s = 2, i = 2, l = 2\}, depth=2\\) .*\[\r\n\].* recurse \\(a=\{s = 3, i = 3, l = 3\}, depth=3\\) .*\[\r\n\].* recurse \\(a=\{s = 4, i = 4, l = 4\}, depth=4\\) .*\[\r\n\].* test_struct_args \\(\\) .*\[\r\n\].* main \\(.*\\) .*\[\r\n\]" "recursive passing of structs by value" + send_gdb "backtrace 100\n" + gdb_expect_list "recursive passing of structs by value" ".*$gdb_prompt $" { + ".*\[\r\n\]#0 .* hitbottom \\(\\) " + ".*\[\r\n\]#1 .* recurse \\(a=\{s = 0, i = 0, l = 0\}, depth=0\\) " + ".*\[\r\n\]#2 .* recurse \\(a=\{s = 1, i = 1, l = 1\}, depth=1\\) " + ".*\[\r\n\]#3 .* recurse \\(a=\{s = 2, i = 2, l = 2\}, depth=2\\) " + ".*\[\r\n\]#4 .* recurse \\(a=\{s = 3, i = 3, l = 3\}, depth=3\\) " + ".*\[\r\n\]#5 .* recurse \\(a=\{s = 4, i = 4, l = 4\}, depth=4\\) " + ".*\[\r\n\]#6 .* test_struct_args \\(\\) " + ".*\[\r\n\]#7 .* main \\(.*\\) " + } } else { fail "recursive passing of structs by value (sparclet)" } diff --git a/gdb/testsuite/gdb.base/remote.exp b/gdb/testsuite/gdb.base/remote.exp index 4c8b415452e..70e97cfc8b3 100644 --- a/gdb/testsuite/gdb.base/remote.exp +++ b/gdb/testsuite/gdb.base/remote.exp @@ -35,16 +35,85 @@ set testfile "remote" set srcfile ${testfile}.c set binfile ${objdir}/${subdir}/${testfile} +gdb_start + +set result [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable {debug}] +if {$result != "" } then { + gdb_suppress_entire_file "Testcase compile failed, so all tests in this file will automatically fail." +} + + +# +# Part ONE: Check the down load commands +# + +gdb_test "show download-write-size" \ + "The write size used when downloading a program is 512." \ + "download limit default" + +gdb_test "set download-write-size" "Argument required.*" + +gdb_test "set download-write-size 0" "" +gdb_test "show download-write-size" \ + "The write size used when downloading a program is unlimited." \ + "set download limit - unlimited" + +gdb_test "show remote memory-write-packet-size" \ + "The memory-write-packet-size is 0. Packets are limited to \[0-9\]+ bytes." \ + "write-packet default" + +gdb_test "set remote memory-write-packet-size" \ + "Argument required .integer, `fixed' or `limited'.\." \ + "set write-packet - NULL" -proc gdb_load_timed {executable writesize} { +gdb_test "set remote memory-write-packet-size 16" "" +gdb_test "show remote memory-write-packet-size" \ + "The memory-write-packet-size is 16. Packets are limited to 16 bytes." \ + "set write-packet - small" + +gdb_test "set remote memory-write-packet-size 1" "" +gdb_test "show remote memory-write-packet-size" \ + "The memory-write-packet-size is 1. Packets are limited to 16 bytes." \ + "set write-packet - very-small" + +# +# Part TWO: Check the download behavour +# + +proc gdb_load_timed {executable downloadsize class writesize} { global test gdb_prompt - set test "timed download `[file tail $executable]' ($writesize)" + set test "timed download `[file tail $executable]' - $downloadsize, $class, $writesize" if {$writesize != ""} then { - send_gdb "set remotewritesize $writesize\n" + gdb_test "set remote memory-write-packet-size $writesize" \ + "" "$test - set packet size" + } + + if {$downloadsize != ""} then { + gdb_test "set download-write-size $downloadsize" \ + "" "$test - set download size" + } + + if {$downloadsize != ""} then { + send_gdb "set remote memory-write-packet-size $class\n" gdb_expect 5 { + -re ".*Change the packet size.*$" { + send_gdb "y\n" + gdb_expect 5 { + -re ".*$gdb_prompt $" { + pass "$test - set write size class" + } + timeout { + fail "$test - set write size class" + return + } + } + } -re ".*$gdb_prompt $" { } - timeout { fail "$test - setting remotewritesize" ; return } + timeout { + fail "$test - set write size class" + return + } } } @@ -58,26 +127,17 @@ proc gdb_load_timed {executable writesize} { -# tests +gdb_load_timed $binfile {} "" {} -gdb_start +# Typically about 400 bytes can be downloaded +gdb_load_timed $binfile 0 "limit" 399 +gdb_load_timed $binfile 0 "limit" 401 -set result [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable {debug}] -if {$result != "" } then { - gdb_suppress_entire_file "Testcase compile failed, so all tests in this file will automatically fail." -} +# fall back to the default +gdb_load_timed $binfile 0 "limit" 0 -gdb_load_timed $binfile {} -gdb_load_timed $binfile 50 -gdb_load_timed $binfile 100 -gdb_load_timed $binfile 200 -gdb_load_timed $binfile 400 - -# extra tests for capable targets -if {[target_info gdb,big_rx_buffers] != ""} then { - gdb_load_timed $binfile 800 - gdb_load_timed $binfile 8000 - gdb_load_timed $binfile 80000 -} +# Absolute max is 16384 +gdb_load_timed $binfile 0 "fixed" 0 +gdb_load_timed $binfile 0 "fixed" 16385 gdb_exit diff --git a/gdb/testsuite/gdb.base/shlib-call.exp b/gdb/testsuite/gdb.base/shlib-call.exp index 4e1daac3bed..0381657ea3a 100644 --- a/gdb/testsuite/gdb.base/shlib-call.exp +++ b/gdb/testsuite/gdb.base/shlib-call.exp @@ -119,9 +119,9 @@ if ![runto_main] then { send_gdb "next\n" gdb_expect { - -re ".*g = shr1\\(g\\).*$gdb_prompt $" {pass "next to shr2"} - -re ".*$gdb_prompt $" { fail "next to shr2" } - timeout { fail "next to shr2 (timeout)" } + -re ".*g = shr1\\(g\\).*$gdb_prompt $" {pass "next to shr1"} + -re ".*$gdb_prompt $" { fail "next to shr1" } + timeout { fail "next to shr1 (timeout)" } } diff --git a/gdb/testsuite/lib/gdb.exp b/gdb/testsuite/lib/gdb.exp index f3e3ed33b5f..64ccaa9362b 100644 --- a/gdb/testsuite/lib/gdb.exp +++ b/gdb/testsuite/lib/gdb.exp @@ -1164,17 +1164,27 @@ proc gdb_expect { args } { } } +# gdb_expect_list MESSAGE SENTINAL LIST -- expect a sequence of outputs # # Check for long sequence of output by parts. -# TEST: is the test message. +# MESSAGE: is the test message to be printed with the test success/fail. # SENTINEL: Is the terminal pattern indicating that output has finished. # LIST: is the sequence of outputs to match. # If the sentinel is recognized early, it is considered an error. # +# Returns: +# 1 if the test failed, +# 0 if the test passes, +# -1 if there was an internal error. +# proc gdb_expect_list {test sentinal list} { global gdb_prompt + global suppress_flag set index 0 set ok 1 + if { $suppress_flag } { + set ok 0 + } while { ${index} < [llength ${list}] } { set pattern [lindex ${list} ${index}] set index [expr ${index} + 1] @@ -1212,6 +1222,11 @@ proc gdb_expect_list {test sentinal list} { } } } + if { ${ok} } { + return 0 + } else { + return 1 + } } # diff --git a/gdb/top.c b/gdb/top.c index 73b286caa1d..3d1b040b745 100644 --- a/gdb/top.c +++ b/gdb/top.c @@ -524,6 +524,25 @@ return_to_top_level (reason) catch_errors. Note that quit should return to the command line fairly quickly, even if some further processing is being done. */ +/* MAYBE: cagney/1999-11-05: catch_errors() in conjunction with + error() et.al. could maintain a set of flags that indicate the the + current state of each of the longjmp buffers. This would give the + longjmp code the chance to detect a longjmp botch (before it gets + to longjmperror()). Prior to 1999-11-05 this wasn't possible as + code also randomly used a SET_TOP_LEVEL macro that directly + initialize the longjmp buffers. */ + +/* MAYBE: cagney/1999-11-05: Since the SET_TOP_LEVEL macro has been + eliminated it is now possible to use the stack to directly store + each longjmp buffer. The global code would just need to update a + pointer (onto the stack - ulgh!?) indicating the current longjmp + buffers. It would certainly improve the performance of the longjmp + code since the memcpy's would be eliminated. */ + +/* MAYBE: cagney/1999-11-05: Should the catch_erros and cleanups code + be consolidated into a single file instead of being distributed + between utils.c and top.c? */ + int catch_errors (func, args, errstring, mask) catch_errors_ftype *func; @@ -561,6 +580,14 @@ catch_errors (func, args, errstring, mask) if (mask & RETURN_MASK_QUIT) memcpy (quit_return, tmp_jmp, sizeof (SIGJMP_BUF)); val = (*func) (args); + /* FIXME: cagney/1999-11-05: A correct FUNC implementaton will + clean things up (restoring the cleanup chain) to the state + they were just prior to the call. Technically, this means + that the below restore_cleanups call is redundant. + Unfortunatly, many FUNC's are not that well behaved. + restore_cleanups should either be replaced with a do_cleanups + call (to cover the problem) or an assertion check to detect + bad FUNCs code. */ } else val = 0; @@ -580,6 +607,41 @@ catch_errors (func, args, errstring, mask) return val; } +struct captured_command_args + { + catch_command_errors_ftype *command; + char *arg; + int from_tty; + }; + +static int +do_captured_command (void *data) +{ + struct captured_command_args *context = data; + context->command (context->arg, context->from_tty); + /* FIXME: cagney/1999-11-07: Technically this do_cleanups() call + isn't needed. Instead an assertion check could be made that + simply confirmed that the called function correctly cleaned up + after its self. Unfortunatly, old code (prior to 1999-11-04) in + main.c was calling SET_TOP_LEVEL(), calling the command function, + and then *always* calling do_cleanups(). For the moment we + remain ``bug compatible'' with that old code.. */ + do_cleanups (ALL_CLEANUPS); + return 1; +} + +int +catch_command_errors (catch_command_errors_ftype *command, + char *arg, int from_tty, return_mask mask) +{ + struct captured_command_args args; + args.command = command; + args.arg = arg; + args.from_tty = from_tty; + return catch_errors (do_captured_command, &args, "", mask); +} + + /* Handler for SIGHUP. */ #ifdef SIGHUP diff --git a/gdb/top.h b/gdb/top.h index 2803aa9fc8c..9f6398f7fca 100644 --- a/gdb/top.h +++ b/gdb/top.h @@ -42,19 +42,6 @@ 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; diff --git a/gdb/tui/ChangeLog b/gdb/tui/ChangeLog index c2a7b58383d..2af1a8f7ecb 100644 --- a/gdb/tui/ChangeLog +++ b/gdb/tui/ChangeLog @@ -1,3 +1,16 @@ +Mon Nov 8 17:47:37 1999 Andrew Cagney + + * tuiRegs.c (_tuiRegisterFormat), tuiDisassem.c + (tuiSetDisassemContent): Replace gdb_file_init_astring with + tui_sfileopen. Replace gdb_file_get_strbuf with + tui_file_get_strbuf. + +Mon Nov 8 16:54:51 1999 Andrew Cagney + + * tuiRegs.c (_tuiRegisterFormat), tuiDisassem.c + (tuiSetDisassemContent): Repace gdb_file_deallocate with + gdb_file_delete. Replace gdb_file_init_astring with tui_sfileopen. + Fri Sep 17 19:34:38 1999 Andrew Cagney * tuiSource.c: Include "source.h". diff --git a/gdb/tui/tuiDisassem.c b/gdb/tui/tuiDisassem.c index 1bc1b95f919..a39574b3890 100644 --- a/gdb/tui/tuiDisassem.c +++ b/gdb/tui/tuiDisassem.c @@ -66,7 +66,7 @@ tuiSetDisassemContent (s, startAddr) threshold = (lineWidth - 1) + offset; /* now init the gdb_file structure */ - gdb_dis_out = gdb_file_init_astring (threshold); + gdb_dis_out = tui_sfileopen (threshold); INIT_DISASSEMBLE_INFO_NO_ARCH (asmInfo, gdb_dis_out, (fprintf_ftype) fprintf_filtered); asmInfo.read_memory_func = dis_asm_read_memory; @@ -82,27 +82,27 @@ tuiSetDisassemContent (s, startAddr) print_address (pc, gdb_dis_out); - curLen = strlen (gdb_file_get_strbuf (gdb_dis_out)); + curLen = strlen (tui_file_get_strbuf (gdb_dis_out)); i = curLen - ((curLen / tab_len) * tab_len); /* adjust buffer length if necessary */ - gdb_file_adjust_strbuf ((tab_len - i > 0) ? (tab_len - i) : 0, gdb_dis_out); + tui_file_adjust_strbuf ((tab_len - i > 0) ? (tab_len - i) : 0, gdb_dis_out); /* Add spaces to make the instructions start onthe same column */ while (i < tab_len) { - gdb_file_get_strbuf (gdb_dis_out)[curLen] = ' '; + tui_file_get_strbuf (gdb_dis_out)[curLen] = ' '; i++; curLen++; } - gdb_file_get_strbuf (gdb_dis_out)[curLen] = '\0'; + tui_file_get_strbuf (gdb_dis_out)[curLen] = '\0'; newpc = pc + ((*tm_print_insn) (pc, &asmInfo)); /* Now copy the line taking the offset into account */ - if (strlen (gdb_file_get_strbuf (gdb_dis_out)) > offset) + if (strlen (tui_file_get_strbuf (gdb_dis_out)) > offset) strcpy (element->whichElement.source.line, - &(gdb_file_get_strbuf (gdb_dis_out)[offset])); + &(tui_file_get_strbuf (gdb_dis_out)[offset])); else element->whichElement.source.line[0] = '\0'; element->whichElement.source.lineOrAddr.addr = (Opaque) pc; @@ -116,9 +116,10 @@ tuiSetDisassemContent (s, startAddr) curLine++; pc = newpc; /* reset the buffer to empty */ - gdb_file_get_strbuf (gdb_dis_out)[0] = '\0'; + tui_file_get_strbuf (gdb_dis_out)[0] = '\0'; } - gdb_file_deallocate (&gdb_dis_out); + gdb_file_delete (gdb_dis_out); + gdb_dis_out = NULL; disassemWin->generic.contentSize = curLine; ret = TUI_SUCCESS; } diff --git a/gdb/tui/tuiRegs.c b/gdb/tui/tuiRegs.c index 92eec56881a..33d6079cf87 100644 --- a/gdb/tui/tuiRegs.c +++ b/gdb/tui/tuiRegs.c @@ -671,10 +671,10 @@ _tuiRegisterFormat (buf, bufLen, regNum, dataElement, precision) char *fmt; GDB_FILE *stream; - stream = gdb_file_init_astring (bufLen); + stream = tui_sfileopen (bufLen); pa_do_strcat_registers_info (regNum, 0, stream, precision); - strcpy (buf, gdb_file_get_strbuf (stream)); - gdb_file_deallocate (&stream); + strcpy (buf, tui_file_get_strbuf (stream)); + gdb_file_delete (stream); return; } /* _tuiRegisterFormat */ diff --git a/gdb/utils.c b/gdb/utils.c index e657c5a374f..339b26a31b0 100644 --- a/gdb/utils.c +++ b/gdb/utils.c @@ -211,6 +211,18 @@ make_cleanup_freeargv (arg) return make_my_cleanup (&cleanup_chain, do_freeargv, arg); } +static void +do_gdb_file_delete (void *arg) +{ + gdb_file_delete (arg); +} + +struct cleanup * +make_cleanup_gdb_file_delete (struct gdb_file *arg) +{ + return make_my_cleanup (&cleanup_chain, do_gdb_file_delete, arg); +} + struct cleanup * make_my_cleanup (pmy_chain, function, arg) struct cleanup **pmy_chain; @@ -535,7 +547,7 @@ error (const char *string,...) NORETURN void error_stream (GDB_FILE *stream) { - error (gdb_file_get_strbuf (stream)); + error (tui_file_get_strbuf (stream)); } /* Get the last error message issued by gdb */ @@ -543,7 +555,7 @@ error_stream (GDB_FILE *stream) char * error_last_message (void) { - return (gdb_file_get_strbuf (gdb_lasterr)); + return (tui_file_get_strbuf (gdb_lasterr)); } /* This is to be called by main() at the very beginning */ @@ -1643,6 +1655,7 @@ begin_line () /* ``struct gdb_file'' implementation that maps directly onto 's FILE. */ +static gdb_file_write_ftype stdio_file_write; static gdb_file_fputs_ftype stdio_file_fputs; static gdb_file_isatty_ftype stdio_file_isatty; static gdb_file_delete_ftype stdio_file_delete; @@ -1670,6 +1683,7 @@ stdio_file_new (file, close_p) stdio->close_p = close_p; set_gdb_file_data (gdb_file, stdio, stdio_file_delete); set_gdb_file_flush (gdb_file, stdio_file_flush); + set_gdb_file_write (gdb_file, stdio_file_write); set_gdb_file_fputs (gdb_file, stdio_file_fputs); set_gdb_file_isatty (gdb_file, stdio_file_isatty); return gdb_file; @@ -1681,7 +1695,7 @@ stdio_file_delete (file) { struct stdio_file *stdio = gdb_file_data (file); if (stdio->magic != &stdio_file_magic) - error ("Internal error: bad magic number"); + internal_error ("stdio_file_delete: bad magic number"); if (stdio->close_p) { fclose (stdio->file); @@ -1695,10 +1709,19 @@ stdio_file_flush (file) { struct stdio_file *stdio = gdb_file_data (file); if (stdio->magic != &stdio_file_magic) - error ("Internal error: bad magic number"); + internal_error ("stdio_file_flush: bad magic number"); fflush (stdio->file); } +static void +stdio_file_write (struct gdb_file *file, const char *buf, long length_buf) +{ + struct stdio_file *stdio = gdb_file_data (file); + if (stdio->magic != &stdio_file_magic) + internal_error ("stdio_file_write: bad magic number"); + fwrite (buf, length_buf, 1, stdio->file); +} + static void stdio_file_fputs (linebuffer, file) const char *linebuffer; @@ -1706,7 +1729,7 @@ stdio_file_fputs (linebuffer, file) { struct stdio_file *stdio = gdb_file_data (file); if (stdio->magic != &stdio_file_magic) - error ("Internal error: bad magic number"); + internal_error ("stdio_file_fputs: bad magic number"); fputs (linebuffer, stdio->file); } @@ -1716,7 +1739,7 @@ stdio_file_isatty (file) { struct stdio_file *stdio = gdb_file_data (file); if (stdio->magic != &stdio_file_magic) - error ("Internal error: bad magic number"); + internal_error ("stdio_file_isatty: bad magic number"); return (isatty (fileno (stdio->file))); } @@ -1882,7 +1905,7 @@ tui_file_delete (file) { struct tui_stream *tmpstream = gdb_file_data (file); if (tmpstream->ts_magic != &tui_file_magic) - error ("Internal error: bad magic number"); + internal_error ("tui_file_delete: bad magic number"); if ((tmpstream->ts_streamtype == astring) && (tmpstream->ts_strbuf != NULL)) { @@ -1919,7 +1942,7 @@ tui_sfileopen (n) } else /* Do not allocate the buffer now. The first time something is printed - one will be allocated by gdb_file_adjust_strbuf() */ + one will be allocated by tui_file_adjust_strbuf() */ tmpstream->ts_strbuf = NULL; tmpstream->ts_buflen = n; return file; @@ -1931,7 +1954,7 @@ tui_file_isatty (file) { struct tui_stream *stream = gdb_file_data (file); if (stream->ts_magic != &tui_file_magic) - error ("Internal error: bad magic number"); + internal_error ("tui_file_isatty: bad magic number"); if (stream->ts_streamtype == afile) return (isatty (fileno (stream->ts_filestream))); else @@ -1944,7 +1967,7 @@ tui_file_rewind (file) { struct tui_stream *stream = gdb_file_data (file); if (stream->ts_magic != &tui_file_magic) - error ("Internal error: bad magic number"); + internal_error ("tui_file_rewind: bad magic number"); stream->ts_strbuf[0] = '\0'; } @@ -1955,7 +1978,7 @@ tui_file_put (file, dest) { struct tui_stream *stream = gdb_file_data (file); if (stream->ts_magic != &tui_file_magic) - error ("Internal error: bad magic number"); + internal_error ("tui_file_put: bad magic number"); if (stream->ts_streamtype == astring) { fputs_unfiltered (stream->ts_strbuf, dest); @@ -2001,7 +2024,7 @@ tui_file_fputs (linebuffer, file) if (stream->ts_streamtype == astring) { - gdb_file_adjust_strbuf (strlen (linebuffer), stream); + tui_file_adjust_strbuf (strlen (linebuffer), stream); strcat (stream->ts_strbuf, linebuffer); } else @@ -2020,7 +2043,7 @@ tui_file_fputs (linebuffer, file) /* The normal case - just do a fputs() */ if (stream->ts_streamtype == astring) { - gdb_file_adjust_strbuf (strlen (linebuffer), stream); + tui_file_adjust_strbuf (strlen (linebuffer), stream); strcat (stream->ts_strbuf, linebuffer); } else @@ -2031,7 +2054,7 @@ tui_file_fputs (linebuffer, file) #else if (stream->ts_streamtype == astring) { - gdb_file_adjust_strbuf (strlen (linebuffer), file); + tui_file_adjust_strbuf (strlen (linebuffer), file); strcat (stream->ts_strbuf, linebuffer); } else @@ -2040,60 +2063,24 @@ tui_file_fputs (linebuffer, file) } } -/* DEPRECATED: Use tui_sfileopen() instead */ - -GDB_FILE * -gdb_file_init_astring (n) - int n; -{ - struct gdb_file *file = tui_file_new (); - struct tui_stream *tmpstream = gdb_file_data (file); - if (tmpstream->ts_magic != &tui_file_magic) - error ("Internal error: bad magic number"); - - tmpstream->ts_streamtype = astring; - tmpstream->ts_filestream = NULL; - if (n > 0) - { - tmpstream->ts_strbuf = xmalloc ((n + 1) * sizeof (char)); - tmpstream->ts_strbuf[0] = '\0'; - } - else - tmpstream->ts_strbuf = NULL; - tmpstream->ts_buflen = n; - - return file; -} - -void -gdb_file_deallocate (streamptr) - GDB_FILE **streamptr; -{ - gdb_file_delete (*streamptr); - *streamptr = NULL; -} - char * -gdb_file_get_strbuf (file) - GDB_FILE *file; +tui_file_get_strbuf (struct gdb_file *file) { struct tui_stream *stream = gdb_file_data (file); if (stream->ts_magic != &tui_file_magic) - error ("Internal error: bad magic number"); + internal_error ("tui_file_get_strbuf: bad magic number"); return (stream->ts_strbuf); } /* adjust the length of the buffer by the amount necessary to accomodate appending a string of length N to the buffer contents */ void -gdb_file_adjust_strbuf (n, file) - int n; - GDB_FILE *file; +tui_file_adjust_strbuf (int n, struct gdb_file *file) { struct tui_stream *stream = gdb_file_data (file); int non_null_chars; if (stream->ts_magic != &tui_file_magic) - error ("Internal error: bad magic number"); + internal_error ("tui_file_adjust_strbuf: bad magic number"); if (stream->ts_streamtype != astring) return; @@ -2150,18 +2137,10 @@ tui_file_flush (file) } } -void -gdb_fclose (streamptr) - GDB_FILE **streamptr; -{ - gdb_file_delete (*streamptr); - *streamptr = NULL; -} - - /* Implement the ``struct gdb_file'' object. */ static gdb_file_isatty_ftype null_file_isatty; +static gdb_file_write_ftype null_file_write; static gdb_file_fputs_ftype null_file_fputs; static gdb_file_flush_ftype null_file_flush; static gdb_file_delete_ftype null_file_delete; @@ -2171,6 +2150,7 @@ static gdb_file_put_ftype null_file_put; struct gdb_file { gdb_file_flush_ftype *to_flush; + gdb_file_write_ftype *to_write; gdb_file_fputs_ftype *to_fputs; gdb_file_delete_ftype *to_delete; gdb_file_isatty_ftype *to_isatty; @@ -2185,6 +2165,7 @@ gdb_file_new () struct gdb_file *file = xmalloc (sizeof (struct gdb_file)); set_gdb_file_data (file, NULL, null_file_delete); set_gdb_file_flush (file, null_file_flush); + set_gdb_file_write (file, null_file_write); set_gdb_file_fputs (file, null_file_fputs); set_gdb_file_isatty (file, null_file_isatty); set_gdb_file_rewind (file, null_file_rewind); @@ -2229,12 +2210,48 @@ null_file_flush (file) return; } +static void +null_file_write (struct gdb_file *file, + const char *buf, + long sizeof_buf) +{ + if (file->to_fputs == null_file_fputs) + /* Both the write and fputs methods are null. Discard the + request. */ + return; + else + { + /* The fputs method isn't null, slowly pass the write request + onto that. FYI, this isn't as bad as it may look - the + current (as of 1999-11-07) printf_* function calls fputc and + fputc does exactly the below. By having a write function it + is possible to clean up that code. */ + int i; + char b[2]; + b[1] = '\0'; + for (i = 0; i < sizeof_buf; i++) + { + b[0] = buf[i]; + file->to_fputs (b, file); + } + return; + } +} + static void null_file_fputs (buf, file) const char *buf; struct gdb_file *file; { - return; + if (file->to_write == null_file_write) + /* Both the write and fputs methods are null. Discard the + request. */ + return; + else + { + /* The write method was implemented, use that. */ + file->to_write (file, buf, strlen (buf)); + } } static void @@ -2280,6 +2297,14 @@ gdb_file_put (file, dest) file->to_put (file, dest); } +void +gdb_file_write (struct gdb_file *file, + const char *buf, + long length_buf) +{ + file->to_write (file, buf, length_buf); +} + void fputs_unfiltered (buf, file) const char *buf; @@ -2320,6 +2345,13 @@ set_gdb_file_put (file, put) file->to_put = put; } +void +set_gdb_file_write (struct gdb_file *file, + gdb_file_write_ftype *write) +{ + file->to_write = write; +} + void set_gdb_file_fputs (file, fputs) struct gdb_file *file; @@ -2467,11 +2499,8 @@ int putchar_unfiltered (c) int c; { - char buf[2]; - - buf[0] = c; - buf[1] = 0; - fputs_unfiltered (buf, gdb_stdout); + char buf = c; + gdb_file_write (gdb_stdout, &buf, 1); return c; } @@ -2480,11 +2509,8 @@ fputc_unfiltered (c, stream) int c; GDB_FILE *stream; { - char buf[2]; - - buf[0] = c; - buf[1] = 0; - fputs_unfiltered (buf, stream); + char buf = c; + gdb_file_write (stream, &buf, 1); return c; } @@ -3122,9 +3148,12 @@ floatformat_to_doublest (fmt, from, to) special_exponent = exponent == 0 || exponent == fmt->exp_nan; -/* Don't bias zero's, denorms or NaNs. */ +/* Don't bias NaNs. Use minimum exponent for denorms. For simplicity, + we don't check for zero as the exponent doesn't matter. */ if (!special_exponent) exponent -= fmt->exp_bias; + else if (exponent == 0) + exponent = 1 - fmt->exp_bias; /* Build the result algebraically. Might go infinite, underflow, etc; who cares. */ diff --git a/sim/common/ChangeLog b/sim/common/ChangeLog index 1d8bfeafed4..c2d1c8c3c9b 100644 --- a/sim/common/ChangeLog +++ b/sim/common/ChangeLog @@ -1,3 +1,16 @@ +1999-11-04 Dave Brolley + + * cgen-par.h (cgen_write_queue_kind): Add CGEN_FN_XI_WRITE and + CGEN_MEM_XI_WRITE members. + (CGEN_WRITE_QUEUE_ELEMENT): Add fn_xi_write and mem_xi_write members. + (sim_queue_fn_xi_write): New function. + (sim_queue_mem_xi_write): New function. + + * cgen-par.c (sim_queue_fn_xi_write): New function. + (sim_queue_mem_xi_write): New function. + (cgen_write_queue_element_execute): Handle CGEN_FN_XI_WRITE and + CGEN_MEM_XI_WRITE. + 1999-10-22 Dave Brolley * cgen-par.h (insn_address): New field in CGEN_WRITE_QUEUE_ELEMENT. diff --git a/sim/common/cgen-par.c b/sim/common/cgen-par.c index e2af54e873b..fece2c9f11f 100644 --- a/sim/common/cgen-par.c +++ b/sim/common/cgen-par.c @@ -121,6 +121,25 @@ void sim_queue_fn_di_write ( element->kinds.fn_di_write.value = value; } +void sim_queue_fn_xi_write ( + SIM_CPU *cpu, + void (*write_function)(SIM_CPU *cpu, UINT, SI *), + UINT regno, + SI *value +) +{ + CGEN_WRITE_QUEUE *q = CPU_WRITE_QUEUE (cpu); + CGEN_WRITE_QUEUE_ELEMENT *element = CGEN_WRITE_QUEUE_NEXT (q); + element->kind = CGEN_FN_XI_WRITE; + element->insn_address = CPU_PC_GET (cpu); + element->kinds.fn_xi_write.function = write_function; + element->kinds.fn_xi_write.regno = regno; + element->kinds.fn_xi_write.value[0] = value[0]; + element->kinds.fn_xi_write.value[1] = value[1]; + element->kinds.fn_xi_write.value[2] = value[2]; + element->kinds.fn_xi_write.value[3] = value[3]; +} + void sim_queue_fn_df_write ( SIM_CPU *cpu, void (*write_function)(SIM_CPU *cpu, UINT, DI), @@ -201,6 +220,19 @@ void sim_queue_mem_df_write (SIM_CPU *cpu, SI address, DF value) element->kinds.mem_df_write.value = value; } +void sim_queue_mem_xi_write (SIM_CPU *cpu, SI address, SI *value) +{ + CGEN_WRITE_QUEUE *q = CPU_WRITE_QUEUE (cpu); + CGEN_WRITE_QUEUE_ELEMENT *element = CGEN_WRITE_QUEUE_NEXT (q); + element->kind = CGEN_MEM_XI_WRITE; + element->insn_address = CPU_PC_GET (cpu); + element->kinds.mem_xi_write.address = address; + element->kinds.mem_xi_write.value[0] = value[0]; + element->kinds.mem_xi_write.value[1] = value[1]; + element->kinds.mem_xi_write.value[2] = value[2]; + element->kinds.mem_xi_write.value[3] = value[3]; +} + /* Execute a write stored on the write queue. */ void cgen_write_queue_element_execute (SIM_CPU *cpu, CGEN_WRITE_QUEUE_ELEMENT *item) @@ -243,6 +275,11 @@ cgen_write_queue_element_execute (SIM_CPU *cpu, CGEN_WRITE_QUEUE_ELEMENT *item) item->kinds.fn_df_write.regno, item->kinds.fn_df_write.value); break; + case CGEN_FN_XI_WRITE: + item->kinds.fn_xi_write.function (cpu, + item->kinds.fn_xi_write.regno, + item->kinds.fn_xi_write.value); + break; case CGEN_FN_PC_WRITE: item->kinds.fn_pc_write.function (cpu, item->kinds.fn_pc_write.value); break; @@ -271,6 +308,17 @@ cgen_write_queue_element_execute (SIM_CPU *cpu, CGEN_WRITE_QUEUE_ELEMENT *item) SETMEMDF (cpu, pc, item->kinds.mem_df_write.address, item->kinds.mem_df_write.value); break; + case CGEN_MEM_XI_WRITE: + pc = item->insn_address; + SETMEMSI (cpu, pc, item->kinds.mem_xi_write.address, + item->kinds.mem_xi_write.value[0]); + SETMEMSI (cpu, pc, item->kinds.mem_xi_write.address + 4, + item->kinds.mem_xi_write.value[1]); + SETMEMSI (cpu, pc, item->kinds.mem_xi_write.address + 8, + item->kinds.mem_xi_write.value[2]); + SETMEMSI (cpu, pc, item->kinds.mem_xi_write.address + 12, + item->kinds.mem_xi_write.value[3]); + break; default: break; /* FIXME: for now....print message later. */ } diff --git a/sim/common/cgen-par.h b/sim/common/cgen-par.h index 9cf5e8c49e1..6771e40635b 100644 --- a/sim/common/cgen-par.h +++ b/sim/common/cgen-par.h @@ -26,9 +26,9 @@ enum cgen_write_queue_kind { CGEN_BI_WRITE, CGEN_QI_WRITE, CGEN_SI_WRITE, CGEN_SF_WRITE, CGEN_PC_WRITE, CGEN_FN_HI_WRITE, CGEN_FN_SI_WRITE, CGEN_FN_DI_WRITE, CGEN_FN_DF_WRITE, - CGEN_FN_PC_WRITE, + CGEN_FN_XI_WRITE, CGEN_FN_PC_WRITE, CGEN_MEM_QI_WRITE, CGEN_MEM_HI_WRITE, CGEN_MEM_SI_WRITE, CGEN_MEM_DI_WRITE, - CGEN_MEM_DF_WRITE, + CGEN_MEM_DF_WRITE, CGEN_MEM_XI_WRITE, CGEN_NUM_WRITE_KINDS }; @@ -76,6 +76,11 @@ typedef struct { DI value; void (*function)(SIM_CPU *, UINT, DI); } fn_df_write; + struct { + UINT regno; + SI value[4]; + void (*function)(SIM_CPU *, UINT, SI *); + } fn_xi_write; struct { USI value; void (*function)(SIM_CPU *, USI); @@ -100,6 +105,10 @@ typedef struct { SI address; DI value; } mem_df_write; + struct { + SI address; + SI value[4]; + } mem_xi_write; } kinds; } CGEN_WRITE_QUEUE_ELEMENT; @@ -143,6 +152,7 @@ extern void sim_queue_fn_hi_write (SIM_CPU *, void (*)(SIM_CPU *, UINT, UHI), UI extern void sim_queue_fn_si_write (SIM_CPU *, void (*)(SIM_CPU *, UINT, USI), UINT, SI); extern void sim_queue_fn_di_write (SIM_CPU *, void (*)(SIM_CPU *, UINT, DI), UINT, DI); extern void sim_queue_fn_df_write (SIM_CPU *, void (*)(SIM_CPU *, UINT, DI), UINT, DF); +extern void sim_queue_fn_xi_write (SIM_CPU *, void (*)(SIM_CPU *, UINT, SI *), UINT, SI *); extern void sim_queue_fn_pc_write (SIM_CPU *, void (*)(SIM_CPU *, USI), USI); extern void sim_queue_mem_qi_write (SIM_CPU *, SI, QI); @@ -150,5 +160,6 @@ extern void sim_queue_mem_hi_write (SIM_CPU *, SI, HI); extern void sim_queue_mem_si_write (SIM_CPU *, SI, SI); extern void sim_queue_mem_di_write (SIM_CPU *, SI, DI); extern void sim_queue_mem_df_write (SIM_CPU *, SI, DF); +extern void sim_queue_mem_xi_write (SIM_CPU *, SI, SI *); #endif /* CGEN_PAR_H */ -- 2.30.2