From: Andrew Cagney Date: Mon, 3 Feb 2003 06:02:47 +0000 (+0000) Subject: Merge kseitz_interps-20020528-branch. X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=39540477e8109d9cc046d38b665a83e9d2df5f71;p=thirdparty%2Fbinutils-gdb.git Merge kseitz_interps-20020528-branch. --- diff --git a/gdb/ChangeLog b/gdb/ChangeLog index ab8db86376c..de814f0d895 100644 --- a/gdb/ChangeLog +++ b/gdb/ChangeLog @@ -1,3 +1,337 @@ +2002-11-05 Elena Zannoni + + * defs.h (selected_frame_level_changed_hook): Removed. + +2002-11-05 Elena Zannoni + + * event-top.c: Reorg some code, to minimize diffs with mainline. + +2002-11-05 Elena Zannoni + + * Makefile.in (event-loop.o): Remove dependency on interps.h. + * event-loop.c: Remove include of interps.h. + +2002-11-04 Elena Zannoni + + * interps.h (clear_interpreter_hooks): Add 'extern' keyword. + +2002-11-04 Elena Zannoni + + * cli/cli-interp.c (_initialize_cli_interp): Call + gdb_interpreter_new and gdb_interpreter_add. + * top.c (gdb_init): Call gdb_interpreter_lookup. + (gdb_init): Call gdb_interpreter_set. + * interps.c (gdb_interpreter_new): Renamed from + gdb_new_interpreter. + (gdb_interpreter_add): Renamed from gdb_add_interpreter. + (gdb_interpreter_set): Renamed from gdb_set_interpreter. + (gdb_interpreter_lookup): Renamed from gdb_lookup_interpreter. + (gdb_interpreter_current): Renamed from gdb_current_interpreter. + Update all callers. + * interps.h: Ditto. + + +2002-11-04 Elena Zannoni + + * interps.h (gdb_interpreter_is_quiet_p): Rename from + gdb_interpreter_is_quiet. + * cli/cli-interp.c (cli_interpreter_display_prompt_p): Call + gdb_interpreter_is_quiet_p. + * interps.c (gdb_interpreter_is_quiet_p): Rename from + gdb_interpreter_is_quiet. + (gdb_set_interpreter): Call gdb_interpreter_is_quiet_p. + +2002-11-04 Elena Zannoni + + * event-top.c (display_gdb_prompt): Use + gdb_interpreter_display_prompt_p. + * cli/cli-interp.c (cli_interpreter_display_prompt_p): Rename from + cli_interpreter_display_prompt and rewrite. + (_initialize_cli_interp): New proc name is + cli_interpreter_display_prompt_p. + * interps.c (gdb_new_interpreter): Initialize prompt_proc_p + instead of prompt_proc. + (gdb_interpreter_display_prompt_p): Rewrite as a predicate. + (gdb_interpreter_is_quiet_p): Rename from gdb_interpreter_is_quiet. + (gdb_set_interpreter): Call gdb_interpreter_is_quiet_p. + + * interps.h (interp_prompt_ftype): Update typedef. + (struct gdb_interpreter_procs): Rename prompt_proc to + prompt_proc_p. + (gdb_interpreter_display_prompt_p): Export this instead of old + function. + +2002-11-04 Elena Zannoni + + * interps.c (list_interpreter_cmd, do_set_interpreter): Remove + useless prototypes. + Update a few comments, remove gratuitous blank lines. + +2002-11-04 Elena Zannoni + + * cli/cli-interp.c (cli_interpreter_delete): Delete. + (_initialize_cli_interp): Remove delete_proc. + + * interps.h (struct gdb_interpreter_procs): Remove delete_proc. + (interp_delete_ftype): Delete. + (gdb_delete_interpreter): Remove. + + * interps.c (gdb_delete_interpreter): Remove. + (gdb_new_interpreter): Don't initialize delete_proc. + +2002-11-04 Elena Zannoni + + * interps.c (set_interpreter_cmd): Remove. + +2002-11-04 Elena Zannoni + + * interps.c (interpreter_completer): Initialize alloced. + (struct gdb_interpreter): Reformat. + (set_interpreter_cmd): Remove. + +2002-11-04 Elena Zannoni + + * interps.h (struct gdb_interpreter_procs): Remove do_one_event_proc. + (interp_do_one_event_ftype): Delete. + * interps.c (gdb_new_interpreter): Remove setup of do_one_event + procedure. + (interpreter_do_one_event): Delete. + * event-loop.c (start_event_loop): Remove no-op call to + interpreter_do_one_event. + * cli/cli-interps.c: (cli_interpreter_do_one_event): Delete. + +2002-11-04 Elena Zannoni + + * Makefile.in (mi-main.o, mi-cmd-break.o, event-loop.o): Update + dependencies on interps.h. + +2002-11-04 Elena Zannoni + + * interps.h (GDB_INTERPRETER_MI2): Define. + (GDB_INTERPRETER_MI0): Remove. + +2002-10-01 Keith Seitz + + * interps.c (interpreter_exec_cmd): Remove mention of "mi" in + error message. + (list_interpreter_cmd): Removed. + + * cli/cli-interp.c (do_captured_execute_command): New function. + (safe_execute_command): New function. + * Makefile.in (cli-interp.c): Depend on top_h. + * wrapper.c (do_captured_execute_command): Moved to cli/cli-interp.c. + (gdb_execute_command): Removed. + * wrapper.h (gdb_execute_command): Removed. + +2002-09-04 Keith Seitz + + * thread.c (do_captured_list_thread_ids): Call prune_threads + and target_find_new_threads. + +2002-08-29 Keith Seitz + + * gdb-events.sh (context_changed): Rename to selected_thread_changed + to parallel selected_frame_level_changed. + * thread.c (do_captured_thread_select): Ditto. + * gdb-events.c: Regenerate. + * gdb-events.h: Regenerate. + +2002-08-28 Keith Seitz + + * interps.c (interpreter_exec_cmd): Temporarily set + current interpreter to quiet, too, so that we don't get + too many prompts when switching interpreters. + +2002-08-28 Keith Seitz + + * thread.c (do_captured_thread_select): Add context-changed + notification. + * infrun.c (handle_inferior_event): Remove context-changed + notification. The stop result already has this information. + + * thread.c (do_captured_list_thread_ids): Use ui_out_list_begin/end + instead of ui_out_tuple_begin/end. + +2002-08-22 Keith Seitz + + * breakpoint.c (internal_breakpoint_number): Revert 2002-06-18 change. + (create_internal_breakpoint): Likewise. + (watch_command_1): Use create_internal_breakpoint to create + the watchpoint scope breakpoint. + +2002-08-21 Keith Seitz + + * gdb-events.sh: Replace register_update with target-changed event. + * gdb-events.c: Regenerated. + * gdb-events.c: Regenerated. + * valops.c (value_assign): Use target_changed_event instead + of register_update_event and memory_changed. + +2002-08-19 Keith Seitz + + * stack.c (select_frame_command): Send selected-frame-level-changed + event notification, but only if the level actually changed. + (up_silently_base): Add selected-frame-level-changed event + notification. + (down_silently_base): Likewise. + (frame_command): Revert 2002-07-25 changes. + (up_command): Likewise. + (down_command): Likewise. + +2002-08-13 Keith Seitz + + * interps.c (_initialize_interpreter): Remove ability to set + the interpreter. This could really undermine MI clients. + * top.c (catcher): Don't worry about interpreter changes. + +2002-08-12 Keith Seitz + + * interps.c (_initialize_interpreter): Add completer function + to "set interpreter" command. + +2002-08-12 Keith Seitz + + * interps.c: Run through gdb_indent.sh + * interps.h: Ditto. + +2002-08-08 Keith Seitz + + * infrun.c (handle_inferior_event): Add context_changed_event. + * gdb-events.sh (context_hook): Removed comment. + (context_changed): Add new event. + * gdb-events.c: Regenerate. + * gdb-events.h: Regenerate. + +2002-07-25 Keith Seitz + + * stack.c (frame_command): If the frame level changed, issue + a selected_frame_level_changed event. + (up_command): Add selected_frame_level_changed event; + (down_command): Likewise. + + * gdb-events.sh: Add selected_frame_level_changed event. + * gdb-events.c: Regenerate. + * gdb-events.h: Regenerate. + + * stack.c (print_frame_info_base): Always set current_source_symtab + and current_source_line. + + * cli/cli-interp.c (cli_interpreter_exec): Pass from_tty=1 to + gdb_execute_command. + +2002-07-22 Keith Seitz + + * gdb-events.sh (register_changed_hook): Remove comment. + (register_update): New event. + * gdb-events.c: Regenerated. + * gdb-events.h: Regenerated. + +2002-07-22 Keith Seitz + + * valops.c (value_assign): Add register_update event notification + for lval_register and lval_reg_frame_relative. + +2002-06-24 Keith Seitz + + * Makefile.in (interps.o): Add gdb-events.h as a dependency. + + * gdb-events.sh (clear_gdb_event_hooks): New function. + * gdb-events.c: Regenerate. + * gdb-events.h: Regenerate. + + * cli-out.h (cli_out_set_stream): New function. + * cli-out.c (cli_out_set_stream): New function. + + * interps.c: Include gdb-events.h. + (clear_interpreter_hooks): Also clear out event handlers. + (gdb_set_interpreter): Clear out any hooks/event handlers that + may have been installed by old interpreter. + + * cli/cli-interp.c (cli_interpreter_exec): Set the stream for the + cli's uiout to gdb_stdout, which has probably changed from it's + initialization. Restore the original stream when we're done executing + in the interpreter. + +2002-06-18 Keith Seitz + + * breakpoint.c (internal_breakpoint_number): Make static global. + (condition_command): Add modify breakpoint event notification. + (commands_command): Likewise. + (create_internal_breakpoint): internal_breakpoint_number is now global. + Add create breakpoint event notification. + (create_fork_vfork_event_catchpoint): Likewise. + (create_exec_event_catchpoint): Likewise. + (mention): Remove FIXME and create breakpoint event. + (create_breakpoints): Add create breakpoint event notification. + (watch_command_1): Likewise. + (create_exception_catchpoint): Likewise. + (set_breakpoint_sal): Likewise. + (set_ignore_count): Add modify breakopint event notification. + + * interps.h: Add GDB_INTERPRETER_MI1. GDB_INTERPRETER_MI will + now be mi version 2. + + * cli/cli-interp.c (cli_uiout): Make static. + (cli_interp): Make static. + (cli_interpreter_exec): Use cli_uiout instead of uiout. + +2002-05-28 Keith Seitz + + * cli/cli-interp.c: New file. Almost entirely from Apple's + sources. Collected and moved here. + * Makefile.in: Add new files. + Update dependencies on interps.h. + * defs.h (selected_frame_level_changed_hook): Add declaration. + * wrapper.c (captured_execute_command): New function. + (do_captured_execute_command): New function. + * wrapper.h (captured_execute_command): Declare. + * top.c (catcher): If the caught command changes the uiout on us, + try to do something sane, like using the current interpreter's + uiout. + + From Jim Ingham : + * event-loop.c (start_event_loop): Poll the interpreter's event loop + as well as gdb... + * event-top.c (gdb_setup_readline, gdb_disable_readline): New functions, + used by console & mi to grab & relinquish control of the readline input. + * event-top.h (gdb_setup_readline, gdb_disable_readline): Declare. + * main.c (captured_main): Copy the interpreter name, since we will + eventually use it as a set variable. + * top.c (gdb_init): Use the interpreter mechanism to startup the stdin + handling. + * interps.c: New file. (Originally called interpreter.c by Apple) + * interps.h: New file. (Originally called interpreter.h by Apple) + * mi/mi-cmds.c, mi/mi-cmds.h: Add mi commands -interpreter-set and + -interpreter-exec. + * mi/mi-main.c: Add the interpreter functions. + (mi_execute_command): Don't print the prompt if the command return + is MI_CMD_QUIET. + +2003-02-02 Elena Zannoni + + Fix PR gdb/742 gdb/743 gdb/877 + * disasm.c (dump_insns): Use make_cleanup_ui_out_tuple_begin_end. + (do_mixed_source_and_assembly): Use + make_cleanup_ui_out_tuple_begin_end and + make_cleanup_ui_out_tuple_begin_end. + (do_mixed_source_and_assembly): Ditto. + * thread.c (do_captured_list_thread_ids): Ditto. + * ui-out.h (ui_out_table_begin, ui_out_list_begin, + ui_out_tuple_begin, ui_out_table_end, ui_out_list_end, + ui_out_tuple_end): Delete prototypes. + * ui-out.c (ui_out_list_begin, ui_out_tuple_begin, + ui_out_list_end, ui_out_tuple_end): Delete. + + From Kevin Buettner : + * ui-out.h (make_cleanup_ui_out_table_begin_end): New function. + * ui-out.c (make_cleanup_ui_out_table_begin_end) + (do_cleanup_table_end): New functions. + * breakpoint.c (print_it_typical, print_one_breakpoint, mention): + Use cleanups to invoke_ui_out_tuple_end(). + (breakpoint_1): Use cleanup to invoke ui_out_table_end(). + * cli/cli-setshow.c (cmd_show_list): Use + make_cleanup_ui_out_tuple_begin_end. + 2003-02-02 Andrew Cagney * frame.c (frame_unwind_register): New function. @@ -610,6 +944,7 @@ 2003-01-14 Elena Zannoni + Fix PR gdb/898 * breakpoint.c (until_break_command): Add new argument. Use it to decide whether to stop only at the current frame or not. * breakpoint.h (until_break_command): Update prototype. diff --git a/gdb/Makefile.in b/gdb/Makefile.in index 8eee1c269d2..730d6e54686 100644 --- a/gdb/Makefile.in +++ b/gdb/Makefile.in @@ -144,11 +144,11 @@ TARGET_SYSTEM_ROOT_DEFINE = @TARGET_SYSTEM_ROOT_DEFINE@ # CLI sub directory definitons # SUBDIR_CLI_OBS = \ - cli-dump.o \ - cli-decode.o cli-script.o cli-cmds.o cli-setshow.o cli-utils.o + cli-dump.o cli-decode.o \ + cli-interp.o cli-script.o cli-cmds.o cli-setshow.o cli-utils.o SUBDIR_CLI_SRCS = \ - cli/cli-dump.c \ - cli/cli-decode.c cli/cli-script.c cli/cli-cmds.c cli/cli-setshow.c \ + cli/cli-dump.c cli/cli-decode.c \ + cli/cli-interp.c cli/cli-script.c cli/cli-cmds.c cli/cli-setshow.c \ cli/cli-utils.c SUBDIR_CLI_DEPS = SUBDIR_CLI_INITS = \ @@ -167,12 +167,16 @@ SUBDIR_MI_OBS = \ mi-out.o mi-console.o \ mi-cmds.o mi-cmd-env.o mi-cmd-var.o mi-cmd-break.o mi-cmd-stack.o \ mi-cmd-disas.o \ + mi-events.o \ + mi-interp.o \ mi-main.o mi-parse.o mi-getopt.o SUBDIR_MI_SRCS = \ mi/mi-out.c mi/mi-console.c \ mi/mi-cmds.c mi/mi-cmd-env.c \ mi/mi-cmd-var.c mi/mi-cmd-break.c mi/mi-cmd-stack.c \ mi/mi-cmd-disas.c \ + mi/mi-events.c \ + mi/mi-interp.c \ mi/mi-main.c mi/mi-parse.c mi/mi-getopt.c SUBDIR_MI_DEPS = SUBDIR_MI_INITS = \ @@ -516,7 +520,7 @@ SFILES = ada-exp.y ada-lang.c ada-typeprint.c ada-valprint.c ada-tasks.c \ frame-unwind.c \ gdbarch.c arch-utils.c gdbtypes.c gnu-v2-abi.c gnu-v3-abi.c \ hpacc-abi.c \ - inf-loop.c infcmd.c inflow.c infrun.c \ + inf-loop.c infcmd.c inflow.c infrun.c interps.c \ jv-exp.y jv-lang.c jv-valprint.c jv-typeprint.c \ kod.c kod-cisco.c \ language.c linespec.c \ @@ -655,6 +659,7 @@ i386_tdep_h = i386-tdep.h i387_tdep_h = i387-tdep.h inf_loop_h = inf-loop.h inferior_h = inferior.h $(breakpoint_h) $(target_h) $(frame_h) +interps_h = interps.h jv_lang_h = jv-lang.h kod_h = kod.h language_h = language.h @@ -828,7 +833,7 @@ COMMON_OBS = version.o blockframe.o breakpoint.o findvar.o regcache.o \ dbxread.o coffread.o elfread.o \ dwarfread.o dwarf2read.o mipsread.o stabsread.o corefile.o \ c-lang.o f-lang.o \ - ui-out.o cli-out.o \ + ui-out.o cli-out.o interps.o \ varobj.o wrapper.o \ jv-lang.o jv-valprint.o jv-typeprint.o \ m2-lang.o p-lang.o p-typeprint.o p-valprint.o \ @@ -1634,9 +1639,10 @@ eval.o: eval.c $(defs_h) $(gdb_string_h) $(symtab_h) $(gdbtypes_h) \ $(value_h) $(expression_h) $(target_h) $(frame_h) $(language_h) \ $(f_lang_h) $(cp_abi_h) event-loop.o: event-loop.c $(defs_h) $(event_loop_h) $(event_top_h) \ - $(gdb_string_h) + $(gdb_string_h) $(interps_h) event-top.o: event-top.c $(defs_h) $(top_h) $(inferior_h) $(target_h) \ - $(terminal_h) $(event_loop_h) $(event_top_h) $(gdbcmd_h) $(readline_h) + $(terminal_h) $(event_loop_h) $(event_top_h) $(gdbcmd_h) \ + $(readline_h) $(interps_h) exec.o: exec.c $(defs_h) $(frame_h) $(inferior_h) $(target_h) $(gdbcmd_h) \ $(language_h) $(symfile_h) $(objfiles_h) $(completer_h) $(value_h) \ $(gdb_string_h) $(gdbcore_h) $(gdb_stat_h) $(xcoffsolib_h) \ @@ -1697,6 +1703,8 @@ go32-nat.o: go32-nat.c $(defs_h) $(inferior_h) $(gdb_wait_h) $(gdbcore_h) \ $(command_h) $(gdbcmd_h) $(floatformat_h) $(buildsym_h) \ $(i387_tdep_h) $(i386_tdep_h) $(value_h) $(regcache_h) \ $(gdb_string_h) +interps.o: interps.c $(defs_h) $(gdbcmd_h) $(ui_out_h) $(event_loop_h) \ + $(event_top_h) $(interps_h) $(gdb_h) $(wrapper_h) $(gdb_events_h) h8300-tdep.o: h8300-tdep.c $(defs_h) $(frame_h) $(symtab_h) $(dis_asm_h) \ $(gdbcmd_h) $(gdbtypes_h) $(gdbcore_h) $(gdb_string_h) $(value_h) \ $(regcache_h) @@ -2311,6 +2319,9 @@ cli-dump.o: $(srcdir)/cli/cli-dump.c $(defs_h) $(gdb_string_h) \ $(cli_decode_h) $(cli_cmds_h) $(value_h) $(completer_h) \ $(cli_dump_h) $(gdb_assert_h) $(target_h) $(readline_h) $(CC) -c $(INTERNAL_CFLAGS) $(srcdir)/cli/cli-dump.c +cli-interp.o: $(srcdir)/cli/cli-interp.c $(defs_h) $(value_h) \ + $(wrapper_h) $(event_top_h) $(ui_out_h) $(cli_out_h) $(top_h) + $(CC) -c $(INTERNAL_CFLAGS) $(srcdir)/cli/cli-interp.c cli-script.o: $(srcdir)/cli/cli-script.c $(defs_h) $(value_h) $(language_h) \ $(ui_out_h) $(gdb_string_h) $(top_h) $(cli_cmds_h) $(cli_decode_h) \ $(cli_script_h) @@ -2471,7 +2482,7 @@ gdbtk-wrapper.o: $(srcdir)/gdbtk/generic/gdbtk-wrapper.c \ mi-cmd-break.o: $(srcdir)/mi/mi-cmd-break.c $(defs_h) $(mi_cmds_h) \ $(ui_out_h) $(mi_out_h) $(breakpoint_h) $(gdb_string_h) \ - $(mi_getopt_h) $(gdb_events_h) $(gdb_h) + $(mi_getopt_h) $(gdb_events_h) $(gdb_h) $(interps_h) $(CC) -c $(INTERNAL_CFLAGS) $(srcdir)/mi/mi-cmd-break.c mi-cmd-disas.o: $(srcdir)/mi/mi-cmd-disas.c $(defs_h) $(target_h) $(value_h) \ $(mi_cmds_h) $(mi_getopt_h) $(ui_out_h) $(gdb_string_h) $(disasm_h) @@ -2492,14 +2503,21 @@ mi-cmds.o: $(srcdir)/mi/mi-cmds.c $(defs_h) $(top_h) $(mi_cmds_h) \ mi-console.o: $(srcdir)/mi/mi-console.c $(defs_h) $(mi_console_h) \ $(gdb_string_h) $(CC) -c $(INTERNAL_CFLAGS) $(srcdir)/mi/mi-console.c +mi-events.o: $(srcdir)/mi/mi-events.c $(defs_h) $(ui_out_h) $(interps_h) \ + $(gdb_h) $(breakpoint_h) $(mi_h) + $(CC) -c $(INTERNAL_CFLAGS) $(srcdir)/mi/mi-events.c mi-getopt.o: $(srcdir)/mi/mi-getopt.c $(defs_h) $(mi_getopt_h) \ $(gdb_string_h) $(CC) -c $(INTERNAL_CFLAGS) $(srcdir)/mi/mi-getopt.c +mi-interp.o: $(srcdir)/mi/mi-interp.c $(defs_h) $(interps_h) \ + $(event_top_h) $(event_loop_h) $(inferior_h) $(ui_out_h) \ + $(top_h) $(mi_h) $(mi_cmds_h) $(mi_out_h) $(mi_console_h) + $(CC) -c $(INTERNAL_CFLAGS) $(srcdir)/mi/mi-interp.c mi-main.o: $(srcdir)/mi/mi-main.c $(defs_h) $(target_h) $(inferior_h) \ $(gdb_string_h) $(top_h) $(gdbthread_h) $(mi_cmds_h) $(mi_parse_h) \ $(mi_getopt_h) $(mi_console_h) $(ui_out_h) $(mi_out_h) \ $(event_loop_h) $(event_top_h) $(gdbcore_h) $(value_h) $(regcache_h) \ - $(gdb_h) $(frame_h) + $(gdb_h) $(frame_h) $(interps_h) $(CC) -c $(INTERNAL_CFLAGS) $(srcdir)/mi/mi-main.c mi-out.o: $(srcdir)/mi/mi-out.c $(defs_h) $(ui_out_h) $(mi_out_h) $(CC) -c $(INTERNAL_CFLAGS) $(srcdir)/mi/mi-out.c diff --git a/gdb/breakpoint.c b/gdb/breakpoint.c index 4544ed54a63..2190fadbcb6 100644 --- a/gdb/breakpoint.c +++ b/gdb/breakpoint.c @@ -2002,7 +2002,7 @@ top: static enum print_stop_action print_it_typical (bpstat bs) { - struct cleanup *old_chain; + struct cleanup *old_chain, *ui_out_chain; struct ui_stream *stb; stb = ui_out_stream_new (uiout); old_chain = make_cleanup_ui_out_stream_delete (stb); @@ -2163,14 +2163,14 @@ print_it_typical (bpstat bs) if (ui_out_is_mi_like_p (uiout)) ui_out_field_string (uiout, "reason", "watchpoint-trigger"); mention (bs->breakpoint_at); - ui_out_tuple_begin (uiout, "value"); + ui_out_chain = make_cleanup_ui_out_tuple_begin_end (uiout, "value"); ui_out_text (uiout, "\nOld value = "); value_print (bs->old_val, stb->stream, 0, Val_pretty_default); ui_out_field_stream (uiout, "old", stb); ui_out_text (uiout, "\nNew value = "); value_print (bs->breakpoint_at->val, stb->stream, 0, Val_pretty_default); ui_out_field_stream (uiout, "new", stb); - ui_out_tuple_end (uiout); + do_cleanups (ui_out_chain); ui_out_text (uiout, "\n"); value_free (bs->old_val); bs->old_val = NULL; @@ -2183,11 +2183,11 @@ print_it_typical (bpstat bs) if (ui_out_is_mi_like_p (uiout)) ui_out_field_string (uiout, "reason", "read-watchpoint-trigger"); mention (bs->breakpoint_at); - ui_out_tuple_begin (uiout, "value"); + ui_out_chain = make_cleanup_ui_out_tuple_begin_end (uiout, "value"); ui_out_text (uiout, "\nValue = "); value_print (bs->breakpoint_at->val, stb->stream, 0, Val_pretty_default); ui_out_field_stream (uiout, "value", stb); - ui_out_tuple_end (uiout); + do_cleanups (ui_out_chain); ui_out_text (uiout, "\n"); return PRINT_UNKNOWN; break; @@ -2199,7 +2199,7 @@ print_it_typical (bpstat bs) if (ui_out_is_mi_like_p (uiout)) ui_out_field_string (uiout, "reason", "access-watchpoint-trigger"); mention (bs->breakpoint_at); - ui_out_tuple_begin (uiout, "value"); + ui_out_chain = make_cleanup_ui_out_tuple_begin_end (uiout, "value"); ui_out_text (uiout, "\nOld value = "); value_print (bs->old_val, stb->stream, 0, Val_pretty_default); ui_out_field_stream (uiout, "old", stb); @@ -2212,12 +2212,12 @@ print_it_typical (bpstat bs) mention (bs->breakpoint_at); if (ui_out_is_mi_like_p (uiout)) ui_out_field_string (uiout, "reason", "access-watchpoint-trigger"); - ui_out_tuple_begin (uiout, "value"); + ui_out_chain = make_cleanup_ui_out_tuple_begin_end (uiout, "value"); ui_out_text (uiout, "\nValue = "); } value_print (bs->breakpoint_at->val, stb->stream, 0,Val_pretty_default); ui_out_field_stream (uiout, "new", stb); - ui_out_tuple_end (uiout); + do_cleanups (ui_out_chain); ui_out_text (uiout, "\n"); return PRINT_UNKNOWN; break; @@ -3229,9 +3229,10 @@ print_one_breakpoint (struct breakpoint *b, char wrap_indent[80]; struct ui_stream *stb = ui_out_stream_new (uiout); struct cleanup *old_chain = make_cleanup_ui_out_stream_delete (stb); + struct cleanup *bkpt_chain; annotate_record (); - ui_out_tuple_begin (uiout, "bkpt"); + bkpt_chain = make_cleanup_ui_out_tuple_begin_end (uiout, "bkpt"); /* 1 */ annotate_field (0); @@ -3469,12 +3470,14 @@ print_one_breakpoint (struct breakpoint *b, if ((l = b->commands)) { + struct cleanup *script_chain; + annotate_field (9); - ui_out_tuple_begin (uiout, "script"); + script_chain = make_cleanup_ui_out_tuple_begin_end (uiout, "script"); print_command_lines (uiout, l, 4); - ui_out_tuple_end (uiout); + do_cleanups (script_chain); } - ui_out_tuple_end (uiout); + do_cleanups (bkpt_chain); do_cleanups (old_chain); } @@ -3542,6 +3545,7 @@ breakpoint_1 (int bnum, int allflag) register struct breakpoint *b; CORE_ADDR last_addr = (CORE_ADDR) -1; int nr_printable_breakpoints; + struct cleanup *bkpttbl_chain; /* Compute the number of rows in the table. */ nr_printable_breakpoints = 0; @@ -3554,9 +3558,13 @@ breakpoint_1 (int bnum, int allflag) } if (addressprint) - ui_out_table_begin (uiout, 6, nr_printable_breakpoints, "BreakpointTable"); + bkpttbl_chain + = make_cleanup_ui_out_table_begin_end (uiout, 6, nr_printable_breakpoints, + "BreakpointTable"); else - ui_out_table_begin (uiout, 5, nr_printable_breakpoints, "BreakpointTable"); + bkpttbl_chain + = make_cleanup_ui_out_table_begin_end (uiout, 5, nr_printable_breakpoints, + "BreakpointTable"); if (nr_printable_breakpoints > 0) annotate_breakpoints_headers (); @@ -3598,7 +3606,7 @@ breakpoint_1 (int bnum, int allflag) print_one_breakpoint (b, &last_addr); } - ui_out_table_end (uiout); + do_cleanups (bkpttbl_chain); if (nr_printable_breakpoints == 0) { @@ -3891,6 +3899,7 @@ create_internal_breakpoint (CORE_ADDR address, enum bptype type) b = set_raw_breakpoint (sal, type); b->number = internal_breakpoint_number--; b->disposition = disp_donttouch; + breakpoint_create_event (b->number); return b; } @@ -4174,6 +4183,7 @@ solib_load_unload_1 (char *hookname, int tempflag, char *dll_pathname, } mention (b); + breakpoint_create_event (b->number); do_cleanups (old_chain); } @@ -4219,6 +4229,7 @@ create_fork_vfork_event_catchpoint (int tempflag, char *cond_string, b->forked_inferior_pid = 0; mention (b); + breakpoint_create_event (b->number); } void @@ -4257,6 +4268,7 @@ create_exec_event_catchpoint (int tempflag, char *cond_string) b->disposition = tempflag ? disp_del : disp_donttouch; mention (b); + breakpoint_create_event (b->number); } static int @@ -4380,6 +4392,7 @@ set_momentary_breakpoint (struct symtab_and_line sal, struct frame_id frame_id, if (in_thread_list (inferior_ptid)) b->thread = pid_to_thread_id (inferior_ptid); + breakpoint_create_event (b->number); return b; } @@ -4390,21 +4403,12 @@ static void mention (struct breakpoint *b) { int say_where = 0; - struct cleanup *old_chain; + struct cleanup *old_chain, *ui_out_chain; struct ui_stream *stb; stb = ui_out_stream_new (uiout); old_chain = make_cleanup_ui_out_stream_delete (stb); - /* FIXME: This is misplaced; mention() is called by things (like hitting a - watchpoint) other than breakpoint creation. It should be possible to - clean this up and at the same time replace the random calls to - breakpoint_changed with this hook, as has already been done for - delete_breakpoint_hook and so on. */ - if (create_breakpoint_hook) - create_breakpoint_hook (b); - breakpoint_create_event (b->number); - switch (b->type) { case bp_none: @@ -4412,39 +4416,39 @@ mention (struct breakpoint *b) break; case bp_watchpoint: ui_out_text (uiout, "Watchpoint "); - ui_out_tuple_begin (uiout, "wpt"); + ui_out_chain = make_cleanup_ui_out_tuple_begin_end (uiout, "wpt"); ui_out_field_int (uiout, "number", b->number); ui_out_text (uiout, ": "); print_expression (b->exp, stb->stream); ui_out_field_stream (uiout, "exp", stb); - ui_out_tuple_end (uiout); + do_cleanups (ui_out_chain); break; case bp_hardware_watchpoint: ui_out_text (uiout, "Hardware watchpoint "); - ui_out_tuple_begin (uiout, "wpt"); + ui_out_chain = make_cleanup_ui_out_tuple_begin_end (uiout, "wpt"); ui_out_field_int (uiout, "number", b->number); ui_out_text (uiout, ": "); print_expression (b->exp, stb->stream); ui_out_field_stream (uiout, "exp", stb); - ui_out_tuple_end (uiout); + do_cleanups (ui_out_chain); break; case bp_read_watchpoint: ui_out_text (uiout, "Hardware read watchpoint "); - ui_out_tuple_begin (uiout, "hw-rwpt"); + ui_out_chain = make_cleanup_ui_out_tuple_begin_end (uiout, "hw-rwpt"); ui_out_field_int (uiout, "number", b->number); ui_out_text (uiout, ": "); print_expression (b->exp, stb->stream); ui_out_field_stream (uiout, "exp", stb); - ui_out_tuple_end (uiout); + do_cleanups (ui_out_chain); break; case bp_access_watchpoint: ui_out_text (uiout, "Hardware access (read/write) watchpoint "); - ui_out_tuple_begin (uiout, "hw-awpt"); + ui_out_chain = make_cleanup_ui_out_tuple_begin_end (uiout, "hw-awpt"); ui_out_field_int (uiout, "number", b->number); ui_out_text (uiout, ": "); print_expression (b->exp, stb->stream); ui_out_field_stream (uiout, "exp", stb); - ui_out_tuple_end (uiout); + do_cleanups (ui_out_chain); break; case bp_breakpoint: if (ui_out_is_mi_like_p (uiout)) @@ -4575,6 +4579,7 @@ create_breakpoints (struct symtabs_and_lines sals, char **addr_string, b->enable_state = bp_enabled; b->disposition = disposition; mention (b); + breakpoint_create_event (b->number); } } } @@ -5429,9 +5434,12 @@ watch_command_1 (char *arg, int accessflag, int from_tty) /* The scope breakpoint is related to the watchpoint. We will need to act on them together. */ b->related_breakpoint = scope_breakpoint; + + breakpoint_create_event (scope_breakpoint->number); } } value_free_to_mark (mark); + breakpoint_create_event (b->number); mention (b); } @@ -6175,6 +6183,7 @@ create_exception_catchpoint (int tempflag, char *cond_string, b->enable_state = bp_enabled; b->disposition = tempflag ? disp_del : disp_donttouch; mention (b); + breakpoint_create_event (b->number); } /* Deal with "catch catch" and "catch throw" commands */ @@ -6340,6 +6349,7 @@ handle_gnu_4_16_catch_command (char *arg, int tempflag, int from_tty) b->disposition = tempflag ? disp_del : disp_donttouch; mention (b); + breakpoint_create_event (b->number); } if (sals.nelts > 1) @@ -6482,6 +6492,7 @@ set_breakpoint_sal (struct symtab_and_line sal) b->number = breakpoint_count; b->cond = 0; b->thread = -1; + breakpoint_create_event (b->number); return b; } diff --git a/gdb/cli-out.c b/gdb/cli-out.c index bd079f250bb..e3b45cdd538 100644 --- a/gdb/cli-out.c +++ b/gdb/cli-out.c @@ -365,6 +365,15 @@ cli_out_new (struct ui_file *stream) return ui_out_new (&cli_ui_out_impl, data, flags); } +struct ui_file * +cli_out_set_stream (struct ui_out *uiout, struct ui_file *stream) +{ + struct ui_out_data *data = ui_out_data (uiout); + struct ui_file *old = data->stream; + data->stream = stream; + return old; +} + /* standard gdb initialization hook */ void _initialize_cli_out (void) diff --git a/gdb/cli-out.h b/gdb/cli-out.h index 723b7260cbf..90fd446bbba 100644 --- a/gdb/cli-out.h +++ b/gdb/cli-out.h @@ -23,5 +23,6 @@ #define CLI_OUT_H extern struct ui_out *cli_out_new (struct ui_file *stream); - +extern struct ui_file *cli_out_set_stream (struct ui_out *uiout, + struct ui_file *stream); #endif diff --git a/gdb/cli/cli-interp.c b/gdb/cli/cli-interp.c new file mode 100644 index 00000000000..2bbf647243b --- /dev/null +++ b/gdb/cli/cli-interp.c @@ -0,0 +1,137 @@ +/* CLI Definitions for GDB + Copyright 2002 Free Software Foundation, Inc. + + This file is part of GDB. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. */ + +#include "defs.h" +#include "interps.h" +#include "wrapper.h" +#include "event-top.h" +#include "ui-out.h" +#include "cli-out.h" +#include "top.h" /* for "execute_command" */ +/* Prototypes for the CLI Interpreter functions */ + +static int cli_interpreter_init (void *data); +static int cli_interpreter_resume (void *data); +static int cli_interpreter_suspend (void *data); +static int cli_interpreter_exec (void *data, char *command_str); +static int cli_interpreter_display_prompt_p (void); + +/* These are the ui_out and the interpreter for the console interpreter. */ +static struct ui_out *cli_uiout; +static struct gdb_interpreter *cli_interp; + +/* Longjmp-safe wrapper for "execute_command" */ +static int do_captured_execute_command (struct ui_out *uiout, void *data); +static enum gdb_rc safe_execute_command (struct ui_out *uiout, char *command, + int from_tty); +struct captured_execute_command_args +{ + char *command; + int from_tty; +}; + +/* These implement the cli out interpreter: */ + +static int +cli_interpreter_init (void *data) +{ + return 1; +} + +static int +cli_interpreter_resume (void *data) +{ + /*sync_execution = 1;*/ + gdb_setup_readline (); + return 1; +} + +static int +cli_interpreter_suspend (void *data) +{ + gdb_disable_readline (); + return 1; +} + +/* Don't display the prompt if we are set quiet. */ +static int +cli_interpreter_display_prompt_p (void) +{ + if (gdb_interpreter_is_quiet_p (NULL)) + return 0; + else + return 1; +} + +static int +cli_interpreter_exec (void *data, char *command_str) +{ + int result; + struct ui_file *old_stream; + + /* gdb_stdout could change between the time cli_uiout was initialized + and now. Since we're probably using a different interpreter which has + a new ui_file for gdb_stdout, use that one instead of the default. + + It is important that it gets reset everytime, since the user could + set gdb to use a different interpreter. */ + old_stream = cli_out_set_stream (cli_uiout, gdb_stdout); + result = safe_execute_command (cli_uiout, command_str, 1); + cli_out_set_stream (cli_uiout, old_stream); + return result; +} + +static int +do_captured_execute_command (struct ui_out *uiout, void *data) +{ + struct captured_execute_command_args *args = + (struct captured_execute_command_args *) data; + execute_command (args->command, args->from_tty); + return GDB_RC_OK; +} + +static enum gdb_rc +safe_execute_command (struct ui_out *uiout, char *command, int from_tty) +{ + struct captured_execute_command_args args; + args.command = command; + args.from_tty = from_tty; + return catch_exceptions (uiout, do_captured_execute_command, &args, + NULL, RETURN_MASK_ALL); +} + +/* standard gdb initialization hook */ +void +_initialize_cli_interp (void) +{ + struct gdb_interpreter_procs procs = { + cli_interpreter_init, /* init_proc */ + cli_interpreter_resume, /* resume_proc */ + cli_interpreter_suspend, /* suspend_proc */ + cli_interpreter_exec, /* exec_proc */ + cli_interpreter_display_prompt_p /* prompt_proc_p */ + }; + + /* Create a default uiout builder for the CLI. */ + cli_uiout = cli_out_new (gdb_stdout); + cli_interp = gdb_interpreter_new (GDB_INTERPRETER_CONSOLE, NULL, cli_uiout, + &procs); + gdb_interpreter_add (cli_interp); +} diff --git a/gdb/cli/cli-setshow.c b/gdb/cli/cli-setshow.c index 6fe2ff0816b..1d68ae4aa1a 100644 --- a/gdb/cli/cli-setshow.c +++ b/gdb/cli/cli-setshow.c @@ -1,6 +1,6 @@ /* Handle set and show GDB commands. - Copyright 2000, 2001, 2002 Free Software Foundation, Inc. + Copyright 2000, 2001, 2002, 2003 Free Software Foundation, Inc. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -353,28 +353,35 @@ do_setshow_command (char *arg, int from_tty, struct cmd_list_element *c) void cmd_show_list (struct cmd_list_element *list, int from_tty, char *prefix) { - ui_out_tuple_begin (uiout, "showlist"); + struct cleanup *showlist_chain; + + showlist_chain = make_cleanup_ui_out_tuple_begin_end (uiout, "showlist"); for (; list != NULL; list = list->next) { /* If we find a prefix, run its list, prefixing our output by its prefix (with "show " skipped). */ if (list->prefixlist && !list->abbrev_flag) { - ui_out_tuple_begin (uiout, "optionlist"); + struct cleanup *optionlist_chain + = make_cleanup_ui_out_tuple_begin_end (uiout, "optionlist"); ui_out_field_string (uiout, "prefix", list->prefixname + 5); cmd_show_list (*list->prefixlist, from_tty, list->prefixname + 5); - ui_out_tuple_end (uiout); + /* Close the tuple. */ + do_cleanups (optionlist_chain); } if (list->type == show_cmd) { - ui_out_tuple_begin (uiout, "option"); + struct cleanup *option_chain + = make_cleanup_ui_out_tuple_begin_end (uiout, "option"); ui_out_text (uiout, prefix); ui_out_field_string (uiout, "name", list->name); ui_out_text (uiout, ": "); do_setshow_command ((char *) NULL, from_tty, list); - ui_out_tuple_end (uiout); + /* Close the tuple. */ + do_cleanups (option_chain); } } - ui_out_tuple_end (uiout); + /* Close the tuple. */ + do_cleanups (showlist_chain); } diff --git a/gdb/defs.h b/gdb/defs.h index d2a16158d37..fe53c82b598 100644 --- a/gdb/defs.h +++ b/gdb/defs.h @@ -1195,7 +1195,6 @@ extern void (*error_begin_hook) (void); extern int (*ui_load_progress_hook) (const char *section, unsigned long num); - /* Inhibit window interface if non-zero. */ extern int use_windows; diff --git a/gdb/disasm.c b/gdb/disasm.c index 4ac22a27a6e..75d1783d13f 100644 --- a/gdb/disasm.c +++ b/gdb/disasm.c @@ -97,6 +97,7 @@ dump_insns (struct ui_out *uiout, disassemble_info * di, char *name = NULL; int offset; int line; + struct cleanup *ui_out_chain; for (pc = low; pc < high;) { @@ -108,7 +109,7 @@ dump_insns (struct ui_out *uiout, disassemble_info * di, else num_displayed++; } - ui_out_tuple_begin (uiout, NULL); + ui_out_chain = make_cleanup_ui_out_tuple_begin_end (uiout, NULL); ui_out_field_core_addr (uiout, "address", pc); if (!build_address_symbolic (pc, 0, &name, &offset, &filename, @@ -131,7 +132,7 @@ dump_insns (struct ui_out *uiout, disassemble_info * di, pc += TARGET_PRINT_INSN (pc, di); ui_out_field_stream (uiout, "inst", stb); ui_file_rewind (stb->stream); - ui_out_tuple_end (uiout); + do_cleanups (ui_out_chain); ui_out_text (uiout, "\n"); } return num_displayed; @@ -157,6 +158,7 @@ do_mixed_source_and_assembly (struct ui_out *uiout, int next_line = 0; CORE_ADDR pc; int num_displayed = 0; + struct cleanup *ui_out_chain; mle = (struct dis_line_entry *) alloca (nlines * sizeof (struct dis_line_entry)); @@ -210,11 +212,14 @@ do_mixed_source_and_assembly (struct ui_out *uiout, they have been emitted before), followed by the assembly code for that line. */ - ui_out_list_begin (uiout, "asm_insns"); + ui_out_chain = make_cleanup_ui_out_list_begin_end (uiout, "asm_insns"); for (i = 0; i < newlines; i++) { + struct cleanup *ui_out_tuple_chain = NULL; + struct cleanup *ui_out_list_chain = NULL; int close_list = 1; + /* Print out everything from next_line to the current line. */ if (mle[i].line >= next_line) { @@ -223,7 +228,9 @@ do_mixed_source_and_assembly (struct ui_out *uiout, /* Just one line to print. */ if (next_line == mle[i].line) { - ui_out_tuple_begin (uiout, "src_and_asm_line"); + ui_out_tuple_chain + = make_cleanup_ui_out_tuple_begin_end (uiout, + "src_and_asm_line"); print_source_lines (symtab, next_line, mle[i].line + 1, 0); } else @@ -231,27 +238,38 @@ do_mixed_source_and_assembly (struct ui_out *uiout, /* Several source lines w/o asm instructions associated. */ for (; next_line < mle[i].line; next_line++) { - ui_out_tuple_begin (uiout, "src_and_asm_line"); + struct cleanup *ui_out_list_chain_line; + struct cleanup *ui_out_tuple_chain_line; + + ui_out_tuple_chain_line + = make_cleanup_ui_out_tuple_begin_end (uiout, + "src_and_asm_line"); print_source_lines (symtab, next_line, next_line + 1, 0); - ui_out_list_begin (uiout, "line_asm_insn"); - ui_out_list_end (uiout); - ui_out_tuple_end (uiout); + ui_out_list_chain_line + = make_cleanup_ui_out_list_begin_end (uiout, + "line_asm_insn"); + do_cleanups (ui_out_list_chain_line); + do_cleanups (ui_out_tuple_chain_line); } /* Print the last line and leave list open for asm instructions to be added. */ - ui_out_tuple_begin (uiout, "src_and_asm_line"); + ui_out_tuple_chain + = make_cleanup_ui_out_tuple_begin_end (uiout, + "src_and_asm_line"); print_source_lines (symtab, next_line, mle[i].line + 1, 0); } } else { - ui_out_tuple_begin (uiout, "src_and_asm_line"); + ui_out_tuple_chain + = make_cleanup_ui_out_tuple_begin_end (uiout, "src_and_asm_line"); print_source_lines (symtab, mle[i].line, mle[i].line + 1, 0); } next_line = mle[i].line + 1; - ui_out_list_begin (uiout, "line_asm_insn"); + ui_out_list_chain + = make_cleanup_ui_out_list_begin_end (uiout, "line_asm_insn"); /* Don't close the list if the lines are not in order. */ if (i < (newlines - 1) && mle[i + 1].line <= mle[i].line) close_list = 0; @@ -261,8 +279,8 @@ do_mixed_source_and_assembly (struct ui_out *uiout, how_many, stb); if (close_list) { - ui_out_list_end (uiout); - ui_out_tuple_end (uiout); + do_cleanups (ui_out_list_chain); + do_cleanups (ui_out_tuple_chain); ui_out_text (uiout, "\n"); close_list = 0; } @@ -270,7 +288,7 @@ do_mixed_source_and_assembly (struct ui_out *uiout, if (num_displayed >= how_many) break; } - ui_out_list_end (uiout); + do_cleanups (ui_out_chain); } @@ -280,12 +298,13 @@ do_assembly_only (struct ui_out *uiout, disassemble_info * di, int how_many, struct ui_stream *stb) { int num_displayed = 0; + struct cleanup *ui_out_chain; - ui_out_list_begin (uiout, "asm_insns"); + ui_out_chain = make_cleanup_ui_out_list_begin_end (uiout, "asm_insns"); num_displayed = dump_insns (uiout, di, low, high, how_many, stb); - ui_out_list_end (uiout); + do_cleanups (ui_out_chain); } void diff --git a/gdb/doc/ChangeLog b/gdb/doc/ChangeLog index 832ac375c64..da1ac3d5d32 100644 --- a/gdb/doc/ChangeLog +++ b/gdb/doc/ChangeLog @@ -1,3 +1,13 @@ +2002-08-29 Keith Seitz + + * gdb.texinfo: Update interpreter chapters with indexing + information. Recommended by Eli Zaretskii . + +2002-08-28 Keith Seitz + + * gdb.texinfo: Add chapter on interpreters. Refer the + command-line option "-i"/"--interpreter" to this chapter. + 2003-02-01 Andrew Cagney * gdbint.texinfo (Target Architecture Definition): Delete diff --git a/gdb/doc/gdb.texinfo b/gdb/doc/gdb.texinfo index b3dd7a7f1dd..d2b4c702f1b 100644 --- a/gdb/doc/gdb.texinfo +++ b/gdb/doc/gdb.texinfo @@ -1123,7 +1123,8 @@ Do not use this option if you run @value{GDBN} from Emacs @cindex @code{--interpreter} Use the interpreter @var{interp} for interface with the controlling program or device. This option is meant to be set by programs which -communicate with @value{GDBN} using it as a back end. +communicate with @value{GDBN} using it as a back end. @xref{Interpreters, , +Command Interpreters}. @samp{--interpreter=mi} (or @samp{--interpreter=mi2}) causes @value{GDBN} to use the current @dfn{@sc{gdb/mi} interface} @@ -13220,6 +13221,70 @@ string are the simple ones that consist of backslash followed by a letter. @end table +@node Interpreters +@chapter Command Interpreters +@cindex command interpreters + +@value{GDBN} supports multiple command interpreters, and some command +infrastructure to allow users or user interface writers to switch between +interpreters or run commands in other interpreters. + +@value{GDBN} currently supports two command interpreters, the console +interpreter (sometimes called the command-line interpreter or @sc{cli}) and +the machine interface interpreter (or @sc{gdb/mi}). This manual describes +both of these interfaces in great detail. + +By default, @value{GDBN} will start with the console interpreter. However, +the user may choose to start @value{GDBN} with another interpreter by specifying +the @option{-i} or @option{--interpreter} startup options. Defined interpreters +include: + +@table @code +@item console +@cindex console interpreter +The traditional console or command-line interpreter. This is the most often +used interpreter with @value{GDBN}. With no interpreter specified at runtime, +@value{GDBN} will use this interpreter. + +@item mi +@cindex mi interpreter +The newest @sc{gdb/mi} interface, used primarily by programs wishing to use +@value{GDBN} as a backend for a debugger GUI or an IDE. For more information, +see @ref{GDB/MI, ,The @sc{gdb/mi} Interface}. + +@item mi2 +@cindex mi2 interpreter +The latest version of the @sc{gdb/mi} interface. + +@item mi1 +@cindex mi1 interpreter +The @sc{gdb/mi} version included in @value{GDBN} version 5.1. + +@item mi0 +@cindex mi0 interpreter +The @sc{gdb/mi} version included in @value{GDBN} version 5.0. +@end table + +@cindex invoke another interpreter +The interpreter being used by @value{GDBN} may not be dynamically switched at +runtime. Although possible, this could lead to a very precarious situation. +Consider an IDE using @sc{gdb/mi}. If a user enters the command +"interpreter-set console" in a console view, @value{GDBN} would switch +to using the console interpreter, rendering the IDE inoperable! + +@kindex interpreter-exec +Although you may only choose a single interpreter at startup, you may execute +commands in any interpreter from the current interpreter using the appropriate +command. If you are running the console interpreter, simply use the +@code{interpreter-exec} command: + +@smallexample +interpreter-exec mi "-data-list-register-names" +@end smallexample + +@sc{gdb/mi} has a similar command, although it is only available in versions of +@value{GDBN} which support @sc{gdb/mi} version 2 (or greater). + @node TUI @chapter @value{GDBN} Text User Interface @cindex TUI diff --git a/gdb/event-top.c b/gdb/event-top.c index 8f39998ed9b..8673c1d4a89 100644 --- a/gdb/event-top.c +++ b/gdb/event-top.c @@ -26,6 +26,7 @@ #include "terminal.h" /* for job_control */ #include "event-loop.h" #include "event-top.h" +#include "interps.h" #include /* For dont_repeat() */ @@ -250,9 +251,9 @@ display_gdb_prompt (char *new_prompt) int prompt_length = 0; char *gdb_prompt = get_prompt (); - /* When an alternative interpreter has been installed, do not - display the comand prompt. */ - if (interpreter_p) + /* Each interpreter has its own rules on wether or not display the + command prompt. */ + if (!gdb_interpreter_display_prompt_p ()) return; if (target_executing && sync_execution) @@ -1125,6 +1126,11 @@ gdb_setup_readline (void) if (event_loop_p) { + gdb_stdout = stdio_fileopen (stdout); + gdb_stderr = stdio_fileopen (stderr); + gdb_stdlog = gdb_stderr; /* for moment */ + gdb_stdtarg = gdb_stderr; /* for moment */ + /* If the input stream is connected to a terminal, turn on editing. */ if (ISATTY (instream)) @@ -1197,8 +1203,6 @@ gdb_disable_readline (void) void _initialize_event_loop (void) { - gdb_setup_readline (); - /* Tell gdb to use the cli_command_loop as the main loop. */ if (event_loop_p && command_loop_hook == NULL) command_loop_hook = cli_command_loop; diff --git a/gdb/event-top.h b/gdb/event-top.h index 24044a57bab..d8c0a963989 100644 --- a/gdb/event-top.h +++ b/gdb/event-top.h @@ -71,6 +71,8 @@ struct prompts FIXME: these should really go into top.h. */ extern void display_gdb_prompt (char *new_prompt); +void gdb_setup_readline (void); +void gdb_disable_readline (void); extern void async_init_signals (void); extern void set_async_editing_command (char *args, int from_tty, struct cmd_list_element *c); diff --git a/gdb/gdb-events.sh b/gdb/gdb-events.sh index 458e4b60b9c..bf738d50678 100755 --- a/gdb/gdb-events.sh +++ b/gdb/gdb-events.sh @@ -86,7 +86,6 @@ f:void:selected_thread_changed:int thread_num:thread_num #*:void:warning_hook:const char *string, va_list args:string, args #*:void:target_output_hook:char *b:b #*:void:interactive_hook:void -#*:void:registers_changed_hook:void #*:void:readline_begin_hook:char *format, ...:format #*:char *:readline_hook:char *prompt:prompt #*:void:readline_end_hook:void @@ -101,7 +100,6 @@ f:void:selected_thread_changed:int thread_num:thread_num #*:int:gdb_load_progress_hook:char *section, unsigned long num:section, num #*:void:pre_add_symbol_hook:char *name:name #*:void:post_add_symbol_hook:void -#*:void:selected_frame_level_changed_hook:int level:level #*:int:gdb_loop_hook:int signo:signo ##*:void:solib_create_inferior_hook:void ##*:void:xcoff_relocate_symtab_hook:unsigned int diff --git a/gdb/interps.c b/gdb/interps.c new file mode 100644 index 00000000000..187d8d98e58 --- /dev/null +++ b/gdb/interps.c @@ -0,0 +1,509 @@ +/* Manages interpreters for gdb. + Copyright 2000, 2002 Free Software Foundation, Inc. + Written by Jim Ingham of Apple Computer, Inc. + + This file is part of GDB. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. */ + +/* This is just a first cut at separating out the "interpreter" functions + of gdb into self-contained modules. There are a couple of open areas that + need to be sorted out: + + 1) The interpreter explicitly contains a UI_OUT, and can insert itself + into the event loop, but it doesn't explicitly contain hooks for readline. + I did this because it seems to me many interpreters won't want to use + the readline command interface, and it is probably simpler to just let + them take over the input in their resume proc. +*/ + +#include "defs.h" +#include "gdbcmd.h" +#include "ui-out.h" +#include "event-loop.h" +#include "event-top.h" +#include "interps.h" +#include "completer.h" +#include "gdb_string.h" +#include "gdb-events.h" + +struct gdb_interpreter +{ + /* This is the name in "-i=" and set interpreter. */ + char *name; + + /* Interpreters are stored in a linked list, this is the next one... */ + struct gdb_interpreter *next; + + /* This is a cookie that the instance of the interpreter can use, for + instance to call itself in hook functions */ + void *data; + + /* Has the init_proc been run? */ + int inited; + + /* This is the ui_out used to collect results for this interpreter. + It can be a formatter for stdout, as is the case for the console + & mi outputs, or it might be a result formatter. */ + struct ui_out *interpreter_out; + + struct gdb_interpreter_procs procs; + int quiet_p; +}; + +/* Functions local to this file. */ +static void initialize_interps (void); +static char **interpreter_completer (char *text, char *word); + +/* The magic initialization routine for this module. */ + +void _initialize_interpreter (void); + +/* Variables local to this file: */ + +static struct gdb_interpreter *interp_list = NULL; +static struct gdb_interpreter *current_interpreter = NULL; + +static int interpreter_initialized = 0; + +/* gdb_interpreter_new - This allocates space for a new interpreter, + fills the fields from the inputs, and returns a pointer to the + interpreter. */ +struct gdb_interpreter * +gdb_interpreter_new (char *name, + void *data, + struct ui_out *uiout, + struct gdb_interpreter_procs *procs) +{ + struct gdb_interpreter *new_interp; + + new_interp = + (struct gdb_interpreter *) xmalloc (sizeof (struct gdb_interpreter)); + + new_interp->name = xstrdup (name); + new_interp->data = data; + new_interp->interpreter_out = uiout; + new_interp->quiet_p = 0; + new_interp->procs.init_proc = procs->init_proc; + new_interp->procs.resume_proc = procs->resume_proc; + new_interp->procs.suspend_proc = procs->suspend_proc; + new_interp->procs.exec_proc = procs->exec_proc; + new_interp->procs.prompt_proc_p = procs->prompt_proc_p; + new_interp->inited = 0; + + return new_interp; +} + +/* Add interpreter INTERP to the gdb interpreter list. If an + interpreter of the same name is already on the list, then + the new one is NOT added, and the function returns 0. Otherwise + it returns 1. */ +int +gdb_interpreter_add (struct gdb_interpreter *interp) +{ + if (!interpreter_initialized) + initialize_interps (); + + if (gdb_interpreter_lookup (interp->name) != NULL) + return 0; + + interp->next = interp_list; + interp_list = interp; + + return 1; +} + +/* This sets the current interpreter to be INTERP. If INTERP has not + been initialized, then this will also run the init proc. If the + init proc is successful, return 1, if it fails, set the old + interpreter back in place and return 0. If we can't restore the + old interpreter, then raise an internal error, since we are in + pretty bad shape at this point. */ +int +gdb_interpreter_set (struct gdb_interpreter *interp) +{ + struct gdb_interpreter *old_interp = current_interpreter; + int first_time = 0; + + + char buffer[64]; + + if (current_interpreter != NULL) + { + do_all_continuations (); + ui_out_flush (uiout); + if (current_interpreter->procs.suspend_proc + && !current_interpreter->procs.suspend_proc (current_interpreter-> + data)) + { + error ("Could not suspend interpreter \"%s\"\n", + current_interpreter->name); + } + } + else + { + first_time = 1; + } + + current_interpreter = interp; + + /* We use interpreter_p for the "set interpreter" variable, so we need + to make sure we have a malloc'ed copy for the set command to free. */ + if (interpreter_p != NULL + && strcmp (current_interpreter->name, interpreter_p) != 0) + { + xfree (interpreter_p); + + interpreter_p = xstrdup (current_interpreter->name); + } + + uiout = interp->interpreter_out; + + /* Run the init proc. If it fails, try to restore the old interp. */ + + if (!interp->inited) + { + if (interp->procs.init_proc != NULL) + { + if (!interp->procs.init_proc (interp->data)) + { + if (!gdb_interpreter_set (old_interp)) + internal_error (__FILE__, __LINE__, + "Failed to initialize new interp \"%s\" %s", + interp->name, + "and could not restore old interp!\n"); + return 0; + } + else + { + interp->inited = 1; + } + } + else + { + interp->inited = 1; + } + } + + /* Clear out any installed interpreter hooks/event handlers. */ + clear_interpreter_hooks (); + + if (interp->procs.resume_proc != NULL + && (!interp->procs.resume_proc (interp->data))) + { + if (!gdb_interpreter_set (old_interp)) + internal_error (__FILE__, __LINE__, + "Failed to initialize new interp \"%s\" %s", + interp->name, "and could not restore old interp!\n"); + return 0; + } + + /* Finally, put up the new prompt to show that we are indeed here. + Also, display_gdb_prompt for the console does some readline magic + which is needed for the console interpreter, at least... */ + + if (!first_time) + { + if (!gdb_interpreter_is_quiet_p (interp)) + { + sprintf (buffer, "Switching to interpreter \"%.24s\".\n", + interp->name); + ui_out_text (uiout, buffer); + } + display_gdb_prompt (NULL); + } + + return 1; +} + +/* gdb_interpreter_lookup - Looks up the interpreter for NAME. If no + such interpreter exists, return NULL, otherwise return a pointer to + the interpreter. */ +struct gdb_interpreter * +gdb_interpreter_lookup (char *name) +{ + struct gdb_interpreter *interp; + + if (name == NULL || strlen (name) == 0) + return NULL; + + for (interp = interp_list; interp != NULL; interp = interp->next) + { + if (strcmp (interp->name, name) == 0) + return interp; + } + + return NULL; +} + +/* Returns the current interpreter. */ +static struct gdb_interpreter * +gdb_interpreter_current (void) +{ + return current_interpreter; +} + +struct ui_out * +gdb_interpreter_ui_out (struct gdb_interpreter *interp) +{ + if (interp != NULL) + return interp->interpreter_out; + + return current_interpreter->interpreter_out; +} + +/* Returns true if the current interp is the passed in name. */ +int +gdb_interpreter_current_is_named_p (char *interp_name) +{ + struct gdb_interpreter *current_interp = gdb_interpreter_current (); + + if (current_interp) + return (strcmp (current_interp->name, interp_name) == 0); + + return 0; +} + +/* This is called in display_gdb_prompt. + If the proc returns a zero value, display_gdb_prompt will + return without displaying the prompt. */ +int +gdb_interpreter_display_prompt_p (void) +{ + if (current_interpreter->procs.prompt_proc_p == NULL) + return 0; + else + return current_interpreter->procs.prompt_proc_p (); +} + +int +gdb_interpreter_is_quiet_p (struct gdb_interpreter *interp) +{ + if (interp != NULL) + return interp->quiet_p; + else + return current_interpreter->quiet_p; +} + +int +gdb_interpreter_set_quiet (struct gdb_interpreter *interp, int quiet) +{ + int old_val = interp->quiet_p; + interp->quiet_p = quiet; + return old_val; +} + +/* gdb_interpreter_exec - This executes COMMAND_STR in the current + interpreter. */ +int +gdb_interpreter_exec (char *command_str) +{ + if (current_interpreter->procs.exec_proc != NULL) + { + return current_interpreter->procs.exec_proc (current_interpreter->data, + command_str); + } + return 0; +} + +/* Accessor function. Not used at the moment. */ +struct gdb_interpreter_procs * +gdb_interpreter_get_procs (struct gdb_interpreter *interp) +{ + if (interp != NULL) + return &interp->procs; + + return ¤t_interpreter->procs; +} + +/* Accessor function. Not used at the moment. */ +void * +gdb_interpreter_get_data (struct gdb_interpreter *interp) +{ + if (interp != NULL) + return interp->data; + + return current_interpreter->data; +} + +/* A convenience routine that nulls out all the + common command hooks. Use it when removing your interpreter in its + suspend proc. */ +void +clear_interpreter_hooks () +{ + init_ui_hook = 0; + print_frame_info_listing_hook = 0; + /*print_frame_more_info_hook = 0; */ + query_hook = 0; + warning_hook = 0; + create_breakpoint_hook = 0; + delete_breakpoint_hook = 0; + modify_breakpoint_hook = 0; + interactive_hook = 0; + registers_changed_hook = 0; + readline_begin_hook = 0; + readline_hook = 0; + readline_end_hook = 0; + register_changed_hook = 0; + memory_changed_hook = 0; + context_hook = 0; + target_wait_hook = 0; + call_command_hook = 0; + error_hook = 0; + error_begin_hook = 0; + command_loop_hook = 0; + clear_gdb_event_hooks (); +} + +/* This is a lazy init routine, called the first time + the interpreter module is used. I put it here just in case, but I haven't + thought of a use for it yet. I will probably bag it soon, since I don't + think it will be necessary. */ +static void +initialize_interps (void) +{ + interpreter_initialized = 1; + /* Don't know if anything needs to be done here... */ +} + +void +interpreter_exec_cmd (char *args, int from_tty) +{ + struct gdb_interpreter *old_interp, *interp_to_use; + char **prules = NULL; + char **trule = NULL; + unsigned int nrules; + unsigned int i; + int old_quiet, use_quiet; + + prules = buildargv (args); + if (prules == NULL) + { + error ("unable to parse arguments"); + } + + nrules = 0; + if (prules != NULL) + { + for (trule = prules; *trule != NULL; trule++) + { + nrules++; + } + } + + if (nrules < 2) + error ("usage: interpreter-exec [ ... ]"); + + old_interp = gdb_interpreter_current (); + + interp_to_use = gdb_interpreter_lookup (prules[0]); + if (interp_to_use == NULL) + error ("Could not find interpreter \"%s\".", prules[0]); + + /* Temporarily set interpreters quiet */ + old_quiet = gdb_interpreter_set_quiet (old_interp, 1); + use_quiet = gdb_interpreter_set_quiet (interp_to_use, 1); + + if (!gdb_interpreter_set (interp_to_use)) + error ("Could not switch to interpreter \"%s\".", prules[0]); + + for (i = 1; i < nrules; i++) + { + if (!gdb_interpreter_exec (prules[i])) + { + gdb_interpreter_set (old_interp); + gdb_interpreter_set_quiet (interp_to_use, old_quiet); + error ("error in command: \"%s\".", prules[i]); + break; + } + } + + gdb_interpreter_set (old_interp); + gdb_interpreter_set_quiet (interp_to_use, use_quiet); + gdb_interpreter_set_quiet (old_interp, old_quiet); +} + +/* List the possible interpreters which could complete the given text. */ +static char ** +interpreter_completer (char *text, char *word) +{ + int alloced = 0; + int textlen; + int num_matches; + char **matches; + struct gdb_interpreter *interp; + + /* We expect only a very limited number of interpreters, so just + allocate room for all of them. */ + for (interp = interp_list; interp != NULL; interp = interp->next) + ++alloced; + matches = (char **) xmalloc (alloced * sizeof (char *)); + + num_matches = 0; + textlen = strlen (text); + for (interp = interp_list; interp != NULL; interp = interp->next) + { + if (strncmp (interp->name, text, textlen) == 0) + { + matches[num_matches] = + (char *) xmalloc (strlen (word) + strlen (interp->name) + 1); + if (word == text) + strcpy (matches[num_matches], interp->name); + else if (word > text) + { + /* Return some portion of interp->name */ + strcpy (matches[num_matches], interp->name + (word - text)); + } + else + { + /* Return some of text plus interp->name */ + strncpy (matches[num_matches], word, text - word); + matches[num_matches][text - word] = '\0'; + strcat (matches[num_matches], interp->name); + } + ++num_matches; + } + } + + if (num_matches == 0) + { + xfree (matches); + matches = NULL; + } + else if (num_matches < alloced) + { + matches = (char **) xrealloc ((char *) matches, ((num_matches + 1) + * sizeof (char *))); + matches[num_matches] = NULL; + } + + return matches; +} + +/* This just adds the "interpreter-exec" command. */ +void +_initialize_interpreter (void) +{ + struct cmd_list_element *c; + + c = add_cmd ("interpreter-exec", class_support, + interpreter_exec_cmd, + "Execute a command in an interpreter. It takes two arguments:\n\ +The first argument is the name of the interpreter to use.\n\ +The second argument is the command to execute.\n", &cmdlist); + set_cmd_completer (c, interpreter_completer); +} diff --git a/gdb/interps.h b/gdb/interps.h new file mode 100644 index 00000000000..21a0279d2c7 --- /dev/null +++ b/gdb/interps.h @@ -0,0 +1,67 @@ +/* Manages interpreters for gdb. + Copyright 2000,2002 Free Software Foundation, Inc. + Written by Jim Ingham of Apple Computer, Inc. + + This file is part of GDB. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. */ + +#ifndef GDB_INTERPRETER_H +#define GDB_INTERPRETER_H + +typedef int (*interp_init_ftype) (void *data); +typedef int (*interp_resume_ftype) (void *data); +typedef int (*interp_suspend_ftype) (void *data); +typedef int (*interp_prompt_ftype) (void); +typedef int (*interp_exec_ftype) (void *data, char *command); + +struct ui_out; +struct gdb_interpreter; + +struct gdb_interpreter_procs +{ + interp_init_ftype init_proc; + interp_resume_ftype resume_proc; + interp_suspend_ftype suspend_proc; + interp_exec_ftype exec_proc; + interp_prompt_ftype prompt_proc_p; +}; + +extern struct gdb_interpreter + *gdb_interpreter_new (char *name, void *data, struct ui_out *uiout, + struct gdb_interpreter_procs *procs); + +extern int gdb_interpreter_set (struct gdb_interpreter *interp); +extern struct gdb_interpreter *gdb_interpreter_lookup (char *name); +extern struct ui_out *gdb_interpreter_ui_out (struct gdb_interpreter *interp); +extern int gdb_interpreter_current_is_named_p (char *interp_name); +extern int gdb_interpreter_exec (char *command_str); +extern int gdb_interpreter_display_prompt_p (void); +extern int gdb_interpreter_is_quiet_p (struct gdb_interpreter *interp); +extern int gdb_interpreter_add (struct gdb_interpreter *interp); +extern struct gdb_interpreter_procs *gdb_interpreter_get_procs (struct + gdb_interpreter + *interp); +extern void *gdb_interpreter_get_data (struct gdb_interpreter *interp); + +extern void clear_interpreter_hooks (); + +/* well-known interpreters */ +#define GDB_INTERPRETER_CONSOLE "console" +#define GDB_INTERPRETER_MI1 "mi1" +#define GDB_INTERPRETER_MI2 "mi2" +#define GDB_INTERPRETER_MI "mi" +#endif /* GDB_INTERPRETER_H */ diff --git a/gdb/main.c b/gdb/main.c index 7da4ac4a325..fdc5c1bb5f6 100644 --- a/gdb/main.c +++ b/gdb/main.c @@ -53,7 +53,9 @@ int display_space; processes UI events asynchronously. */ int event_loop_p = 1; -/* Has an interpreter been specified and if so, which. */ +/* Has an interpreter been specified and if so, which. + This will be used as a set command variable, so it should + always be malloc'ed - since do_setshow_command will free it. */ char *interpreter_p; /* Whether this is the command line version or not */ @@ -386,7 +388,7 @@ extern int gdbtk_test (char *); } #endif /* GDBTK */ case 'i': - interpreter_p = optarg; + interpreter_p = xstrdup (optarg); break; case 'd': dirarg[ndir++] = optarg; diff --git a/gdb/mi/ChangeLog b/gdb/mi/ChangeLog index e25430ec873..f89b49422f3 100644 --- a/gdb/mi/ChangeLog +++ b/gdb/mi/ChangeLog @@ -1,3 +1,216 @@ +2002-11-05 Elena Zannoni + + * mi-cmd-stack.c (mi_cmd_stack_select_frame): Remove stray statement. + Remove include of gdb-events.h. + +2002-11-04 Elena Zannoni + + * mi.h: Clean up interface, removing unnecessarily exported + functions and data structures. + * mi-events.c (mi_event_handlers): Move here... + * mi-interps.c: .. from here. + Include gdb_string.h. + +2002-11-04 Elena Zannoni + + * mi-interp.c (mi_interpreter_resume): Ditto. + (mi_cmd_interpreter_exec): Use gdb_interpreter_lookup. + (_initialize_mi_interp): Use gdb_interpreter_new, + gdb_interpreter_add. + * mi-cmd-break.c (mi_cmd_break_insert): Use + gdb_interpreter_current_is_named_p. + (mi_cmd_break_watch): Ditto. + * mi-events.c (mi_interp_stack_changed_hook): Ditto. + (event_notify): Ditto. + + + * mi-main.c (captured_mi_execute_command): Use + gdb_interpreter_current_is_named_p. + (mi_load_progress): Ditto. + +2002-11-04 Elena Zannoni + + * mi-interp.c (_initialize_mi_interp): Use mi_interpreter_prompt_p + instead of mi_interpreter_prompt. + (mi_interpreter_prompt_p): Rename from mi_interpreter_prompt and + rewrite. + +2002-11-04 Elena Zannoni + + * mi-interp.c mi_interpreter_delete): Remove. + (_initialize_mi_interp): Remove mi_interpreter_delete. + +2002-11-04 Elena Zannoni + + * mi-interp.c (mi_interpreter_do_one_event): Remove. + +2002-11-04 Elena Zannoni + + * mi-cmd-break.c (mi_cmd_break_insert): Initialize old_hooks. + (mi_cmd_break_insert, mi_cmd_break_watch, mi_cmd_break_insert): + Increment MI version number. + +2002-11-04 Elena Zannoni + + * mi-interp.c: Increment mi version numbers: 0->1, 1->2, + and 2->3. Remove MI0 references. + * mi-events.c: Ditto. + * mi-main.c: Ditto. Remove erroneously merged code. + * mi.h: Ditto. + +2002-08-28 Keith Seitz + + * mi-interp.c (_initialize_mi_interp): Add exec_proc. + (mi_interpreter_exec): New function. MI's exec_proc. + +2002-08-28 Keith Seitz + + * gdbmi.texinfo: Document the interpreter-exec command. + +2002-08-21 Keith Seitz + + * mi-events.c (mi_target_changed): Renamed from mi_register_update. + * mi.h (mi_target_changed): Ditto. + * mi-interp.c (mi_event_handlers): Ditto. + +2002-08-19 Keith Seitz + + * mi-cmd-stack.c (mi_cmd_stack_select_frame): Revert 2002-07-25 + change. stack.c now handles it properly. + +2002-08-13 Keith Seitz + + * mi-interp.c (mi_cmd_interpreter_set): Remove. We're not going + to allow this. + * mi-cmds.c: Remove "interpreter-set" command. + * mi-cmds.h (mi_cmd_interpreter_set): Remove. + +2002-08-09 Keith Seitz + + * gdbmi.texinfo: Document selected-frame-changed, register-update, + and context-changed events. + +2002-08-09 Keith Seitz + + * gdbmi.texinfo (-data-list-register-names): Document "-numbers" + option. + * mi-main.c (mi_cmd_data_list_register_names): Add "-numbers" + option. + +2002-08-09 Keith Seitz + + * mi-interp.c (mi_event_handlers): Add context_changed event + handler. + (mi_command_loop): Remove big block of code repeated in + mi_interpreter_resume. I don't think this is needed. + (mi_insert_notify_hooks): Remove context_hook. + (mi_remove_notify_hooks): Likewise. + * mi-events.c (mi_context_changed): New function. + * mi.h (mi_context_changed): Add declaration. + +2002-07-25 Keith Seitz + + * mi-interp.c (mi_event_handlers): Add selected_frame_level_changed + handler. + (mi_insert_notify_hooks): Remove breakpoint hooks and frame + changed hook. + (mi_remove_notify_hooks): Likewise. + * mi-events.c (mi_selected_frame_level_changed): New function. + (mi_interp_frame_changed_hook): Remove. + (mi_interp_create_breakpoint_hook): Remove. + (mi_interp_modify_breakpoint_hook): Remove. + (mi_interp_delete_breakpoint_hook): Remove. + * mi.h (mi_selected_frame_level_changed): Add declaration. + (mi_interp_create_breakpoint_hook): Remove declaration. + (mi_interp_modify_breakpoint_hook): Remove declaration. + (mi_interp_delete_breakpoint_hook): Remove declaration. + * mi-cmd-stack.c (mi_cmd_stack_select_frame): If the stack level changes, + issue a selected_frame_level_changed event. + +2002-07-22 Keith Seitz + + * mi-events.c (mi_register_update): New function. + * mi-interp.c (mi_event_handlers): Add mi_register_update + event handler. + * mi.h (mi_register_update): Add declaration. + +2002-06-24 Keith Seitz + + * mi-cmds.h (mi_execute_command): Add "extern". + (mi_error_last_message): New function. + * mi-main.c (mi_error_last_message): New function. + * mi-interp.c (mi_event_handlers): New static global. + (mi_interpreter_init): Don't install mi event handlers here. + (mi_interpreter_resume): Install mi event handlers here. + (mi_interpreter_exec): Don't actually switch interpreters. + Update error messages. + exec_proc will return <0 if an error occurs. + +2002-06-19 Keith Seitz + + * mi-cmd-break.c (breakpoint_notify): Only query the breakpoint + for user breakpoints. + (mi_cmd_break_insert): Only reset event handlers for MI0 and MI1 + interpreters. + (mi_cmd_break_watch): Reset uiout output to clear watchpoint + query. This is only used for MI0 and MI1. + + * mi-console.h (mi_console_file_new): Add "quote" parameter. + * mi_console.c (struct mi_console_file): Add "quote". + (mi_console_file_new): Add "quote" parameter. + (mi_console_raw_packet): Use the quote character specified in + mi_console_file_new, instead of assuming it is '"'. + + * mi-interp.c (mi_event_channel): New channel for event notifications. + (mi_interpreter_init): Make static. + Set event handlers. + (mi_interpreter_resume): Make static. + Deal with MI version bump. + (mi_interpreter_suspend): Make static. + (mi_interpreter_delete): Ditto. + (mi_do_one_event): Ditto. + (mi_cmd_exec_continuation): Ditto. + (mi_interp_query_hook): Ditto. + (mi_interp_read_one_line_hook): Ditto. + (_initialize_mi_interp): Create explicit mi1 interp. + + * mi-events.c (notify_event): New helper function. + (mi_create_breakpoint, mi_modify_breakpoint, mi_delete_breakpoint, + mi_create_tracepoint, mi_modify_tracepoint, mi_delete_tracepoint, + mi_architecture_changed): New functions. + + * mi.h: Add declarations for mi_create_breakpoint, mi_modify_breakpoint, + mi_delete_breakpoint, mi_create_tracepoint, mi_modify_tracepoint, + mi_delete_tracepoint, mi_architecture_changed, mi_stdout, mi_stderr, + mi_stdtarg, mi_stdlog, and mi_eventchannel. + + * mi-main.c (captured_mi_execute_command): Deal with mi version + bump. + (mi_load_progress): Ditto. + + * gdbmi.texinfo: Expand notify-async-output to include GDB events. + Update all examples to show breakpoint events and + remove redundant breakpoint info on "-break-insert" and "-break-watch". + The event now supplies everything that is needed. + +2002-05-28 Keith Seitz + + * mi-interp.c: New file. Almost entirely from Apple's + sources. Collected and moved here. + * mi-events.c: Ditto. + * mi.h: New file. + * mi-main.c (captured_execute_command): Use catch_exception + instead of catch_errors. + (mi_execute_command_wrapper): Remove. Using catch_errors now. + (mi_input): Make global. + (mi_load_progress): Ditto. + Use interpreter functions instead of interpreter_p. + (mi_command_loop): Moved to mi-interp.c + (mi0_command_loop): Ditto. + (mi1_command_loop): Ditto. + (mi_init_ui): Remove. + (_initialize_mi_main): Remove. No longer needed. + 2003-02-02 Andrew Cagney From 2002-11-10 Jason Molenda (jason-cl@molenda.com): @@ -138,7 +351,6 @@ 2002-07-29 Andrew Cagney - * mi-cmd-var.c: Include "gdb_string.h". * mi-cmd-disas.c: Ditto. diff --git a/gdb/mi/gdbmi.texinfo b/gdb/mi/gdbmi.texinfo index 8326bcab00b..4080c39d776 100644 --- a/gdb/mi/gdbmi.texinfo +++ b/gdb/mi/gdbmi.texinfo @@ -313,8 +313,8 @@ prefixed by @samp{+}. @item @cindex notify output in @sc{gdb/mi} -@var{notify-async-output} contains supplementary information that the -client should handle (e.g., a new breakpoint information). All notify +@var{notify-async-output} contains supplementary information (events) that the +client should handle (e.g., a new breakpoint was inserted). All notify output is prefixed by @samp{=}. @item @@ -388,7 +388,8 @@ Here's an example of a simple CLI command being passed through @example -> -symbol-file xyz.exe -<- *breakpoint,nr="3",address="0x123",source="a.c:123" +<- =breakpoint-create,number="3" +<- ^done <- (@value{GDBP}) @end example @@ -494,10 +495,53 @@ additional changes that have occurred. Those changes can either be a consequence of @sc{gdb/mi} (e.g., a breakpoint modified) or a result of target activity (e.g., target stopped). -The following is a preliminary list of possible out-of-band records. +The following is a preliminary list of out-of-band records. @table @code -@item "*" "stop" +@item stop +The inferior stopped. +@c Need an example! + +@item breakpoint-create +@itemx breakpoint-modify +@itemx breakpoint-delete +@itemx tracepoint-create +@itemx tracepoint-modify +@itemx tracepoint-delete +A breakpoint or tracepoint was created, modified, or deleted. In all cases, +the event will also report the @code{number} of the affected breakpoint/tracepoint: +@smallexample +=breakpoint-create,number="1" +@end smallexample + +@item architecture-changed +This event indicates that @value{GDBN} has changed architectures, and that +the user interface may need to update certain views that are architecture-dependent, +such as registers. +@smallexample +=architecture-changed +@end smallexample + +@item register-update +A register has been changed in the inferior. The event will include the +@code{number} of the register that the UI needs to update. +@smallexample +=register-changed,number="3" +@end smallexample + +@item selected-frame-level-changed +This event is sent whenever the user changes @value{GDBN}'s selected frame. +The event will include the newly selected frame level. +@smallexample +=selected-frame-level-changed,level="3" +@end smallexample + +@item context-changed +The user has changed @value{GDBN}'s current thread. The event will include +the newly selected thread number. +@smallexample +=context-changed,thread="2" +@end smallexample @end table @@ -576,10 +620,11 @@ The corresponding @value{GDBN} command is @samp{ignore}. @smallexample (@value{GDBP}) -break-insert main -^done,bkpt=@{number="1",addr="0x000100d0",file="hello.c",line="5"@} +=breakpoint-create,number="1" +^done (@value{GDBP}) -break-after 1 3 -~ +=breakpoint-modify,number="1" ^done (@value{GDBP}) -break-list @@ -628,6 +673,7 @@ The corresponding @value{GDBN} command is @samp{condition}. @smallexample (@value{GDBP}) -break-condition 1 1 +=breakpoint-modify,number="1" ^done (@value{GDBP}) -break-list @@ -665,6 +711,7 @@ The corresponding @value{GDBN} command is @samp{delete}. @example (@value{GDBP}) -break-delete 1 +=breakpoint-delete,number="1" ^done (@value{GDBP}) -break-list @@ -700,6 +747,7 @@ The corresponding @value{GDBN} command is @samp{disable}. @smallexample (@value{GDBP}) -break-disable 2 +=breakpoint-modify,number="2" ^done (@value{GDBP}) -break-list @@ -735,6 +783,7 @@ The corresponding @value{GDBN} command is @samp{enable}. @smallexample (@value{GDBP}) -break-enable 2 +=breakpoint-modify,number="2" ^done (@value{GDBP}) -break-list @@ -810,24 +859,6 @@ given regular expression. Other flags are not applicable to regular expresson. @end table -@subsubheading Result - -The result is in the form: - -@example - ^done,bkptno="@var{number}",func="@var{funcname}", - file="@var{filename}",line="@var{lineno}" -@end example - -@noindent -where @var{number} is the @value{GDBN} number for this breakpoint, @var{funcname} -is the name of the function where the breakpoint was inserted, -@var{filename} is the name of the source file which contains this -function, and @var{lineno} is the source line number within that file. - -Note: this format is open to change. -@c An out-of-band breakpoint instead of part of the result? - @subsubheading @value{GDBN} Command The corresponding @value{GDBN} commands are @samp{break}, @samp{tbreak}, @@ -838,10 +869,12 @@ The corresponding @value{GDBN} commands are @samp{break}, @samp{tbreak}, @smallexample (@value{GDBP}) -break-insert main -^done,bkpt=@{number="1",addr="0x0001072c",file="recursive2.c",line="4"@} +=breakpoint-create,number="1" +^done (@value{GDBP}) -break-insert -t foo -^done,bkpt=@{number="2",addr="0x00010774",file="recursive2.c",line="11"@} +=breakpoint-create,number="2" +^done (@value{GDBP}) -break-list ^done,BreakpointTable=@{nr_rows="2",nr_cols="6", @@ -858,7 +891,8 @@ addr="0x00010774",func="foo",file="recursive2.c",line="11",times="0"@}]@} (@value{GDBP}) -break-insert -r foo.* ~int foo(int, int); -^done,bkpt=@{number="3",addr="0x00010774",file="recursive2.c",line="11"@} +=breakpoint-create,number="1" +^done (@value{GDBP}) @end smallexample @@ -967,7 +1001,8 @@ Setting a watchpoint on a variable in the @code{main} function: @smallexample (@value{GDBP}) -break-watch x -^done,wpt=@{number="2",exp="x"@} +=breakpoint-create,number="2" +^done (@value{GDBP}) -exec-continue ^running @@ -984,7 +1019,8 @@ for the watchpoint going out of scope. @smallexample (@value{GDBP}) -break-watch C -^done,wpt=@{number="5",exp="C"@} +=breakpoint-create,number="5" +^done (@value{GDBP}) -exec-continue ^running @@ -1009,7 +1045,8 @@ deleted. @smallexample (@value{GDBP}) -break-watch C -^done,wpt=@{number="2",exp="C"@} +=breakpoint-create,number="2" +^done (@value{GDBP}) -break-list ^done,BreakpointTable=@{nr_rows="2",nr_cols="6", @@ -1302,7 +1339,7 @@ args=[],file="try.c",line="5"@} @subsubheading Synopsis @example - -data-list-register-names [ ( @var{regno} )+ ] + -data-list-register-names [ [ -numbers ] ( @var{regno} )+ ] @end example Show a list of register names for the current target. If no arguments @@ -1312,6 +1349,9 @@ names of the registers corresponding to the arguments. To ensure consistency between a register name and its number, the output list may include empty register names. +When the "-numbers" option is used, it will return the list of register +numbers in addition to the register names. + @subsubheading @value{GDBN} Command @value{GDBN} does not have a command which corresponds to @@ -2543,6 +2583,34 @@ information when you start an interactive session. (@value{GDBP}) @end smallexample +@subheading The @code{-interpreter-exec} Command +@findex -interpreter-exec + +@subheading Synopsis + +@smallexample +-interpreter-exec @var{interpreter} @var{command} +@end smallexample + +Execute the specified @var{command} in the given @var{interpreter}. + +@subheading @value{GDBN} Command + +The corresponding @value{GDBN} command is @samp{interpreter-exec}. + +@subheading Example + +@smallexample +(@value{GDBP}) +-interpreter-exec console "break main" +&"During symbol reading, couldn't parse type; debugger out of date?.\n" +&"During symbol reading, bad structure-type format.\n" +~"Breakpoint 1 at 0x8074fc6: file ../../src/gdb/main.c, line 743.\n" +=breakpoint-create,number="1" +^done +(@value{GDBP}) +@end smallexample + @ignore @c %%%%%%%%%%%%%%%%%%%%%%%%%%%% SECTION %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% @node GDB/MI Kod Commands diff --git a/gdb/mi/mi-cmd-break.c b/gdb/mi/mi-cmd-break.c index 5d15aa98b8a..5f9d6aca756 100644 --- a/gdb/mi/mi-cmd-break.c +++ b/gdb/mi/mi-cmd-break.c @@ -28,6 +28,7 @@ #include "mi-getopt.h" #include "gdb-events.h" #include "gdb.h" +#include "interps.h" enum { @@ -39,7 +40,8 @@ enum static void breakpoint_notify (int b) { - gdb_breakpoint_query (uiout, b); + if (b > 0) + gdb_breakpoint_query (uiout, b); } @@ -77,7 +79,7 @@ mi_cmd_break_insert (char *command, char **argv, int argc) int ignore_count = 0; char *condition = NULL; enum gdb_rc rc; - struct gdb_events *old_hooks; + struct gdb_events *old_hooks = NULL; enum opt { HARDWARE_OPT, TEMP_OPT /*, REGEXP_OPT */ , CONDITION_OPT, @@ -133,8 +135,17 @@ mi_cmd_break_insert (char *command, char **argv, int argc) error ("mi_cmd_break_insert: Garbage following "); address = argv[optind]; + /* Save the current event handlers so that we can insert our own. This + allows us to capture the breakpoint information as the breakpoint + is created. Unfortunately, it also overrides any existing event + handlers, so we won't get any event notifications sent out to the + client. MI3+ does NOT send breakpoint information with the -break-insert + command for this reason. */ + if (gdb_interpreter_current_is_named_p (GDB_INTERPRETER_MI2) + || gdb_interpreter_current_is_named_p (GDB_INTERPRETER_MI1)) + old_hooks = set_gdb_event_hooks (&breakpoint_hooks); + /* Now we have what we need, let's insert the breakpoint! */ - old_hooks = set_gdb_event_hooks (&breakpoint_hooks); switch (type) { case REG_BP: @@ -160,7 +171,10 @@ mi_cmd_break_insert (char *command, char **argv, int argc) internal_error (__FILE__, __LINE__, "mi_cmd_break_insert: Bad switch."); } - set_gdb_event_hooks (old_hooks); + + if (gdb_interpreter_current_is_named_p (GDB_INTERPRETER_MI2) + || gdb_interpreter_current_is_named_p (GDB_INTERPRETER_MI1)) + set_gdb_event_hooks (old_hooks); if (rc == GDB_RC_FAIL) return MI_CMD_CAUGHT_ERROR; @@ -236,5 +250,15 @@ mi_cmd_break_watch (char *command, char **argv, int argc) default: error ("mi_cmd_break_watch: Unknown watchpoint type."); } + + /* Ugh. This is a hack. mention and print_one_breakpoint in + breakpoint.c are so overloaded, that watchpoints and breakpoints + cannot use the same printing mechanisms. So for MI3+, we simply + rewind MI's uiout so that we can prevent GDB from printing + any information about the watchpoint we just inserted. */ + if (!gdb_interpreter_current_is_named_p (GDB_INTERPRETER_MI2) + && !gdb_interpreter_current_is_named_p (GDB_INTERPRETER_MI1)) + mi_out_rewind (uiout); + return MI_CMD_DONE; } diff --git a/gdb/mi/mi-cmds.c b/gdb/mi/mi-cmds.c index 699937d0ff2..1447d57ffb2 100644 --- a/gdb/mi/mi-cmds.c +++ b/gdb/mi/mi-cmds.c @@ -88,6 +88,7 @@ struct mi_cmd mi_cmds[] = {"gdb-show", "show %s", 0}, {"gdb-source", 0, 0}, {"gdb-version", "show version", 0}, + {"interpreter-exec", 0, 0, mi_cmd_interpreter_exec}, {"kod-info", 0, 0}, {"kod-list", 0, 0}, {"kod-list-object-types", 0, 0}, diff --git a/gdb/mi/mi-cmds.h b/gdb/mi/mi-cmds.h index f4fe64d279e..b8ff05709d3 100644 --- a/gdb/mi/mi-cmds.h +++ b/gdb/mi/mi-cmds.h @@ -27,7 +27,7 @@ enum mi_cmd_result { /* Report the command as ``done''. Display both the ``NNN^done'' - message and the completion prompt. */ + message and the completion prompt. */ MI_CMD_DONE = 0, /* The command is still running in the forground. Main loop should display the completion prompt. */ @@ -79,6 +79,7 @@ extern mi_cmd_args_ftype mi_cmd_exec_step_instruction; extern mi_cmd_args_ftype mi_cmd_exec_until; extern mi_cmd_args_ftype mi_cmd_exec_interrupt; extern mi_cmd_argv_ftype mi_cmd_gdb_exit; +extern mi_cmd_argv_ftype mi_cmd_interpreter_exec; extern mi_cmd_argv_ftype mi_cmd_stack_info_depth; extern mi_cmd_argv_ftype mi_cmd_stack_list_args; extern mi_cmd_argv_ftype mi_cmd_stack_list_frames; @@ -126,4 +127,7 @@ extern int mi_debug_p; /* Raw console output - FIXME: should this be a parameter? */ extern struct ui_file *raw_stdout; +extern char *mi_error_message; +extern void mi_error_last_message (void); +extern void mi_execute_command (char *cmd, int from_tty); #endif diff --git a/gdb/mi/mi-console.c b/gdb/mi/mi-console.c index c1b6e9f7b33..aca008640fd 100644 --- a/gdb/mi/mi-console.c +++ b/gdb/mi/mi-console.c @@ -37,13 +37,14 @@ struct mi_console_file struct ui_file *raw; struct ui_file *buffer; const char *prefix; + char quote; }; int mi_console_file_magic; struct ui_file * mi_console_file_new (struct ui_file *raw, - const char *prefix) + const char *prefix, char quote) { struct ui_file *ui_file = ui_file_new (); struct mi_console_file *mi_console = XMALLOC (struct mi_console_file); @@ -51,6 +52,7 @@ mi_console_file_new (struct ui_file *raw, mi_console->raw = raw; mi_console->buffer = mem_fileopen (); mi_console->prefix = prefix; + mi_console->quote = quote; set_ui_file_fputs (ui_file, mi_console_file_fputs); set_ui_file_flush (ui_file, mi_console_file_flush); set_ui_file_data (ui_file, mi_console, mi_console_file_delete); @@ -96,9 +98,17 @@ mi_console_raw_packet (void *data, if (length_buf > 0) { fputs_unfiltered (mi_console->prefix, mi_console->raw); - fputs_unfiltered ("\"", mi_console->raw); - fputstrn_unfiltered (buf, length_buf, '"', mi_console->raw); - fputs_unfiltered ("\"\n", mi_console->raw); + if (mi_console->quote) + { + fputs_unfiltered ("\"", mi_console->raw); + fputstrn_unfiltered (buf, length_buf, mi_console->quote, mi_console->raw); + fputs_unfiltered ("\"\n", mi_console->raw); + } + else + { + fputstrn_unfiltered (buf, length_buf, 0, mi_console->raw); + fputs_unfiltered ("\n", mi_console->raw); + } gdb_flush (mi_console->raw); } } diff --git a/gdb/mi/mi-console.h b/gdb/mi/mi-console.h index 6bd03cbd924..99ecb73e154 100644 --- a/gdb/mi/mi-console.h +++ b/gdb/mi/mi-console.h @@ -22,6 +22,7 @@ #ifndef MI_CONSOLE_H #define MI_CONSOLE_H -extern struct ui_file *mi_console_file_new (struct ui_file *raw, const char *prefix); +extern struct ui_file *mi_console_file_new (struct ui_file *raw, const char *prefix, + char quote); #endif diff --git a/gdb/mi/mi-events.c b/gdb/mi/mi-events.c new file mode 100644 index 00000000000..e579f347b55 --- /dev/null +++ b/gdb/mi/mi-events.c @@ -0,0 +1,136 @@ +/* MI Event Handlers + Copyright 2002 Free Software Foundation, Inc. + + This file is part of GDB. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. */ + +#include "defs.h" +#include "ui-out.h" +#include "interps.h" +#include "gdb.h" +#include "breakpoint.h" + +#include "mi.h" + +void +mi_interp_stack_changed_hook (void) +{ + struct ui_out *saved_ui_out = uiout; + struct mi_out *tmp_mi_out; + struct cleanup *cleanup; + + if (gdb_interpreter_current_is_named_p (GDB_INTERPRETER_MI1)) + uiout = gdb_interpreter_ui_out (mi1_interp); + else + uiout = gdb_interpreter_ui_out (mi_interp); + + cleanup = make_cleanup_ui_out_list_begin_end (uiout, "MI_HOOK_RESULT"); + ui_out_field_string (uiout, "HOOK_TYPE", "stack_changed"); + do_cleanups (cleanup); + uiout = saved_ui_out; +} + +static void +event_notify (const char *string, ...) +{ + va_list args; + + if (!gdb_interpreter_current_is_named_p (GDB_INTERPRETER_MI1) + && !gdb_interpreter_current_is_named_p (GDB_INTERPRETER_MI2)) + { + va_start (args, string); + vfprintf_unfiltered (mi_event_channel, string, args); + va_end (args); + gdb_flush (mi_event_channel); + } +} + +/* breakpoint-create,number=bpnum */ +void +mi_create_breakpoint (int bpnum) +{ + event_notify ("breakpoint-create,number=\"%d\"", bpnum); +} + +void +mi_modify_breakpoint (int bpnum) +{ + event_notify ("breakpoint-modify,number=\"%d\"", bpnum); +} + +void +mi_delete_breakpoint (int bpnum) +{ + event_notify ("breakpoint-delete,number=\"%d\"", bpnum); +} + +void +mi_create_tracepoint (int tpnum) +{ + event_notify ("tracepoint-create,number=\"%d\"", tpnum); +} + +void +mi_modify_tracepoint (int tpnum) +{ + event_notify ("tracepoint-modify,number=\"%d\"", tpnum); +} + +void +mi_delete_tracepoint (int tpnum) +{ + event_notify ("tracepoint-delete,number=\"%d\"", tpnum); +} + +void +mi_architecture_changed (void) +{ + event_notify ("architecture-changed"); +} + +void +mi_target_changed (void) +{ + event_notify ("target-changed"); +} + +void +mi_selected_frame_level_changed (int level) +{ + event_notify ("selected-frame-level-changed,level=\"%d\"", level); +} + +void +mi_context_changed (int thread_id) +{ + event_notify ("context-changed,thread=\"%d\"", thread_id); +} + +struct gdb_events mi_event_handlers = + { + mi_create_breakpoint, + mi_delete_breakpoint, + mi_modify_breakpoint, + mi_create_tracepoint, + mi_delete_tracepoint, + mi_modify_tracepoint, + mi_architecture_changed, + mi_target_changed, + mi_selected_frame_level_changed, + mi_context_changed + }; + diff --git a/gdb/mi/mi-interp.c b/gdb/mi/mi-interp.c new file mode 100644 index 00000000000..456e42d21ee --- /dev/null +++ b/gdb/mi/mi-interp.c @@ -0,0 +1,450 @@ +/* MI Interpreter Definitions and Commands + Copyright 2002 Free Software Foundation, Inc. + + This file is part of GDB. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. */ + +#include "defs.h" +#include "gdb_string.h" +#include "interps.h" +#include "event-top.h" +#include "event-loop.h" +#include "inferior.h" +#include "ui-out.h" +#include "top.h" + +#include "mi.h" +#include "mi-cmds.h" +#include "mi-out.h" +#include "mi-console.h" + +/* MI's output channels */ +struct ui_file *mi_stdout; +struct ui_file *mi_stderr; +struct ui_file *mi_stdlog; +struct ui_file *mi_stdtarg; +struct ui_file *mi_event_channel; + +/* This is the interpreter for the mi... */ +struct gdb_interpreter *mi2_interp; +struct gdb_interpreter *mi1_interp; +struct gdb_interpreter *mi_interp; + +/* These are the interpreter setup, etc. functions for the MI interpreter */ +static int mi_interpreter_init (void *data); +static int mi_interpreter_resume (void *data); +static int mi_interpreter_suspend (void *data); +static int mi_interpreter_exec (void *data, char *command); +static int mi_interpreter_prompt_p (void); + +static void mi_execute_command_wrapper (char *cmd); +static void mi_command_loop (int mi_version); +static char *mi_input (char *); + +/* These are hooks that we put in place while doing interpreter_exec + so we can report interesting things that happened "behind the mi's + back" in this command */ +static int mi_interp_query_hook (const char *ctlstr, va_list ap); +static char *mi_interp_read_one_line_hook (char *prompt, int repeat, + char *anno); + +static void mi2_command_loop (void); +static void mi1_command_loop (void); + +static void mi_insert_notify_hooks (void); +static void mi_remove_notify_hooks (void); + +static int +mi_interpreter_init (void *data) +{ + static struct gdb_events handlers; + + /* Why is this a part of the mi architecture? */ + + mi_setup_architecture_data (); + + /* HACK: We need to force stdout/stderr to point at the console. This avoids + any potential side effects caused by legacy code that is still + using the TUI / fputs_unfiltered_hook. So we set up output channels for + this now, and swap them in when we are run. */ + + raw_stdout = stdio_fileopen (stdout); + + /* Create MI channels */ + mi_stdout = mi_console_file_new (raw_stdout, "~", '"'); + mi_stderr = mi_console_file_new (raw_stdout, "&", '"'); + mi_stdlog = mi_stderr; + mi_stdtarg = mi_console_file_new (raw_stdout, "@", '"'); + mi_event_channel = mi_console_file_new (raw_stdout, "=", 0); + + return 1; +} + +static int +mi_interpreter_resume (void *data) +{ + /* As per hack note in mi_interpreter_init, swap in the output channels... */ + + gdb_setup_readline (); + mi_register_gdbarch_swap (); + + if (event_loop_p) + { + /* These overwrite some of the initialization done in + _intialize_event_loop. */ + call_readline = gdb_readline2; + input_handler = mi_execute_command_wrapper; + add_file_handler (input_fd, stdin_event_handler, 0); + async_command_editing_p = 0; + /* FIXME: This is a total hack for now. PB's use of the MI implicitly + relies on a bug in the async support which allows asynchronous + commands to leak through the commmand loop. The bug involves + (but is not limited to) the fact that sync_execution was + erroneously initialized to 0. Duplicate by initializing it + thus here... */ + sync_execution = 0; + } + + gdb_stdout = mi_stdout; + /* Route error and log output through the MI */ + gdb_stderr = mi_stderr; + gdb_stdlog = mi_stdlog; + /* Route target output through the MI. */ + gdb_stdtarg = mi_stdtarg; + + /* Replace all the hooks that we know about. There really needs to + be a better way of doing this... */ + clear_interpreter_hooks (); + set_gdb_event_hooks (&mi_event_handlers); + + show_load_progress = mi_load_progress; + + /* If we're _the_ interpreter, take control. */ + if (gdb_interpreter_current_is_named_p (GDB_INTERPRETER_MI2)) + command_loop_hook = mi2_command_loop; + else if (gdb_interpreter_current_is_named_p (GDB_INTERPRETER_MI1)) + command_loop_hook = mi1_command_loop; + else if (gdb_interpreter_current_is_named_p (GDB_INTERPRETER_MI)) + command_loop_hook = mi2_command_loop; + else + return 0; + + return 1; +} + +static int +mi_interpreter_suspend (void *data) +{ + gdb_disable_readline (); + return 1; +} + +static int +mi_interpreter_exec (void *data, char *command) +{ + mi_execute_command_wrapper (command); + return 1; +} + +/* Never display the default gdb prompt in mi case. */ +static int +mi_interpreter_prompt_p (void) +{ + return 0; +} + +static void +mi_interpreter_exec_continuation (struct continuation_arg *arg) +{ + bpstat_do_actions (&stop_bpstat); + if (!target_executing) + { + fputs_unfiltered ("*stopped", raw_stdout); + mi_out_put (uiout, raw_stdout); + fputs_unfiltered ("\n", raw_stdout); + fputs_unfiltered ("(gdb) \n", raw_stdout); + gdb_flush (raw_stdout); + do_exec_cleanups (ALL_CLEANUPS); + } + else if (target_can_async_p ()) + { + add_continuation (mi_interpreter_exec_continuation, NULL); + } +} + +enum mi_cmd_result +mi_cmd_interpreter_exec (char *command, char **argv, int argc) +{ + struct gdb_interpreter *interp_to_use; + enum mi_cmd_result result = MI_CMD_DONE; + int i; + struct gdb_interpreter_procs *procs; + + if (argc < 2) + { + xasprintf (&mi_error_message, + "mi_cmd_interpreter_exec: Usage: -interpreter-exec interp command"); + return MI_CMD_ERROR; + } + + interp_to_use = gdb_interpreter_lookup (argv[0]); + if (interp_to_use == NULL) + { + xasprintf (&mi_error_message, + "mi_cmd_interpreter_exec: could not find interpreter \"%s\"", + argv[0]); + return MI_CMD_ERROR; + } + + procs = gdb_interpreter_get_procs (interp_to_use); + if (!procs->exec_proc) + { + xasprintf (&mi_error_message, + "mi_cmd_interpreter_exec: interpreter \"%s\" does not support command execution", + argv[0]); + return MI_CMD_ERROR; + } + + /* Insert the MI out hooks, making sure to also call the interpreter's hooks + if it has any. */ + /* KRS: We shouldn't need this... Events should be installed and they should + just ALWAYS fire something out down the MI channel... */ + mi_insert_notify_hooks (); + + /* Now run the code... */ + + for (i = 1; i < argc; i++) + { + char *buff = NULL; + /* Do this in a cleaner way... We want to force execution to be + asynchronous for commands that run the target. */ + if (target_can_async_p () && (strcmp (argv[0], "console") == 0)) + { + int len = strlen (argv[i]); + buff = xmalloc (len + 2); + memcpy (buff, argv[i], len); + buff[len] = '&'; + buff[len + 1] = '\0'; + } + + /* We had to set sync_execution = 0 for the mi (well really for Project + Builder's use of the mi - particularly so interrupting would work. + But for console commands to work, we need to initialize it to 1 - + since that is what the cli expects - before running the command, + and then set it back to 0 when we are done. */ + sync_execution = 1; + if (procs->exec_proc (gdb_interpreter_get_data (interp_to_use), argv[i]) < 0) + { + mi_error_last_message (); + result = MI_CMD_ERROR; + break; + } + xfree (buff); + do_exec_error_cleanups (ALL_CLEANUPS); + sync_execution = 0; + } + + mi_remove_notify_hooks (); + + /* Okay, now let's see if the command set the inferior going... + Tricky point - have to do this AFTER resetting the interpreter, since + changing the interpreter will clear out all the continuations for + that interpreter... */ + + if (target_can_async_p () && target_executing) + { + fputs_unfiltered ("^running\n", raw_stdout); + add_continuation (mi_interpreter_exec_continuation, NULL); + } + + return result; +} + +/* + * mi_insert_notify_hooks - This inserts a number of hooks that are meant to produce + * async-notify ("=") MI messages while running commands in another interpreter + * using mi_interpreter_exec. The canonical use for this is to allow access to + * the gdb CLI interpreter from within the MI, while still producing MI style output + * when actions in the CLI command change gdb's state. +*/ + +static void +mi_insert_notify_hooks (void) +{ + query_hook = mi_interp_query_hook; +} + +static void +mi_remove_notify_hooks () +{ + query_hook = NULL; +} + +static int +mi_interp_query_hook (const char *ctlstr, va_list ap) +{ + return 1; +} + +static char * +mi_interp_read_one_line_hook (char *prompt, int repeat, char *anno) +{ + static char buff[256]; + printf_unfiltered ("=read-one-line,prompt=\"%s\"\n", prompt); + gdb_flush (gdb_stdout); + (void) fgets (buff, sizeof (buff), stdin); + buff[(strlen (buff) - 1)] = 0; + return buff; +} + +static void +output_control_change_notification (char *notification) +{ + printf_unfiltered ("^"); + printf_unfiltered ("%s\n", notification); + gdb_flush (gdb_stdout); +} + +static void +mi_execute_command_wrapper (char *cmd) +{ + mi_execute_command (cmd, stdin == instream); +} + +static void +mi1_command_loop (void) +{ + mi_command_loop (1); +} + +static void +mi2_command_loop (void) +{ + mi_command_loop (2); +} + +static void +mi_command_loop (int mi_version) +{ +#if 0 + /* HACK: Force stdout/stderr to point at the console. This avoids + any potential side effects caused by legacy code that is still + using the TUI / fputs_unfiltered_hook */ + raw_stdout = stdio_fileopen (stdout); + /* Route normal output through the MIx */ + gdb_stdout = mi_console_file_new (raw_stdout, "~", '"'); + /* Route error and log output through the MI */ + gdb_stderr = mi_console_file_new (raw_stdout, "&", '"'); + gdb_stdlog = gdb_stderr; + /* Route target output through the MI. */ + gdb_stdtarg = mi_console_file_new (raw_stdout, "@", '"'); + /* HACK: Poke the ui_out table directly. Should we be creating a + mi_out object wired up to the above gdb_stdout / gdb_stderr? */ + uiout = mi_out_new (mi_version); + /* HACK: Override any other interpreter hooks. We need to create a + real event table and pass in that. */ + init_ui_hook = 0; + /* command_loop_hook = 0; */ + print_frame_info_listing_hook = 0; + query_hook = 0; + warning_hook = 0; + create_breakpoint_hook = 0; + delete_breakpoint_hook = 0; + modify_breakpoint_hook = 0; + interactive_hook = 0; + registers_changed_hook = 0; + readline_begin_hook = 0; + readline_hook = 0; + readline_end_hook = 0; + register_changed_hook = 0; + memory_changed_hook = 0; + context_hook = 0; + target_wait_hook = 0; + call_command_hook = 0; + error_hook = 0; + error_begin_hook = 0; + show_load_progress = mi_load_progress; +#endif + /* Turn off 8 bit strings in quoted output. Any character with the + high bit set is printed using C's octal format. */ + sevenbit_strings = 1; + /* Tell the world that we're alive */ + fputs_unfiltered ("(gdb) \n", raw_stdout); + gdb_flush (raw_stdout); + if (!event_loop_p) + simplified_command_loop (mi_input, mi_execute_command); + else + start_event_loop (); +} + +static char * +mi_input (char *buf) +{ + return gdb_readline (NULL); +} + +void +_initialize_mi_interp (void) +{ + struct gdb_interpreter_procs procs = + { + mi_interpreter_init, /* init_proc */ + mi_interpreter_resume, /* resume_proc */ + mi_interpreter_suspend, /* suspend_proc */ + mi_interpreter_exec, /* exec_proc */ + mi_interpreter_prompt_p /* prompt_proc_p */ + }; + + /* Create MI1 interpreter */ + if (mi1_interp == NULL) + { + mi1_interp = + gdb_interpreter_new (GDB_INTERPRETER_MI1, NULL, mi_out_new (1), + &procs); + if (mi1_interp == NULL) + error + ("Couldn't allocate a new interpreter for the mi1 interpreter\n"); + if (gdb_interpreter_add (mi1_interp) != 1) + error ("Couldn't add the mi1 interpreter to gdb.\n"); + } + + /* Create MI2 interpreter */ + if (mi2_interp == NULL) + { + mi2_interp = + gdb_interpreter_new (GDB_INTERPRETER_MI2, NULL, mi_out_new (2), + &procs); + if (mi2_interp == NULL) + error + ("Couldn't allocate a new interpreter for the mi2 interpreter\n"); + if (gdb_interpreter_add (mi2_interp) != 1) + error ("Couldn't add the mi2 interpreter to gdb.\n"); + } + + /* Create MI3 interpreter */ + if (mi_interp == NULL) + { + mi_interp = + gdb_interpreter_new (GDB_INTERPRETER_MI, NULL, mi_out_new (3), + &procs); + if (mi_interp == NULL) + error + ("Couldn't allocate a new interpreter for the mi interpreter\n"); + if (gdb_interpreter_add (mi_interp) != 1) + error ("Couldn't add the mi interpreter to gdb.\n"); + } +} diff --git a/gdb/mi/mi-interp.h b/gdb/mi/mi-interp.h new file mode 100644 index 00000000000..2e4761bdfbe --- /dev/null +++ b/gdb/mi/mi-interp.h @@ -0,0 +1,30 @@ +/* MI Interpreter for GDB the GNU debugger. + + Copyright 2003 Free Software Foundation, Inc. + + This file is part of GDB. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. */ + +#ifndef MI_INTERP_H +#define MI_INTERP_H + +/* The mi interpreters. */ +struct gdb_interpreter; +extern struct gdb_interpreter *mi_interp; +extern struct gdb_interpreter *mi1_interp; + +#endif diff --git a/gdb/mi/mi-main.c b/gdb/mi/mi-main.c index 96030b71ab6..e6cbbb2017e 100644 --- a/gdb/mi/mi-main.c +++ b/gdb/mi/mi-main.c @@ -33,6 +33,7 @@ #include "mi-console.h" #include "ui-out.h" #include "mi-out.h" +#include "interps.h" #include "event-loop.h" #include "event-top.h" #include "gdbcore.h" /* for write_memory() */ @@ -79,27 +80,34 @@ struct ui_file *raw_stdout; /* The token of the last asynchronous command */ static char *last_async_command; static char *previous_async_command; -static char *mi_error_message; +char *mi_error_message; static char *old_regs; extern void _initialize_mi_main (void); -static char *mi_input (char *); -static void mi_execute_command (char *cmd, int from_tty); +void mi_execute_command (char *cmd, int from_tty); static enum mi_cmd_result mi_cmd_execute (struct mi_parse *parse); static void mi_execute_cli_command (const char *cli, char *args); static enum mi_cmd_result mi_execute_async_cli_command (char *mi, char *args, int from_tty); -static void mi_execute_command_wrapper (char *cmd); void mi_exec_async_cli_cmd_continuation (struct continuation_arg *arg); static int register_changed_p (int regnum); static int get_register (int regnum, int format); -static void mi_load_progress (const char *section_name, - unsigned long sent_so_far, - unsigned long total_section, - unsigned long total_sent, - unsigned long grand_total); +void mi_load_progress (const char *section_name, + unsigned long sent_so_far, + unsigned long total_section, + unsigned long total_sent, + unsigned long grand_total); + +/* A helper function which will set mi_error_message to error_last_message. */ +void +mi_error_last_message (void) +{ + char *s = error_last_message (); + xasprintf (&mi_error_message, s); + xfree (s); +} /* Command implementations. FIXME: Is this libgdb? No. This is the MI layer that calls libgdb. Any operation used in the below should be @@ -1098,7 +1106,12 @@ captured_mi_execute_command (struct ui_out *uiout, void *data) if (!target_can_async_p () || !target_executing) { - /* print the result if there were no errors */ + /* print the result if there were no errors + + Remember that on the way out of executing a command, you have + to directly use the mi_interp's uiout, since the command could + have reset the interpreter, in which case the current uiout + will most likely crash in the mi_out_* routines. */ if (args->rc == MI_CMD_DONE) { fputs_unfiltered (context->token, raw_stdout); @@ -1146,15 +1159,22 @@ captured_mi_execute_command (struct ui_out *uiout, void *data) /* FIXME: If the command string has something that looks like a format spec (e.g. %s) we will get a core dump */ mi_execute_cli_command ("%s", context->command); - /* print the result */ - /* FIXME: Check for errors here. */ - fputs_unfiltered (context->token, raw_stdout); - fputs_unfiltered ("^done", raw_stdout); - mi_out_put (uiout, raw_stdout); - mi_out_rewind (uiout); - fputs_unfiltered ("\n", raw_stdout); - args->action = EXECUTE_COMMAND_DISPLAY_PROMPT; - args->rc = MI_CMD_DONE; + + /* If we changed interpreters, DON'T print out anything. */ + if (gdb_interpreter_current_is_named_p (GDB_INTERPRETER_MI) + || gdb_interpreter_current_is_named_p (GDB_INTERPRETER_MI2) + || gdb_interpreter_current_is_named_p (GDB_INTERPRETER_MI1)) + { + /* print the result */ + /* FIXME: Check for errors here. */ + fputs_unfiltered (context->token, raw_stdout); + fputs_unfiltered ("^done", raw_stdout); + mi_out_put (uiout, raw_stdout); + mi_out_rewind (uiout); + fputs_unfiltered ("\n", raw_stdout); + args->action = EXECUTE_COMMAND_DISPLAY_PROMPT; + args->rc = MI_CMD_DONE; + } break; } @@ -1169,7 +1189,7 @@ mi_execute_command (char *cmd, int from_tty) struct mi_parse *command; struct captured_mi_execute_command_args args; struct ui_out *saved_uiout = uiout; - int result, rc; + int result; /* This is to handle EOF (^D). We just quit gdb. */ /* FIXME: we should call some API function here. */ @@ -1277,12 +1297,6 @@ mi_cmd_execute (struct mi_parse *parse) } } -static void -mi_execute_command_wrapper (char *cmd) -{ - mi_execute_command (cmd, stdin == instream); -} - /* FIXME: This is just a hack so we can get some extra commands going. We don't want to channel things through the CLI, but call libgdb directly */ /* Use only for synchronous commands */ @@ -1385,13 +1399,7 @@ mi_exec_async_cli_cmd_continuation (struct continuation_arg *arg) do_exec_cleanups (ALL_CLEANUPS); } -static char * -mi_input (char *buf) -{ - return gdb_readline (NULL); -} - -static void +void mi_load_progress (const char *section_name, unsigned long sent_so_far, unsigned long total_section, @@ -1403,7 +1411,9 @@ mi_load_progress (const char *section_name, static char *previous_sect_name = NULL; int new_section; - if (!interpreter_p || strncmp (interpreter_p, "mi", 2) != 0) + if (!gdb_interpreter_current_is_named_p (GDB_INTERPRETER_MI) + && !gdb_interpreter_current_is_named_p (GDB_INTERPRETER_MI2) + && !gdb_interpreter_current_is_named_p (GDB_INTERPRETER_MI1)) return; update_threshold.tv_sec = 0; @@ -1462,131 +1472,17 @@ mi_load_progress (const char *section_name, } } -static void -mi_command_loop (int mi_version) -{ - if (mi_version <= 1) - { - /* HACK: Force stdout/stderr to point at the console. This avoids - any potential side effects caused by legacy code that is still - using the TUI / fputs_unfiltered_hook */ - raw_stdout = stdio_fileopen (stdout); - /* Route normal output through the MIx */ - gdb_stdout = mi_console_file_new (raw_stdout, "~"); - } - - /* Route error and log output through the MI */ - gdb_stderr = mi_console_file_new (raw_stdout, "&"); - gdb_stdlog = gdb_stderr; - /* Route target output through the MI. */ - gdb_stdtarg = mi_console_file_new (raw_stdout, "@"); - - /* HACK: Poke the ui_out table directly. Should we be creating a - mi_out object wired up to the above gdb_stdout / gdb_stderr? */ - uiout = mi_out_new (mi_version); - - /* HACK: Override any other interpreter hooks. We need to create a - real event table and pass in that. */ - init_ui_hook = 0; - /* command_loop_hook = 0; */ - print_frame_info_listing_hook = 0; - query_hook = 0; - warning_hook = 0; - create_breakpoint_hook = 0; - delete_breakpoint_hook = 0; - modify_breakpoint_hook = 0; - interactive_hook = 0; - registers_changed_hook = 0; - readline_begin_hook = 0; - readline_hook = 0; - readline_end_hook = 0; - register_changed_hook = 0; - memory_changed_hook = 0; - context_hook = 0; - target_wait_hook = 0; - call_command_hook = 0; - error_hook = 0; - error_begin_hook = 0; - show_load_progress = mi_load_progress; - - /* Turn off 8 bit strings in quoted output. Any character with the - high bit set is printed using C's octal format. */ - sevenbit_strings = 1; - - /* Tell the world that we're alive */ - fputs_unfiltered ("(gdb) \n", raw_stdout); - gdb_flush (raw_stdout); - - if (!event_loop_p) - simplified_command_loop (mi_input, mi_execute_command); - else - start_event_loop (); -} - -static void -mi1_command_loop (void) -{ - mi_command_loop (1); -} - -static void -mi2_command_loop (void) -{ - mi_command_loop (2); -} - -static void -setup_architecture_data (void) +void +mi_setup_architecture_data (void) { /* don't trust REGISTER_BYTES to be zero. */ old_regs = xmalloc (REGISTER_BYTES + 1); memset (old_regs, 0, REGISTER_BYTES + 1); } -static void -mi_init_ui (char *arg0) -{ - if (strlen (interpreter_p) <= 2 || - interpreter_p[2] > '1') - { - /* HACK: Force stdout/stderr to point at the console. This avoids - any potential side effects caused by legacy code that is still - using the TUI / fputs_unfiltered_hook */ - raw_stdout = stdio_fileopen (stdout); - /* Route normal output through the MIx */ - gdb_stdout = mi_console_file_new (raw_stdout, "~"); - } -} - void -_initialize_mi_main (void) +mi_register_gdbarch_swap (void) { - if (interpreter_p == NULL) - return; - - /* If we're _the_ interpreter, take control. */ - if (strcmp (interpreter_p, "mi") == 0) - command_loop_hook = mi2_command_loop; - else if (strcmp (interpreter_p, "mi1") == 0) - command_loop_hook = mi1_command_loop; - else if (strcmp (interpreter_p, "mi2") == 0) - command_loop_hook = mi2_command_loop; - else - return; - - init_ui_hook = mi_init_ui; - setup_architecture_data (); register_gdbarch_swap (&old_regs, sizeof (old_regs), NULL); - register_gdbarch_swap (NULL, 0, setup_architecture_data); - if (event_loop_p) - { - /* These overwrite some of the initialization done in - _intialize_event_loop. */ - call_readline = gdb_readline2; - input_handler = mi_execute_command_wrapper; - add_file_handler (input_fd, stdin_event_handler, 0); - async_command_editing_p = 0; - } - /* FIXME: Should we notify main that we are here as a possible - interpreter? */ + register_gdbarch_swap (NULL, 0, mi_setup_architecture_data); } diff --git a/gdb/mi/mi.h b/gdb/mi/mi.h new file mode 100644 index 00000000000..b553d56c9b2 --- /dev/null +++ b/gdb/mi/mi.h @@ -0,0 +1,38 @@ +/* MI Internal Functions + Copyright 2002 Free Software Foundation, Inc. + + This file is part of GDB. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. */ + +#ifndef MI_H +#define MI_H +/* The mi interpreters. */ + +extern struct gdb_interpreter *mi_interp; +extern struct gdb_interpreter *mi1_interp; +extern struct gdb_events mi_event_handlers; +extern struct ui_file *mi_event_channel; + +extern void mi_setup_architecture_data (void); +extern void mi_register_gdbarch_swap (void); + +extern void mi_load_progress (const char *section_name, + unsigned long sent_so_far, + unsigned long total_section, + unsigned long total_sent, + unsigned long grand_total); +#endif /* MI_H */ diff --git a/gdb/testsuite/ChangeLog b/gdb/testsuite/ChangeLog index 82f3843f3ed..9757675c39b 100644 --- a/gdb/testsuite/ChangeLog +++ b/gdb/testsuite/ChangeLog @@ -1,3 +1,57 @@ +2003-02-03 Andrew Cagney + + * lib/mi-support: Hack, accept any prompt for moment. + +2002-09-11 Keith Seitz + + * lib/mi-support.exp (mi_step_next_helper): Remove. + (mi_next): Use mi_next_to. + (mi_step): Use mi_step_to. + +2002-09-05 Keith Seitz + + * lib/mi-support.exp (mi_runto): New proc. Does the same as gdb's + runto proc. + (mi_run_to_main): Use mi_runto. + +2002-09-04 Keith Seitz + + * lib/mi-support.exp (mi_run_to_main): Allow anything to precede + regexp for stopping at main. Could have multiple event notifications. + Don't assume that main was declared with no parameters. + (mi_step_next_helper): New procedure to do step/next. + (mi_next): Use mi_step_next_helper. + (mi_step): Ditto. + +2002-09-04 Keith Seitz + + * lib/gdb.exp (gdb_compile_pthreads): Fix "build_bin" typo. + Use integer comparison instead of string comparison for testing + whether binary was built. + +2002-08-29 Keith Seitz + + * lib/mi-support.exp (mi_gdb_test): Add global declaration for + expect_out so that callers can get at it. + +2002-07-22 Keith Seitz + + * lib/mi-support.exp (mi_delete_breakpoints): Allow for breakpoint + delete events in output of -break-delete. + (mi_run_to_main): Don't assume that breakpoint at main is first + breakpoint installed. + +2002-06-24 Keith Seitz + + * lib/mi-support.exp (mi_gdb_test): Move expected pattern higher + in the list of expect statements. + +2002-06-19 Keith Seitz + + * lib/mi-support.exp (mi_run_to_main): Use MIFLAGS to figure + out what version of MI is running. Use this to determine the proper + output of setting a breakpoint. + 2003-02-02 Andrew Cagney 2002-11-10 Jason Molenda (jason-cl@molenda.com): diff --git a/gdb/testsuite/gdb.mi/ChangeLog b/gdb/testsuite/gdb.mi/ChangeLog index 2e2a82e3c85..8af7538b053 100644 --- a/gdb/testsuite/gdb.mi/ChangeLog +++ b/gdb/testsuite/gdb.mi/ChangeLog @@ -1,3 +1,29 @@ +2002-08-21 Keith Seitz + + * mi-cli.exp: Use "target_changed" instead of "register-update". + +2002-07-25 Keith Seitz + + * mi-cli.exp: Fix typo in result for "-interpreter-exec console list" + test. + Don't break at main: use mi_run_to_main instead. + Add tests to break in callee4 and navigate the stack. + Add test to set a register and test for update event. + +2002-07-22 Keith Seitz + + * mi-cli.exp: Use mi_run_to_main to get to main. Don't use "run". + Refine result string for "-interpreter-exec console bougs" test. + +2002-06-25 Keith Seitz + + * mi-cli.exp: Add tests to check if list_command in the console + is synchronized with MI's state. + +2002-06-24 Keith Seitz + + * mi-cli.exp: New file. + 2002-12-13 Jeff Johnston * mi-basics.exp: Change tests for -environment-directory. Also add diff --git a/gdb/testsuite/gdb.mi/mi-break.exp b/gdb/testsuite/gdb.mi/mi-break.exp index 5cbe4e40d2e..ffc23a6b4d8 100644 --- a/gdb/testsuite/gdb.mi/mi-break.exp +++ b/gdb/testsuite/gdb.mi/mi-break.exp @@ -1,4 +1,4 @@ -# Copyright 1999 Free Software Foundation, Inc. +# Copyright 1999, 2002 Free Software Foundation, Inc. # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by @@ -62,20 +62,20 @@ proc test_tbreak_creation_and_listing {} { # -break-list mi_gdb_test "222-break-insert -t main" \ - "222\\^done,bkpt=\{number=\"1\",type=\"breakpoint\",disp=\"del\",enabled=\"y\",addr=\"$hex\",func=\"main\",file=\".*basics.c\",line=\"32\",times=\"0\"\}" \ + "=breakpoint-create,number=\"1\"\r\n222\\^done" \ "break-insert -t operation" mi_gdb_test "333-break-insert -t basics.c:callee2" \ - "333\\^done,bkpt=\{number=\"2\",type=\"breakpoint\",disp=\"del\",enabled=\"y\",addr=\"$hex\",func=\"callee2\",file=\".*basics.c\",line=\"22\",times=\"0\"\}" \ + "=breakpoint-create,number=\"2\"\r\n333\\^done" \ "insert temp breakpoint at basics.c:callee2" mi_gdb_test "444-break-insert -t basics.c:15" \ - "444\\^done,bkpt=\{number=\"3\",type=\"breakpoint\",disp=\"del\",enabled=\"y\",addr=\"$hex\",func=\"callee3\",file=\".*basics.c\",line=\"15\",times=\"0\"\}" \ + "=breakpoint-create,number=\"3\"\r\n444\\^done" \ "insert temp breakpoint at basics.c:15 (callee3)" # Getting the quoting right is tricky. That is "\"\":6" mi_gdb_test "555-break-insert -t \"\\\"${srcfile}\\\":6\"" \ - "555\\^done,bkpt=\{number=\"4\",type=\"breakpoint\",disp=\"del\",enabled=\"y\",addr=\"$hex\",func=\"callee4\",file=\".*basics.c\",line=\"6\",times=\"0\"\}" \ + "=breakpoint-create,number=\"4\"\r\n555\\^done" \ "insert temp breakpoint at \"\":6 (callee4)" mi_gdb_test "666-break-list" \ diff --git a/gdb/testsuite/gdb.mi/mi-cli.exp b/gdb/testsuite/gdb.mi/mi-cli.exp new file mode 100644 index 00000000000..850d177cb19 --- /dev/null +++ b/gdb/testsuite/gdb.mi/mi-cli.exp @@ -0,0 +1,143 @@ +# Copyright 2002 Free Software Foundation, Inc. + +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +# Please email any bugs, comments, and/or additions to this file to: +# bug-gdb@prep.ai.mit.edu + +# This file tests that GDB's console can be accessed via the MI. +# Specifically, we are testing the "interpreter-exec" command and that +# the commands that are executed via this command are properly executed. +# Console commands executed via MI should use MI output wrappers, MI event +# handlers, etc. + +load_lib mi-support.exp +set MIFLAGS "-i=mi" + +gdb_exit +if [mi_gdb_start] { + continue +} + +set testfile "basics" +set srcfile ${testfile}.c +set binfile ${objdir}/${subdir}/${testfile} +if { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable {debug additional_flags=-DFAKEARGV}] != "" } { + gdb_suppress_entire_file "Testcase compile failed, so all tests in this file will automatically fail." +} + +mi_gdb_reinitialize_dir $srcdir/$subdir + +mi_gdb_test "-interpreter-exec" \ + {\^error,msg="mi_cmd_interpreter_exec: Usage: -interpreter-exec interp command"} \ + "-interpreter-exec with no arguments" + +mi_gdb_test "-interpreter-exec console" \ + {\^error,msg="mi_cmd_interpreter_exec: Usage: -interpreter-exec interp command"} \ + "-interpreter-exec with one argument" + +mi_gdb_test "-interpreter-exec bogus command" \ + {\^error,msg="mi_cmd_interpreter_exec: could not find interpreter \\\"bogus\\\""} \ + "-interpreter-exec with bogus interpreter" + +set msg {Undefined command: \\\"bogus\\\"\. Try \\\"help\\\"\.} +mi_gdb_test "-interpreter-exec console bogus" \ + "&\\\"$msg\\\\n\\\".*\\^error,msg=\\\"$msg\\\".*" \ + "-interpreter-exec console bogus" + +mi_gdb_test "-interpreter-exec console \"file $binfile\"" \ + {(=.*)+\^done} \ + "-interpreter-exec console \"file \$binfile\"" + +mi_run_to_main + +mi_gdb_test "-interpreter-exec console \"set args foobar\"" \ + {\^done} \ + "-interpreter-exec console \"set args foobar\"" + +mi_gdb_test "-interpreter-exec console \"show args\"" \ + {\~"Argument list to give program being debugged when it is started is \\\"foobar\\\"\.\\n".*\^done} \ + "-interpreter-exec console \"show args\"" + +mi_gdb_test "-interpreter-exec console \"break callee4\"" \ + {(&.*)*.*~"Breakpoint 2 at.*\\n".*=breakpoint-create,number="2".*\^done} \ + "-interpreter-exec console \"break callee4\"" + +mi_gdb_test "-interpreter-exec console \"info break\"" \ + {\~"Num[ \t]*Type[ \t]*Disp[ \t]*Enb[ \t]*Address[ \t]*What\\n".*~"2[ \t]*breakpoint[ \t]*keep[ \t]*y[ \t]*0x[0-9A-Fa-f]+[ \t]*in callee4 at .*basics.c:[0-9]+\\n".*\^done} \ + "-interpreter-exec console \"info break\"" + +mi_gdb_test "-interpreter-exec console \"set listsize 1\"" \ + {\^done} \ + "-interpreter-exec console \"set listsize 1\"" + +mi_gdb_test "-interpreter-exec console \"list\"" \ + {.*\~"32[ \t(\\t)]*callee1.*\\n".*\^done} \ + "-interpreter-exec console \"list\"" + +mi_gdb_test "-exec-continue" \ + {.*\*stopped,reason="breakpoint-hit",.*func="callee4".*file=".*basics.c",line="8"\}} \ + "-interpreter-exec console \"continue to callee4\"" + +mi_gdb_test "-interpreter-exec console \"delete 2\"" \ + {.*=breakpoint-delete,number=\"2\".*\^done} \ + "-interpreter-exec console \"delete 2\"" + +mi_gdb_test "-interpreter-exec console \"up\"" \ + {.*=selected-frame-level-changed,level="1".*\^done} \ + "-interpreter-exec console \"up\"" + +mi_gdb_test "-interpreter-exec console \"down\"" \ + {.*=selected-frame-level-changed,level="0".*\^done} \ + "-interpreter-exec console \"down\"" + +mi_gdb_test "-interpreter-exec console \"frame 2\"" \ + {.*=selected-frame-level-changed,level="2".*\^done} \ + "-interpreter-exec console \"frame 2\"" + +mi_gdb_test "-stack-select-frame 0" \ + {.*=selected-frame-level-changed,level="0".*\^done} \ + "-stack-select-frame 0" + +mi_gdb_test "-break-insert -t basics.c:35" \ + {.*=breakpoint-create,number="3".*\^done} \ + "-break-insert -t basics.c:35" + +mi_gdb_test "-exec-continue" \ + {.*\*stopped.*,file=".*basics.c",line="35"\}} \ + "-exec-continue to line 35" + +mi_gdb_test "-exec-next" \ + {.*\*stopped,reason="end-stepping-range",.*,file=".*basics.c",line="37"\}} \ + "-exec-next to line 37" + +mi_gdb_test "-interpreter-exec console \"list\"" \ + {\~"37[ \t(\\t)]*return 0;\\n".*\^done} \ + "-interpreter-exec console \"list\" at basics.c:37" + +mi_gdb_test "-interpreter-exec console \"help set args\"" \ + {\~"Set argument list to give program being debugged when it is started\.\\nFollow this command with any number of args, to be passed to the program\.".*\^done} \ + "-interpreter-exec console \"help set args\"" + +mi_gdb_test "-interpreter-exec console \"set \$pc=0x0\"" \ + {.*=target-changed.*\^done} \ + "-interpreter-exec console \"set \$pc=0x0\"" + +#mi_gdb_test "-interpreter-exec console \"\"" \ + {} \ + "-interpreter-exec console \"\"" + +mi_gdb_exit +return 0 diff --git a/gdb/testsuite/gdb.mi/mi-pthreads.exp b/gdb/testsuite/gdb.mi/mi-pthreads.exp index 532134acc04..8fc5061c803 100644 --- a/gdb/testsuite/gdb.mi/mi-pthreads.exp +++ b/gdb/testsuite/gdb.mi/mi-pthreads.exp @@ -17,11 +17,11 @@ # Please email any bugs, comments, and/or additions to this file to: # bug-gdb@prep.ai.mit.edu -# This file tests MI thread commands. -# Specifically, we are testing the MI command set and the console (in MI) -# command set ("interpreter-exec") and that the commands that are executed -# via these command pathways are properly executed. Console commands -# executed via MI should use MI output wrappers, MI event handlers, etc. +# This file tests that GDB's console can be accessed via the MI. +# Specifically, we are testing the "interpreter-exec" command and that +# the commands that are executed via this command are properly executed. +# Console commands executed via MI should use MI output wrappers, MI event +# handlers, etc. # This only works with native configurations if {![isnative]} { @@ -36,10 +36,6 @@ if {[mi_gdb_start]} { continue } -# The procs below dealing with parsing cli/mi output for the threadlist -# is duplicated in gdb669.exp. Any changes here will probably need to -# be made there as well. - proc get_mi_thread_list {name} { global expect_out @@ -49,16 +45,11 @@ proc get_mi_thread_list {name} { # ^done,thread-ids=[thread-id="1",thread-id="2",...],number-of-threads="N" # (gdb) mi_gdb_test "-thread-list-ids" \ - {\^done,thread-ids={(thread-id="[0-9]+"(,)?)+},number-of-threads="[0-9]+"} \ + {\^done,thread-ids=\{(thread-id="[0-9]+"(,)*)+\},number-of-threads="[0-9]+"} \ "-thread_list_ids ($name)" - set output {} - if {[info exists expect_out(buffer)]} { - set output $expect_out(buffer) - } - set thread_list {} - if {![regexp {thread-ids=\{(thread-id="[0-9]+"(,)?)*\}} $output threads]} { + if {![regexp {thread-ids=\{(thread-id="[0-9]+"(,)?)*\}} $expect_out(buffer) threads]} { fail "finding threads in MI output ($name)" } else { pass "finding threads in MI output ($name)" @@ -83,12 +74,9 @@ proc check_mi_and_console_threads {name} { global expect_out mi_gdb_test "-thread-list-ids" \ - {\^done,thread-ids={(thread-id="[0-9]+"(,)*)+},number-of-threads="[0-9]+"} \ + {\^done,thread-ids=\{(thread-id="[0-9]+"(,)*)+\},number-of-threads="[0-9]+"} \ "-thread-list-ids ($name)" - set mi_output {} - if {[info exists expect_out(buffer)]} { - set mi_output $expect_out(buffer) - } + set mi_output $expect_out(buffer) # GDB will return a list of thread ids and some more info: # @@ -98,14 +86,10 @@ proc check_mi_and_console_threads {name} { # ~" 3 Thread 1026 (LWP 7733) () at __libc_nanosleep:-1" # ~" 2 Thread 2049 (LWP 7732) 0x401411f8 in __poll (fds=0x804bb24, nfds=1, timeout=2000) at ../sysdeps/unix/sysv/linux/poll.c:63" # ~"* 1 Thread 1024 (LWP 7731) main (argc=1, argv=0xbfffdd94) at ../../../src/gdb/testsuite/gdb.mi/pthreads.c:160" - # FIXME: kseitz/2002-09-05: Don't use the hack-cli method. - mi_gdb_test "info threads" \ + mi_gdb_test {-interpreter-exec console "info threads"} \ {.*(~".*"[\r\n]*)+.*} \ "info threads ($name)" - set console_output {} - if {[info exists $expect_out(buffer)]} { - set console_output $expect_out(buffer) - } + set console_output $expect_out(buffer) # Make a list of all known threads to console (gdb's thread IDs) set console_thread_list {} @@ -175,6 +159,19 @@ proc check_mi_and_console_threads {name} { } } +# This procedure checks for the bug gdb/669, where the console +# command "info threads" and the MI command "-thread-list-ids" +# return different threads in the system. +proc check_for_gdb669_bug {} { + mi_run_to_main + check_mi_and_console_threads "at main" + + for {set i 0} {$i < 4} {incr i} { + mi_next "next, try $i" + check_mi_and_console_threads "try $i" + } +} + # This procedure tests the various thread commands in MI. proc check_mi_thread_command_set {} { @@ -195,11 +192,24 @@ proc check_mi_thread_command_set {} { # many of the threads are blocked in libc calls, # and many people have libc's with no symbols. mi_gdb_test "-thread-select $thread" \ - "\\^done,new-thread-id=\"$thread\",frame={.*}(,line=\"(-)?\[0-9\]+\",file=\".*\")?" \ + "=context-changed,thread=\"$thread\"\r\n\\^done,new-thread-id=\"$thread\",frame={.*},line=\"(-)?\[0-9\]+\",file=\".*\"" \ "check_mi_thread_command_set: -thread-select $thread" } } +# This procedure checks that the console and MI don't get out +# of sync with each other. +proc check_console_thread_commands {} { + + # Assumed that we're at done_making_threads + set thread_list [get_mi_thread_list "in check_console_thread_commands"] + foreach thread $thread_list { + mi_gdb_test "-interpreter-exec console \"thread $thread\"" \ + "(\\~\".*\"\r\n)*=context-changed,thread=\"$thread\"\r\n\\^done" \ + "-interpreter-exec console \"thread $thread\"" + } +} + # # Start here # @@ -216,6 +226,8 @@ mi_gdb_reinitialize_dir $srcdir/$subdir mi_gdb_load $binfile check_mi_thread_command_set +check_console_thread_commands +check_for_gdb669_bug mi_gdb_exit diff --git a/gdb/testsuite/gdb.mi/mi-return.exp b/gdb/testsuite/gdb.mi/mi-return.exp index ca37e9fc9fc..0454e0ef788 100644 --- a/gdb/testsuite/gdb.mi/mi-return.exp +++ b/gdb/testsuite/gdb.mi/mi-return.exp @@ -46,7 +46,6 @@ mi_gdb_reinitialize_dir $srcdir/$subdir mi_gdb_reinitialize_dir $srcdir/$subdir mi_gdb_load ${binfile} - proc test_return_simple {} { global mi_gdb_prompt global hex diff --git a/gdb/testsuite/gdb.mi/mi-simplerun.exp b/gdb/testsuite/gdb.mi/mi-simplerun.exp index a3ebd20910b..4c6629700a3 100644 --- a/gdb/testsuite/gdb.mi/mi-simplerun.exp +++ b/gdb/testsuite/gdb.mi/mi-simplerun.exp @@ -1,4 +1,4 @@ -# Copyright 1999, 2000 Free Software Foundation, Inc. +# Copyright 1999, 2000, 2002 Free Software Foundation, Inc. # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by @@ -62,19 +62,19 @@ proc test_breakpoints_creation_and_listing {} { # -break-info mi_gdb_test "200-break-insert main" \ - "200\\^done,bkpt=\{number=\"1\",type=\"breakpoint\",disp=\"keep\",enabled=\"y\",addr=\"$hex\",func=\"main\",file=\".*basics.c\",line=\"32\",times=\"0\"\}" \ + "=breakpoint-create,number=\"1\"\r\n200\\^done" \ "break-insert operation" mi_gdb_test "201-break-insert basics.c:callee2" \ - "201\\^done,bkpt=\{number=\"2\",type=\"breakpoint\",disp=\"keep\",enabled=\"y\",addr=\"$hex\",func=\"callee2\",file=\".*basics.c\",line=\"22\",times=\"0\"\}" \ + "=breakpoint-create,number=\"2\"\r\n201\\^done" \ "insert breakpoint at basics.c:callee2" mi_gdb_test "202-break-insert basics.c:15" \ - "202\\^done,bkpt=\{number=\"3\",type=\"breakpoint\",disp=\"keep\",enabled=\"y\",addr=\"$hex\",func=\"callee3\",file=\".*basics.c\",line=\"15\",times=\"0\"\}" \ + "=breakpoint-create,number=\"3\"\r\n202\\^done" \ "insert breakpoint at basics.c:15 (callee3)" mi_gdb_test "203-break-insert \"\\\"${srcfile}\\\":6\"" \ - "203\\^done,bkpt=\{number=\"4\",type=\"breakpoint\",disp=\"keep\",enabled=\"y\",addr=\"$hex\",func=\"callee4\",file=\".*basics.c\",line=\"6\",times=\"0\"\}" \ + "=breakpoint-create,number=\"4\"\r\n203\\^done" \ "insert breakpoint at \"\":6 (callee4)" mi_gdb_test "204-break-list" \ @@ -82,7 +82,7 @@ proc test_breakpoints_creation_and_listing {} { "list of breakpoints" mi_gdb_test "205-break-disable 2 3 4" \ - "205\\^done.*" \ + "=breakpoint-modify,number=\"2\"\r\n=breakpoint-modify,number=\"3\"\r\n=breakpoint-modify,number=\"4\"\r\n205\\^done.*" \ "disabling of breakpoints" mi_gdb_test "206-break-info 2" \ diff --git a/gdb/testsuite/gdb.mi/mi-until.exp b/gdb/testsuite/gdb.mi/mi-until.exp index ac276cc5229..8e82a0c053a 100644 --- a/gdb/testsuite/gdb.mi/mi-until.exp +++ b/gdb/testsuite/gdb.mi/mi-until.exp @@ -1,4 +1,4 @@ -# Copyright 1999, 2000 Free Software Foundation, Inc. +# Copyright 1999, 2000, 2002 Free Software Foundation, Inc. # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by @@ -46,12 +46,13 @@ mi_gdb_reinitialize_dir $srcdir/$subdir mi_gdb_reinitialize_dir $srcdir/$subdir mi_gdb_load ${binfile} +set timeout 5 proc test_running_to_foo {} { global mi_gdb_prompt global hex mi_gdb_test "200-break-insert 10" \ - "200\\^done,bkpt=\{number=\"1\",type=\"breakpoint\",disp=\"keep\",enabled=\"y\",addr=\"$hex\",func=\"foo\",file=\".*until.c\",line=\"10\",times=\"0\"\}" \ + "=breakpoint-create,number=\"1\"\r\n200\\^done" \ "break-insert operation" mi_run_cmd @@ -68,7 +69,7 @@ proc test_running_to_foo {} { } } - mi_gdb_test "100-break-delete 1" "100\\^done" "break-delete 1" + mi_gdb_test "100-break-delete 1" "=breakpoint-delete,number=\"1\"\r\n100\\^done" "break-delete 1" } @@ -88,7 +89,7 @@ proc test_until {} { send_gdb "222-exec-until 15\n" gdb_expect { - -re "222\\^running\r\n${mi_gdb_prompt}222\\*stopped,reason=\"location-reached\",thread-id=\"\[01\]\",frame=\{addr=\"$hex\",func=\"foo\",args=\\\[\\\],file=\".*until.c\",line=\"15\"\}\r\n$mi_gdb_prompt$" { + -re "222\\^running\r\n${mi_gdb_prompt}(=breakpoint-.*\r\n)*222\\*stopped,reason=\"location-reached\",thread-id=\"\[01\]\",frame=\{addr=\"$hex\",func=\"foo\",args=\\\[\\\],file=\".*until.c\",line=\"15\"\}\r\n$mi_gdb_prompt$" { pass "until line number" } timeout { @@ -98,7 +99,7 @@ proc test_until {} { send_gdb "333-exec-until until.c:17\n" gdb_expect { - -re "333\\^running\r\n${mi_gdb_prompt}333\\*stopped,reason=\"location-reached\",thread-id=\"\[01\]\",frame=\{addr=\"$hex\",func=\"foo\",args=\\\[\\\],file=\".*until.c\",line=\"17\"\}\r\n$mi_gdb_prompt$" { + -re "333\\^running\r\n${mi_gdb_prompt}(=breakpoint-.*\r\n)*333\\*stopped,reason=\"location-reached\",thread-id=\"\[01\]\",frame=\{addr=\"$hex\",func=\"foo\",args=\\\[\\\],file=\".*until.c\",line=\"17\"\}\r\n$mi_gdb_prompt$" { pass "until line number:file" } timeout { @@ -110,7 +111,7 @@ proc test_until {} { send_gdb "444-exec-until until.c:25\n" gdb_expect { - -re "444\\^running\r\n${mi_gdb_prompt}444\\*stopped,reason=\"location-reached\",thread-id=\"\[01\]\",frame=\{addr=\"$hex\",func=\"main\",args=\\\[\\\],file=\".*until.c\",line=\"24\"\}\r\n$mi_gdb_prompt$" { + -re "444\\^running\r\n${mi_gdb_prompt}(=breakpoint-.*\r\n)*444\\*stopped,reason=\"location-reached\",thread-id=\"\[01\]\",frame=\{addr=\"$hex\",func=\"main\",args=\\\[\\\],file=\".*until.c\",line=\"24\"\}\r\n$mi_gdb_prompt$" { pass "until after current function" } timeout { diff --git a/gdb/testsuite/gdb.mi/mi-var-cmd.exp b/gdb/testsuite/gdb.mi/mi-var-cmd.exp index 7d02b36943a..bdb4f75fbd6 100644 --- a/gdb/testsuite/gdb.mi/mi-var-cmd.exp +++ b/gdb/testsuite/gdb.mi/mi-var-cmd.exp @@ -385,7 +385,7 @@ mi_gdb_test "-var-assign lsimple.integer 333" \ ##### mi_gdb_test "-break-insert subroutine1" \ - "\\^done,bkpt=\{number=\"2\",type=\"breakpoint\",disp=\"keep\",enabled=\"y\",addr=\"$hex\",func=\"subroutine1\",file=\".*var-cmd.c\",line=\"146\",times=\"0\"\}" \ + "=breakpoint-create,number=\"2\"\r\n\\^done" \ "break-insert subroutine1" mi_continue_to "2" "subroutine1" \ "\{name=\"i\",value=\"4321\"\},\{name=\"l\",value=\"$hex\"\}" \ @@ -530,7 +530,7 @@ mi_gdb_test "-var-delete l" \ # Test whether we can follow the name of a variable through multiple # stack frames. mi_gdb_test "-break-insert do_special_tests" \ - {\^done,bkpt=.*} \ + "=breakpoint-create,number=\"\[0-9\]+\"\r\n\\^done" \ "set breakpoint at do_special_tests" mi_continue_to {.*} do_special_tests {.*} {.*var-cmd.c} {.*} {stop in do_special_tests} @@ -540,7 +540,7 @@ mi_gdb_test "-var-create selected_a @ a" \ "create selected_a" mi_gdb_test "-break-insert incr_a" \ - {\^done,bkpt=.*} \ + "=breakpoint-create,number=\"\[0-9\]+\"\r\n\\^done" \ "set breakpoint at incr_a" mi_continue_to {.*} incr_a {.*} {.*var-cmd.c} {.*} {stop in incr_a} diff --git a/gdb/testsuite/gdb.mi/mi-var-display.exp b/gdb/testsuite/gdb.mi/mi-var-display.exp index fafa79a3390..1a888dfa0df 100644 --- a/gdb/testsuite/gdb.mi/mi-var-display.exp +++ b/gdb/testsuite/gdb.mi/mi-var-display.exp @@ -43,7 +43,7 @@ mi_gdb_reinitialize_dir $srcdir/$subdir mi_gdb_load ${binfile} mi_gdb_test "200-break-insert 260" \ - "200\\^done,bkpt=\{number=\"1\",type=\"breakpoint\",disp=\"keep\",enabled=\"y\",addr=\"$hex\",func=\"do_children_tests\",file=\".*var-cmd.c\",line=\"260\",times=\"0\"\}" \ + "=breakpoint-create,number=\"1\"\r\n200\\^done" \ "break-insert operation" mi_run_cmd @@ -325,12 +325,12 @@ mi_gdb_test "-var-delete weird" \ # Stop in "do_special_tests" mi_gdb_test "200-break-insert do_special_tests" \ - "200\\^done,bkpt=\{number=\"2\",type=\"breakpoint\",disp=\"keep\",enabled=\"y\",addr=\"$hex\",func=\"do_special_tests\",file=\".*var-cmd.c\",line=\"282\",times=\"0\"\}" \ + "=breakpoint-create,number=\"2\"\r\n200\\^done" \ "break-insert operation" send_gdb "-exec-continue\n" gdb_expect { - -re "\\^running\r\n${mi_gdb_prompt}\\*stopped,reason=\"breakpoint-hit\",bkptno=\"2\",thread-id=\"\[01\]\",frame=\{addr=\"$hex\",func=\"do_special_tests\",args=\\\[\\\],file=\".*var-cmd.c\",line=\"282\"\}\r\n$mi_gdb_prompt$" { + -re "\\^running\r\n${mi_gdb_prompt}(=breakpoint-.*\r\n)*\\*stopped,reason=\"breakpoint-hit\",bkptno=\"2\",thread-id=\"\[01\]\",frame=\{addr=\"$hex\",func=\"do_special_tests\",args=\\\[\\\],file=\".*var-cmd.c\",line=\"282\"\}\r\n$mi_gdb_prompt$" { pass "continue to do_special_tests" } timeout { @@ -584,14 +584,14 @@ gdb_expect { } mi_gdb_test "200-break-insert incr_a" \ - "200\\^done,bkpt=\{number=\"3\",type=\"breakpoint\",disp=\"keep\",enabled=\"y\",addr=\"$hex\",func=\"incr_a\",file=\".*var-cmd.c\",line=\"85\",times=\"0\"\}" \ + "=breakpoint-create,number=\"3\"\r\n200\\^done" \ "break-insert operation" send_gdb "-exec-continue\n" gdb_expect { - -re "\\^running\r\n${mi_gdb_prompt}\\*stopped,reason=\"breakpoint-hit\",bkptno=\"3\",thread-id=\"\[01\]\",frame=\{addr=\"$hex\",func=\"incr_a\",args=\\\[\{name=\"a\",value=\"2\.*\"\}\\\],file=\".*var-cmd.c\",line=\"85\"\}\r\n$mi_gdb_prompt$" { + -re "\\^running\r\n${mi_gdb_prompt}(=breakpoint-.*\r\n)*\\*stopped,reason=\"breakpoint-hit\",bkptno=\"3\",thread-id=\"\[01\]\",frame=\{addr=\"$hex\",func=\"incr_a\",args=\\\[\{name=\"a\",value=\"2\.*\"\}\\\],file=\".*var-cmd.c\",line=\"85\"\}\r\n$mi_gdb_prompt$" { pass "continue to incr_a" } - -re "\\^running\r\n${mi_gdb_prompt}\\*stopped,reason=\"breakpoint-hit\",bkptno=\"3\",thread-id=\"\[01\]\",frame=\{addr=\"$hex\",func=\"incr_a\",args=\\\[\{name=\"a\",value=\"\.*\"\}\\\],file=\".*var-cmd.c\",line=\"8\[345\]\"\}\r\n$mi_gdb_prompt$" { + -re "\\^running\r\n${mi_gdb_prompt}(=breakpoint-.*\r\n)*\\*stopped,reason=\"breakpoint-hit\",bkptno=\"3\",thread-id=\"\[01\]\",frame=\{addr=\"$hex\",func=\"incr_a\",args=\\\[\{name=\"a\",value=\"\.*\"\}\\\],file=\".*var-cmd.c\",line=\"8\[345\]\"\}\r\n$mi_gdb_prompt$" { fail "continue to incr_a (compiler debug info incorrect)" } -re "\\^running\r\n${mi_gdb_prompt}.*\r\n$mi_gdb_prompt$" { diff --git a/gdb/testsuite/gdb.mi/mi-watch.exp b/gdb/testsuite/gdb.mi/mi-watch.exp index ba243999d19..c7bffb510e4 100644 --- a/gdb/testsuite/gdb.mi/mi-watch.exp +++ b/gdb/testsuite/gdb.mi/mi-watch.exp @@ -58,7 +58,7 @@ proc test_watchpoint_creation_and_listing {} { # -break-list mi_gdb_test "111-break-watch C" \ - "111\\^done,wpt=\{number=\"2\",exp=\"C\"\}" \ + "=breakpoint-create,number=\"2\"\r\n111\\^done" \ "break-watch operation" mi_gdb_test "222-break-list" \ @@ -79,7 +79,7 @@ proc test_awatch_creation_and_listing {} { # -break-list mi_gdb_test "333-break-watch -a A" \ - "333\\^done,bkpt=\{number=\"1\",addr=\"$hex\",file=\".*basics.c\",line=\"32\"\}" \ + "=breakpoint-create,number=\"1\"\r\n333\\^done" \ "break-watch -a operation" mi_gdb_test "444-break-list" \ @@ -87,7 +87,7 @@ proc test_awatch_creation_and_listing {} { "list of watchpoints awatch" mi_gdb_test "777-break-delete 3" \ - "777\\^done" \ + "=breakpoint-delete,number=\"3\"\r\n777\\^done" \ "delete access watchpoint" } @@ -103,7 +103,7 @@ proc test_rwatch_creation_and_listing {} { # -break-list mi_gdb_test "200-break-watch -r C" \ - "200\\^done,bkpt=\{number=\"5\",type=\"breakpoint\",disp=\"keep\",enabled=\"y\",addr=\"$hex\",func=\"callee4\",file=\".*basics.c\",line=\"32\",times=\"0\"\}" \ + "=breakpoint-create,number=\"5"\r\n200\\^done" \ "break-insert -r operation" mi_gdb_test "300-break-list" \ @@ -111,7 +111,7 @@ proc test_rwatch_creation_and_listing {} { "list of breakpoints" mi_gdb_test "177-break-delete 4" \ - "177\\^done" \ + "=breakpoint-delete,number=\"4\"\r\n177\\^done" \ "delete read watchpoint" } diff --git a/gdb/testsuite/gdb.mi/mi1-basics.exp b/gdb/testsuite/gdb.mi/mi1-basics.exp index 42d022d6861..a10468b3c10 100644 --- a/gdb/testsuite/gdb.mi/mi1-basics.exp +++ b/gdb/testsuite/gdb.mi/mi1-basics.exp @@ -1,4 +1,4 @@ -# Copyright 1999, 2000 Free Software Foundation, Inc. +# Copyright 2002 Free Software Foundation, Inc. # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by diff --git a/gdb/testsuite/gdb.mi/mi1-break.exp b/gdb/testsuite/gdb.mi/mi1-break.exp index 34a6ef7b141..04e353494ea 100644 --- a/gdb/testsuite/gdb.mi/mi1-break.exp +++ b/gdb/testsuite/gdb.mi/mi1-break.exp @@ -1,4 +1,4 @@ -# Copyright 1999 Free Software Foundation, Inc. +# Copyright 2002 Free Software Foundation, Inc. # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by diff --git a/gdb/testsuite/gdb.mi/mi1-console.exp b/gdb/testsuite/gdb.mi/mi1-console.exp index ab7f5ac5d3f..5d7a381a753 100644 --- a/gdb/testsuite/gdb.mi/mi1-console.exp +++ b/gdb/testsuite/gdb.mi/mi1-console.exp @@ -1,4 +1,4 @@ -# Copyright 1999, 2000, 2001, 2002 Free Software Foundation, Inc. +# Copyright 2002 Free Software Foundation, Inc. # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by diff --git a/gdb/testsuite/gdb.mi/mi1-hack-cli.exp b/gdb/testsuite/gdb.mi/mi1-hack-cli.exp index 951981a16b9..0f59249e10f 100644 --- a/gdb/testsuite/gdb.mi/mi1-hack-cli.exp +++ b/gdb/testsuite/gdb.mi/mi1-hack-cli.exp @@ -1,4 +1,4 @@ -# Copyright 1999 Free Software Foundation, Inc. +# Copyright 2002 Free Software Foundation, Inc. # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by diff --git a/gdb/testsuite/gdb.mi/mi1-return.exp b/gdb/testsuite/gdb.mi/mi1-return.exp index 539a61cbf44..476fe576769 100644 --- a/gdb/testsuite/gdb.mi/mi1-return.exp +++ b/gdb/testsuite/gdb.mi/mi1-return.exp @@ -53,7 +53,7 @@ proc test_return_simple {} { send_gdb "111-exec-return\n" gdb_expect { - -re "111\\^done,frame=\{level=\"0\",addr=\"$hex\",func=\"callee3\",args=\\\[.*\\\],file=\".*basics.c\",line=\"18\"\}\r\n$mi_gdb_prompt$" {pass "return from callee4 now"} + -re "111\\^done,frame=\{level=\"0 \",addr=\"$hex\",func=\"callee3\",args=\\\[.*\\\],file=\".*basics.c\",line=\"18\"\}\r\n$mi_gdb_prompt$" {pass "return from callee4 now"} -re ".*\r\n$mi_gdb_prompt$" { fail "return from callee4 now" } timeout { fail "return from callee4 now (timeout)" } diff --git a/gdb/testsuite/gdb.mi/mi1-simplerun.exp b/gdb/testsuite/gdb.mi/mi1-simplerun.exp index 839903a02cc..bef690532f0 100644 --- a/gdb/testsuite/gdb.mi/mi1-simplerun.exp +++ b/gdb/testsuite/gdb.mi/mi1-simplerun.exp @@ -1,4 +1,4 @@ -# Copyright 1999, 2000 Free Software Foundation, Inc. +# Copyright 2002 Free Software Foundation, Inc. # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by diff --git a/gdb/testsuite/gdb.mi/mi1-stack.exp b/gdb/testsuite/gdb.mi/mi1-stack.exp index b8c7cab5ce3..7de39992c7b 100644 --- a/gdb/testsuite/gdb.mi/mi1-stack.exp +++ b/gdb/testsuite/gdb.mi/mi1-stack.exp @@ -57,13 +57,13 @@ proc test_stack_frame_listing {} { # -stack-list-frames 1 3 mi_gdb_test "231-stack-list-frames" \ - "231\\^done,stack=\\\[frame=\{level=\"0\",addr=\"$hex\",func=\"callee4\",file=\".*basics.c\",line=\"8\"\},frame=\{level=\"1\",addr=\"$hex\",func=\"callee3\",.*\},frame=\{level=\"2\",addr=\"$hex\",func=\"callee2\",.*\},frame=\{level=\"3\",addr=\"$hex\",func=\"callee1\",.*\},frame=\{level=\"4\",addr=\"$hex\",func=\"main\",.*\}\\\]" \ + "231\\^done,stack=\\\[frame=\{level=\"0 \",addr=\"$hex\",func=\"callee4\",file=\".*basics.c\",line=\"8\"\},frame=\{level=\"1 \",addr=\"$hex\",func=\"callee3\",.*\},frame=\{level=\"2 \",addr=\"$hex\",func=\"callee2\",.*\},frame=\{level=\"3 \",addr=\"$hex\",func=\"callee1\",.*\},frame=\{level=\"4 \",addr=\"$hex\",func=\"main\",.*\}\\\]" \ "stack frame listing" mi_gdb_test "232-stack-list-frames 1 1" \ - "232\\^done,stack=\\\[frame=\{level=\"1\",addr=\"$hex\",func=\"callee3\",.*\}\\\]" \ + "232\\^done,stack=\\\[frame=\{level=\"1 \",addr=\"$hex\",func=\"callee3\",.*\}\\\]" \ "stack frame listing 1 1" mi_gdb_test "233-stack-list-frames 1 3" \ - "233\\^done,stack=\\\[frame=\{level=\"1\",addr=\"$hex\",func=\"callee3\",.*\},frame=\{level=\"2\",addr=\"$hex\",func=\"callee2\",.*\},frame=\{level=\"3\",addr=\"$hex\",func=\"callee1\",.*\}\\\]" \ + "233\\^done,stack=\\\[frame=\{level=\"1 \",addr=\"$hex\",func=\"callee3\",.*\},frame=\{level=\"2 \",addr=\"$hex\",func=\"callee2\",.*\},frame=\{level=\"3 \",addr=\"$hex\",func=\"callee1\",.*\}\\\]" \ "stack frame listing 1 3" mi_gdb_test "234-stack-list-frames 1" \ diff --git a/gdb/testsuite/gdb.mi/mi1-until.exp b/gdb/testsuite/gdb.mi/mi1-until.exp index a036b937c68..44daf79c9bd 100644 --- a/gdb/testsuite/gdb.mi/mi1-until.exp +++ b/gdb/testsuite/gdb.mi/mi1-until.exp @@ -1,4 +1,4 @@ -# Copyright 1999, 2000 Free Software Foundation, Inc. +# Copyright 2002 Free Software Foundation, Inc. # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by diff --git a/gdb/testsuite/gdb.mi/mi1-var-child.exp b/gdb/testsuite/gdb.mi/mi1-var-child.exp index 92ae3819277..91536a67d57 100644 --- a/gdb/testsuite/gdb.mi/mi1-var-child.exp +++ b/gdb/testsuite/gdb.mi/mi1-var-child.exp @@ -1,5 +1,5 @@ -# Copyright (C) 1999, 2000, 2002 Free Software Foundation - +# Copyright 2002 Free Software Foundation, Inc. +# # This Program Is Free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of the License, or @@ -42,7 +42,19 @@ mi_delete_breakpoints mi_gdb_reinitialize_dir $srcdir/$subdir mi_gdb_load ${binfile} -mi_runto do_children_tests +mi_gdb_test "200-break-insert do_children_tests" \ + "200\\^done,bkpt=\{number=\"1\",type=\"breakpoint\",disp=\"keep\",enabled=\"y\",addr=\"$hex\",func=\"do_children_tests\",file=\".*var-cmd.c\",line=\"190\",times=\"0\"\}" \ + "break-insert operation" + +mi_run_cmd +# The running part has been checked already by mi_run_cmd +gdb_expect { + -re "\[\r\n\]*000\\*stopped,reason=\"breakpoint-hit\",bkptno=\"1\",thread-id=\"\[01\]\",frame=\{addr=\"$hex\",func=\"do_children_tests\",args=\\\[\\\],file=\".*var-cmd.c\",line=\"190\"\}\r\n$mi_gdb_prompt$" { + pass "run to do_children_tests" + } + -re ".*$mi_gdb_prompt$" {fail "run to do_children_tests (2)"} + timeout {fail "run to do_children_tests (timeout 2)"} +} ##### ##### # # @@ -555,8 +567,16 @@ mi_gdb_test "-var-info-num-children struct_declarations.int_ptr_ptr.*int_ptr_ptr # Step to "struct_declarations.integer = 123;" -set line 192 -mi_step_to do_children_tests {} {.*var-cmd.c} $line "step to line $line" +send_gdb "-exec-step\n" +gdb_expect { + -re "\\^running\r\n${mi_gdb_prompt}\\*stopped,reason=\"end-stepping-range\",thread-id=\"\[01\]\",frame=\{addr=\"$hex\",func=\"do_children_tests\",args=\\\[\\\],file=\".*var-cmd.c\",line=\"192\"\}\r\n$mi_gdb_prompt$" { + pass "step at do_children_tests" + } + timeout { + fail "step at do_children_tests (timeout)" + } +} + # Test: c_variable-4.81 # Desc: create local variable "weird" @@ -754,8 +774,15 @@ mi_gdb_test "-var-update *" \ "update all vars. None changed" # Step over "struct_declarations.integer = 123;" -set line 193 -mi_step_to do_children_tests {} {.*var-cmd.c} $line "step $line" +send_gdb "-exec-step\n" +gdb_expect { + -re "\\^running\r\n${mi_gdb_prompt}\\*stopped,reason=\"end-stepping-range\",thread-id=\"\[01\]\",frame=\{addr=\"$hex\",func=\"do_children_tests\",args=\\\[\\\],file=\".*var-cmd.c\",line=\"193\"\}\r\n$mi_gdb_prompt$" { + pass "step at do_children_tests" + } + timeout { + fail "step at do_children_tests (timeout)" + } +} # Test: c_variable-5.2 # Desc: check that integer changed @@ -767,8 +794,16 @@ mi_gdb_test "-var-update *" \ # weird->char_ptr = "hello"; # bar = 2121; # foo = &bar; -set line 196 -mi_execute_to "exec-step 3" "end-stepping-range" do_children_tests {} {.*var-cmd.c} $line {} "step $line" + +send_gdb "-exec-step 3\n" +gdb_expect { + -re "\\^running\r\n${mi_gdb_prompt}\\*stopped,reason=\"end-stepping-range\",thread-id=\"\[01\]\",frame=\{addr=\"$hex\",func=\"do_children_tests\",args=\\\[\\\],file=\".*var-cmd.c\",line=\"196\"\}\r\n$mi_gdb_prompt$" { + pass "step at do_children_tests" + } + timeout { + fail "step at do_children_tests (timeout)" + } +} # Test: c_variable-5.3 # Desc: check that char_ptr changed @@ -777,8 +812,15 @@ mi_gdb_test "-var-update *" \ "update all vars struct_declarations.char_ptr" # Step over "struct_declarations.int_ptr_ptr = &foo;" -set line 197 -mi_step_to do_children_tests {} {.*var-cmd.c} $line "step $line" +send_gdb "-exec-step\n" +gdb_expect { + -re "\\^running\r\n${mi_gdb_prompt}\\*stopped,reason=\"end-stepping-range\",thread-id=\"\[01\]\",frame=\{addr=\"$hex\",func=\"do_children_tests\",args=\\\[\\\],file=\".*var-cmd.c\",line=\"197\"\}\r\n$mi_gdb_prompt$" { + pass "step at do_children_tests" + } + timeout { + fail "step at do_children_tests (timeout)" + } +} # Test: c_variable-5.4 # Desc: check that int_ptr_ptr and children changed @@ -787,8 +829,15 @@ mi_gdb_test "-var-update *" \ "update all vars int_ptr_ptr and children changed" # Step over "weird->long_array[0] = 1234;" -set line 198 -mi_step_to do_children_tests {} {.*var-cmd.c} $line "step $line" +send_gdb "-exec-step\n" +gdb_expect { + -re "\\^running\r\n${mi_gdb_prompt}\\*stopped,reason=\"end-stepping-range\",thread-id=\"\[01\]\",frame=\{addr=\"$hex\",func=\"do_children_tests\",args=\\\[\\\],file=\".*var-cmd.c\",line=\"198\"\}\r\n$mi_gdb_prompt$" { + pass "step at do_children_tests" + } + timeout { + fail "step at do_children_tests (timeout)" + } +} # Test: c_variable-5.5 # Desc: check that long_array[0] changed @@ -797,8 +846,15 @@ mi_gdb_test "-var-update *" \ "update all vars struct_declarations.long_array.0 changed" # Step over "struct_declarations.long_array[1] = 2345;" -set line 199 -mi_step_to do_children_tests {} {.*var-cmd.c} $line "step $line" +send_gdb "-exec-step\n" +gdb_expect { + -re "\\^running\r\n${mi_gdb_prompt}\\*stopped,reason=\"end-stepping-range\",thread-id=\"\[01\]\",frame=\{addr=\"$hex\",func=\"do_children_tests\",args=\\\[\\\],file=\".*var-cmd.c\",line=\"199\"\}\r\n$mi_gdb_prompt$" { + pass "step at do_children_tests" + } + timeout { + fail "step at do_children_tests (timeout)" + } +} # Test: c_variable-5.6 # Desc: check that long_array[1] changed @@ -807,8 +863,15 @@ mi_gdb_test "-var-update *" \ "update all vars struct_declarations.long_array.1 changed" # Step over "weird->long_array[2] = 3456;" -set line 200 -mi_step_to do_children_tests {} {.*var-cmd.c} $line "step $line" +send_gdb "-exec-step\n" +gdb_expect { + -re "\\^running\r\n${mi_gdb_prompt}\\*stopped,reason=\"end-stepping-range\",thread-id=\"\[01\]\",frame=\{addr=\"$hex\",func=\"do_children_tests\",args=\\\[\\\],file=\".*var-cmd.c\",line=\"200\"\}\r\n$mi_gdb_prompt$" { + pass "step at do_children_tests" + } + timeout { + fail "step at do_children_tests (timeout)" + } +} # Test: c_variable-5.7 # Desc: check that long_array[2] changed @@ -824,8 +887,15 @@ mi_gdb_test "-var-update *" \ # struct_declarations.long_array[7] = 8901; # weird->long_array[8] = 9012; # struct_declarations.long_array[9] = 1234; -set line 208 -mi_execute_to "exec-step 7" "end-stepping-range" do_children_tests {} {.*var-cmd.c} $line {} "step $line" +send_gdb "-exec-step 7\n" +gdb_expect { + -re "\\^running\r\n${mi_gdb_prompt}\\*stopped,reason=\"end-stepping-range\",thread-id=\"\[01\]\",frame=\{addr=\"$hex\",func=\"do_children_tests\",args=\\\[\\\],file=\".*var-cmd.c\",line=\"208\"\}\r\n$mi_gdb_prompt$" { + pass "step at do_children_tests" + } + timeout { + fail "step at do_children_tests (timeout)" + } +} # Test: c_variable-5.8 # Desc: check that long_array[3-9] changed @@ -835,8 +905,15 @@ mi_gdb_test "-var-update *" \ # Step over "weird->func_ptr = nothing;" -set line 211 -mi_step_to do_children_tests {} {.*var-cmd.c} $line "step $line" +send_gdb "-exec-step\n" +gdb_expect { + -re "\\^running\r\n${mi_gdb_prompt}\\*stopped,reason=\"end-stepping-range\",thread-id=\"\[01\]\",frame=\{addr=\"$hex\",func=\"do_children_tests\",args=\\\[\\\],file=\".*var-cmd.c\",line=\"211\"\}\r\n$mi_gdb_prompt$" { + pass "step at do_children_tests" + } + timeout { + fail "step at do_children_tests (timeout)" + } +} # Test: c_variable-5.9 # Desc: check that func_ptr changed @@ -856,8 +933,15 @@ mi_gdb_test "-var-delete weird->int_ptr_ptr" \ # Step over all lines: # ... # psnp = &snp0; -set line 254 -mi_execute_to "exec-step 43" "end-stepping-range" do_children_tests {} {.*var-cmd.c} $line {} "step $line" +send_gdb "-exec-step 43\n" +gdb_expect { + -re "\\^running\r\n${mi_gdb_prompt}\\*stopped,reason=\"end-stepping-range\",thread-id=\"\[01\]\",frame=\{addr=\"$hex\",func=\"do_children_tests\",args=\\\[\\\],file=\".*var-cmd.c\",line=\"254\"\}\r\n$mi_gdb_prompt$" { + pass "step at do_children_tests" + } + timeout { + fail "step at do_children_tests (timeout)" + } +} # Test: c_variable-5.10 # Desc: create psnp->char_ptr @@ -1127,8 +1211,15 @@ mi_gdb_test "-var-list-children psnp->ptrs.0.next.next.ptrs" \ "get children of psnp->ptrs.0.next.next.ptrs" # Step over "snp0.char_ptr = &b3;" -set line 255 -mi_step_to do_children_tests {} {.*var-cmd.c} $line "step $line" +send_gdb "-exec-step\n" +gdb_expect { + -re "\\^running\r\n${mi_gdb_prompt}\\*stopped,reason=\"end-stepping-range\",thread-id=\"\[01\]\",frame=\{addr=\"$hex\",func=\"do_children_tests\",args=\\\[\\\],file=\".*var-cmd.c\",line=\"255\"\}\r\n$mi_gdb_prompt$" { + pass "step at do_children_tests" + } + timeout { + fail "step at do_children_tests (timeout)" + } +} # Test: c_variable-5.47 # Desc: check that psnp->char_ptr (and [0].char_ptr) changed @@ -1137,8 +1228,16 @@ mi_gdb_test "-var-update *" \ "update all vars psnp->char_ptr (and 0.char_ptr) changed" # Step over "snp1.char_ptr = &c3;" -set line 256 -mi_step_to do_children_tests {} {.*var-cmd.c} $line "step $line" +send_gdb "-exec-step\n" +gdb_expect { + -re "\\^running\r\n${mi_gdb_prompt}\\*stopped,reason=\"end-stepping-range\",thread-id=\"\[01\]\",frame=\{addr=\"$hex\",func=\"do_children_tests\",args=\\\[\\\],file=\".*var-cmd.c\",line=\"256\"\}\r\n$mi_gdb_prompt$" { + pass "step at do_children_tests" + } + timeout { + fail "step at do_children_tests (timeout)" + } +} + # Test: c_variable-5.48 # Desc: check that psnp->next->char_ptr (and [1].char_ptr) changed @@ -1148,8 +1247,16 @@ mi_gdb_test "-var-update *" \ # Step over "snp2.char_ptr = &a3;" -set line 257 -mi_step_to do_children_tests {} {.*var-cmd.c} $line "step $line" +send_gdb "-exec-step\n" +gdb_expect { + -re "\\^running\r\n${mi_gdb_prompt}\\*stopped,reason=\"end-stepping-range\",thread-id=\"\[01\]\",frame=\{addr=\"$hex\",func=\"do_children_tests\",args=\\\[\\\],file=\".*var-cmd.c\",line=\"257\"\}\r\n$mi_gdb_prompt$" { + pass "step at do_children_tests" + } + timeout { + fail "step at do_children_tests (timeout)" + } +} + # Test: c_variable-5.49 # Desc: check that psnp->next->next->char_ptr (and [2].char_ptr) changed @@ -1159,8 +1266,15 @@ mi_gdb_test "-var-update *" \ # Step over "snp0.long_ptr = &y3;" -set line 258 -mi_step_to do_children_tests {} {.*var-cmd.c} $line "step $line" +send_gdb "-exec-step\n" +gdb_expect { + -re "\\^running\r\n${mi_gdb_prompt}\\*stopped,reason=\"end-stepping-range\",thread-id=\"\[01\]\",frame=\{addr=\"$hex\",func=\"do_children_tests\",args=\\\[\\\],file=\".*var-cmd.c\",line=\"258\"\}\r\n$mi_gdb_prompt$" { + pass "step at do_children_tests" + } + timeout { + fail "step at do_children_tests (timeout)" + } +} # Test: c_variable-5.50 # Desc: check that psnp->long_ptr (and [0].long_ptr) changed @@ -1170,8 +1284,16 @@ mi_gdb_test "-var-update *" \ # Step over "snp1.long_ptr = &x3;" -set line 259 -mi_step_to do_children_tests {} {.*var-cmd.c} $line "step $line" +send_gdb "-exec-step\n" +gdb_expect { + -re "\\^running\r\n${mi_gdb_prompt}\\*stopped,reason=\"end-stepping-range\",thread-id=\"\[01\]\",frame=\{addr=\"$hex\",func=\"do_children_tests\",args=\\\[\\\],file=\".*var-cmd.c\",line=\"259\"\}\r\n$mi_gdb_prompt$" { + pass "step at do_children_tests" + } + timeout { + fail "step at do_children_tests (timeout)" + } +} + # Test: c_variable-5.51 # Desc: check that psnp->next->long_ptr (and [1].long_ptr) changed @@ -1187,8 +1309,16 @@ clear_xfail *-*-* # # Step over "snp2.long_ptr = &z3;" -set line 260 -mi_step_to do_children_tests {} {.*var-cmd.c} $line "step $line" +send_gdb "-exec-step\n" +gdb_expect { + -re "\\^running\r\n${mi_gdb_prompt}\\*stopped,reason=\"end-stepping-range\",thread-id=\"\[01\]\",frame=\{addr=\"$hex\",func=\"do_children_tests\",args=\\\[\\\],file=\".*var-cmd.c\",line=\"260\"\}\r\n$mi_gdb_prompt$" { + pass "step at do_children_tests" + } + timeout { + fail "step at do_children_tests (timeout)" + } +} + # Test: c_variable-5.52 # Desc: check that psnp->next->next->long_ptr (and [2].long_ptr) changed diff --git a/gdb/testsuite/gdb.mi/mi1-var-cmd.exp b/gdb/testsuite/gdb.mi/mi1-var-cmd.exp index c6a88b6bd93..ca98d7e52d6 100644 --- a/gdb/testsuite/gdb.mi/mi1-var-cmd.exp +++ b/gdb/testsuite/gdb.mi/mi1-var-cmd.exp @@ -276,18 +276,6 @@ mi_gdb_test "-var-assign linteger 3333" \ "\\^done,value=\"3333\"" \ "assign to linteger" -mi_gdb_test "-var-update *" \ - "\\^done,changelist=\{name=\"linteger\",in_scope=\"true\",type_changed=\"false\"\}" \ - "update all vars: linteger changed after assign" - -mi_gdb_test "-var-assign linteger 3333" \ - "\\^done,value=\"3333\"" \ - "assign to linteger again, same value" - -mi_gdb_test "-var-update *" \ - "\\^done,changelist=\{\}" \ - "update all vars: linteger not changed after same assign" - mi_gdb_test "-var-evaluate-expression linteger" \ "\\^done,value=\"3333\"" \ "eval linteger" @@ -296,14 +284,6 @@ mi_gdb_test "-var-assign lpinteger \"&linteger + 3\"" \ "\\^done,value=\"$hex\"" \ "assign to lpinteger" -mi_gdb_test "-var-update *" \ - "\\^done,changelist=\{name=\"lpinteger\",in_scope=\"true\",type_changed=\"false\"\}" \ - "update all vars: lpinteger changed after assign" - -mi_gdb_test "-var-update *" \ - "\\^done,changelist=\{\}" \ - "update all vars: no changes for second update" - mi_gdb_test "-var-evaluate-expression lpinteger" \ "\\^done,value=\"$hex\"" \ "eval lpinteger" @@ -527,34 +507,5 @@ mi_gdb_test "-var-delete l" \ "\\^done,ndeleted=\"1\"" \ "delete var l" -# Test whether we can follow the name of a variable through multiple -# stack frames. -mi_gdb_test "-break-insert do_special_tests" \ - {\^done,bkpt=.*} \ - "set breakpoint at do_special_tests" - -mi_continue_to {.*} do_special_tests {.*} {.*var-cmd.c} {.*} {stop in do_special_tests} - -mi_gdb_test "-var-create selected_a @ a" \ - {\^done,name="selected_a",numchild="0",type="int"} \ - "create selected_a" - -mi_gdb_test "-break-insert incr_a" \ - {\^done,bkpt=.*} \ - "set breakpoint at incr_a" - -mi_continue_to {.*} incr_a {.*} {.*var-cmd.c} {.*} {stop in incr_a} - -mi_gdb_test "-var-update selected_a" \ - {\^done,changelist=\{name="selected_a",in_scope="true",new_type="char",new_num_children="0"\}} \ - "update selected_a in incr_a" - -mi_next "step a line in incr_a" -mi_next "return from incr_a to do_special_tests" - -mi_gdb_test "-var-update selected_a" \ - {\^done,changelist=\{name="selected_a",in_scope="true",new_type="int",new_num_children="0"\}} \ - "update selected_a in do_special_tests" - mi_gdb_exit return 0 diff --git a/gdb/testsuite/gdb.mi/mi1-var-display.exp b/gdb/testsuite/gdb.mi/mi1-var-display.exp index 0bdaee44ae4..a2873dac99d 100644 --- a/gdb/testsuite/gdb.mi/mi1-var-display.exp +++ b/gdb/testsuite/gdb.mi/mi1-var-display.exp @@ -1,4 +1,4 @@ -# Copyright (C) 1999, 2000, 2002 Free Software Foundation, Inc. +# Copyright 2002 Free Software Foundation, Inc. # # This Program Is Free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by diff --git a/gdb/testsuite/lib/mi-support.exp b/gdb/testsuite/lib/mi-support.exp index 4b057d49623..f7eb2652e4f 100644 --- a/gdb/testsuite/lib/mi-support.exp +++ b/gdb/testsuite/lib/mi-support.exp @@ -127,22 +127,22 @@ proc mi_gdb_start { } { # We have a new format mi startup prompt. If we are # running mi1, then this is an error as we should be # using the old-style prompt. - if { $MIFLAGS == "-i=mi1" } { - perror "(mi startup) Got unexpected new mi prompt." - remote_close host; - return -1; - } +# if { $MIFLAGS == "-i=mi1" } { +# perror "(mi startup) Got unexpected new mi prompt." +# remote_close host; +# return -1; +# } verbose "GDB initialized." } -re "\[^~\].*$mi_gdb_prompt$" { # We have an old format mi startup prompt. If we are # not running mi1, then this is an error as we should be # using the new-style prompt. - if { $MIFLAGS != "-i=mi1" } { - perror "(mi startup) Got unexpected old mi prompt." - remote_close host; - return -1; - } +# if { $MIFLAGS != "-i=mi1" } { +# perror "(mi startup) Got unexpected old mi prompt." +# remote_close host; +# return -1; +# } verbose "GDB initialized." } -re ".*$gdb_prompt $" { @@ -209,7 +209,7 @@ proc mi_delete_breakpoints {} { send_gdb "y\n"; exp_continue } - -re ".*102-break-delete\r\n102\\\^done\r\n$mi_gdb_prompt$" { + -re ".*102-break-delete\r\n(=.*)*102\\\^done\r\n$mi_gdb_prompt$" { # This happens if there were no breakpoints } timeout { perror "Delete all breakpoints in mi_delete_breakpoints (timeout)" ; return } @@ -711,7 +711,7 @@ proc mi_runto {func} { set test "mi runto $func" mi_gdb_test "200-break-insert $func" \ - "200\\^done,bkpt=\{number=\"\[0-9\]+\",type=\"breakpoint\",disp=\"keep\",enabled=\"y\",addr=\"$hex\",func=\"$func\",file=\".*\",line=\"\[0-9\]*\",times=\"0\"\}" \ + "\(=breakpoint-create,number=\"\[0-9\]+\")\r\n200\\^done" \ "breakpoint at $func" if {![regexp {number="[0-9]+"} $expect_out(buffer) str] diff --git a/gdb/thread.c b/gdb/thread.c index f36def1f279..50d5b563a3a 100644 --- a/gdb/thread.c +++ b/gdb/thread.c @@ -261,11 +261,12 @@ do_captured_list_thread_ids (struct ui_out *uiout, { struct thread_info *tp; int num = 0; + struct cleanup *cleanup_chain; prune_threads (); target_find_new_threads (); - ui_out_tuple_begin (uiout, "thread-ids"); + cleanup_chain = make_cleanup_ui_out_tuple_begin_end (uiout, "thread-ids"); for (tp = thread_list; tp; tp = tp->next) { @@ -273,7 +274,7 @@ do_captured_list_thread_ids (struct ui_out *uiout, ui_out_field_int (uiout, "thread-id", tp->num); } - ui_out_tuple_end (uiout); + do_cleanups (cleanup_chain); ui_out_field_int (uiout, "number-of-threads", num); return GDB_RC_OK; } @@ -693,10 +694,12 @@ do_captured_thread_select (struct ui_out *uiout, void *tidstr) { int num; + ptid_t old_ptid; struct thread_info *tp; num = value_as_long (parse_and_eval (tidstr)); + old_ptid = inferior_ptid; tp = find_thread_id (num); if (!tp) @@ -719,6 +722,10 @@ do_captured_thread_select (struct ui_out *uiout, print_stack_frame (deprecated_selected_frame, frame_relative_level (deprecated_selected_frame), 1); + + if (!ptid_equal (old_ptid, inferior_ptid)) + selected_thread_changed_event (pid_to_thread_id (inferior_ptid)); + return GDB_RC_OK; } diff --git a/gdb/top.c b/gdb/top.c index dcffb051436..d93a98db193 100644 --- a/gdb/top.c +++ b/gdb/top.c @@ -63,6 +63,7 @@ #include #include "ui-out.h" #include "cli-out.h" +#include "interps.h" /* Default command line prompt. This is overriden in some configs. */ @@ -2126,17 +2127,30 @@ gdb_init (char *argv0) init_ui_hook (argv0); /* Install the default UI */ - if (!init_ui_hook) - { - uiout = cli_out_new (gdb_stdout); + /* All the interpreters should have had a look at things by now. + Initialize the selected interpreter. */ + { - /* All the interpreters should have had a look at things by now. - Initialize the selected interpreter. */ - if (interpreter_p) - { - fprintf_unfiltered (gdb_stderr, "Interpreter `%s' unrecognized.\n", - interpreter_p); - exit (1); - } - } + /* There will always be an interpreter. Either the one specified + by the user at start up or the console. */ + + struct gdb_interpreter *interp; + if (interpreter_p == NULL) + interpreter_p = xstrdup (GDB_INTERPRETER_CONSOLE); + + interp = gdb_interpreter_lookup (interpreter_p); + + if (interp == NULL) + { + fprintf_unfiltered (gdb_stderr, "Interpreter `%s' unrecognized.\n", + interpreter_p); + exit (1); + } + if (!gdb_interpreter_set (interp)) + { + fprintf_unfiltered (gdb_stderr, "Interpreter `%s' failed to initialize.\n", + interpreter_p); + exit (1); + } + } } diff --git a/gdb/ui-out.c b/gdb/ui-out.c index d98cf167e85..ed32da3ded8 100644 --- a/gdb/ui-out.c +++ b/gdb/ui-out.c @@ -273,7 +273,7 @@ static void init_ui_out_state (struct ui_out *uiout); /* Mark beginning of a table */ -void +static void ui_out_table_begin (struct ui_out *uiout, int nbrofcols, int nr_rows, const char *tblid) @@ -318,7 +318,7 @@ columns."); uo_table_body (uiout); } -void +static void ui_out_table_end (struct ui_out *uiout) { if (!uiout->table.flag) @@ -351,6 +351,22 @@ and before table_body."); uo_table_header (uiout, width, alignment, col_name, colhdr); } +static void +do_cleanup_table_end (void *data) +{ + struct ui_out *ui_out = data; + + ui_out_table_end (ui_out); +} + +struct cleanup * +make_cleanup_ui_out_table_begin_end (struct ui_out *ui_out, int nr_cols, + int nr_rows, const char *tblid) +{ + ui_out_table_begin (ui_out, nr_cols, nr_rows, tblid); + return make_cleanup (do_cleanup_table_end, ui_out); +} + void ui_out_begin (struct ui_out *uiout, enum ui_out_type type, @@ -387,19 +403,6 @@ specified after table_body."); uo_begin (uiout, type, new_level, id); } -void -ui_out_list_begin (struct ui_out *uiout, - const char *id) -{ - ui_out_begin (uiout, ui_out_type_list, id); -} - -void -ui_out_tuple_begin (struct ui_out *uiout, const char *id) -{ - ui_out_begin (uiout, ui_out_type_tuple, id); -} - void ui_out_end (struct ui_out *uiout, enum ui_out_type type) @@ -408,18 +411,6 @@ ui_out_end (struct ui_out *uiout, uo_end (uiout, type, old_level); } -void -ui_out_list_end (struct ui_out *uiout) -{ - ui_out_end (uiout, ui_out_type_list); -} - -void -ui_out_tuple_end (struct ui_out *uiout) -{ - ui_out_end (uiout, ui_out_type_tuple); -} - struct ui_out_end_cleanup_data { struct ui_out *uiout; @@ -458,7 +449,7 @@ struct cleanup * make_cleanup_ui_out_tuple_begin_end (struct ui_out *uiout, const char *id) { - ui_out_tuple_begin (uiout, id); + ui_out_begin (uiout, ui_out_type_tuple, id); return make_cleanup_ui_out_end (uiout, ui_out_type_tuple); } @@ -466,7 +457,7 @@ struct cleanup * make_cleanup_ui_out_list_begin_end (struct ui_out *uiout, const char *id) { - ui_out_list_begin (uiout, id); + ui_out_begin (uiout, ui_out_type_list, id); return make_cleanup_ui_out_end (uiout, ui_out_type_list); } diff --git a/gdb/ui-out.h b/gdb/ui-out.h index c8ed9dd504e..a52c3453722 100644 --- a/gdb/ui-out.h +++ b/gdb/ui-out.h @@ -88,31 +88,21 @@ extern struct cleanup *ui_out_begin_cleanup_end (struct ui_out *uiout, implied structure: ``table = { hdr = { header, ... } , body = [ { field, ... }, ... ] }''. If NR_ROWS is negative then there is at least one row. */ - -extern void ui_out_table_begin (struct ui_out *uiout, int nbrofcols, - int nr_rows, const char *tblid); - extern void ui_out_table_header (struct ui_out *uiout, int width, enum ui_align align, const char *col_name, const char *colhdr); extern void ui_out_table_body (struct ui_out *uiout); -extern void ui_out_table_end (struct ui_out *uiout); - +extern struct cleanup *make_cleanup_ui_out_table_begin_end (struct ui_out *ui_out, + int nr_cols, + int nr_rows, + const char *tblid); /* Compatibility wrappers. */ -extern void ui_out_list_begin (struct ui_out *uiout, const char *id); - -extern void ui_out_list_end (struct ui_out *uiout); - extern struct cleanup *make_cleanup_ui_out_list_begin_end (struct ui_out *uiout, const char *id); -extern void ui_out_tuple_begin (struct ui_out *uiout, const char *id); - -extern void ui_out_tuple_end (struct ui_out *uiout); - extern struct cleanup *make_cleanup_ui_out_tuple_begin_end (struct ui_out *uiout, const char *id); diff --git a/gdb/valops.c b/gdb/valops.c index 2304274c2bb..22c97c723ff 100644 --- a/gdb/valops.c +++ b/gdb/valops.c @@ -727,6 +727,8 @@ value_assign (struct value *toval, struct value *fromval) error ("Attempt to assign to an unmodifiable value."); } + if (regno > VALUE_FRAME_REGNUM (toval) + reg_offset) + regno = -1; if (register_changed_hook) register_changed_hook (-1); target_changed_event (); diff --git a/gdb/version.in b/gdb/version.in index 9e082a07492..dbeb39b31c4 100644 --- a/gdb/version.in +++ b/gdb/version.in @@ -1 +1 @@ -2003-02-02-cvs +2003-02-03-cvs diff --git a/gdb/wrapper.c b/gdb/wrapper.c index 6c9c6d60cef..e57f19a49cb 100644 --- a/gdb/wrapper.c +++ b/gdb/wrapper.c @@ -20,7 +20,7 @@ #include "value.h" #include "wrapper.h" -/* Use this struct to pass arguments to wrapper routines. We assume +/* use this struct to pass arguments to wrapper routines. We assume (arbitrarily) that no gdb function takes more than ten arguments. */ struct gdb_wrapper_arguments { @@ -330,4 +330,3 @@ do_captured_value_struct_elt (struct ui_out *uiout, void *data) cargs->static_memfuncp, cargs->err); return GDB_RC_OK; } - diff --git a/gdb/wrapper.h b/gdb/wrapper.h index 977a77d04cd..99c1e1672f7 100644 --- a/gdb/wrapper.h +++ b/gdb/wrapper.h @@ -21,6 +21,10 @@ #include "gdb.h" struct value; +struct block; +struct expression; +struct ui_out; +struct type; /* Use this struct to pass arguments to wrapper routines. */ struct gdb_wrapper_arguments; @@ -45,5 +49,4 @@ extern enum gdb_rc gdb_value_struct_elt (struct ui_out *uiout, struct value **re extern int gdb_value_ind (struct value *val, struct value ** rval); extern int gdb_parse_and_eval_type (char *, int, struct type **); - #endif /* WRAPPER_H */