binutils-gdb/gdb/cli/cli-interp.c

250 lines
6.4 KiB
C
Raw Normal View History

2003-02-06 06:30:17 +01:00
/* CLI Definitions for GDB, the GNU debugger.
Copyright (C) 2002-2015 Free Software Foundation, Inc.
2003-02-06 06:30:17 +01:00
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 3 of the License, or
2003-02-06 06:30:17 +01:00
(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, see <http://www.gnu.org/licenses/>. */
2003-02-06 06:30:17 +01:00
#include "defs.h"
#include "interps.h"
#include "event-top.h"
#include "ui-out.h"
#include "cli-out.h"
#include "top.h" /* for "execute_command" */
PR gdb/13860 - Make MI sync vs async output (closer to) the same. Ignoring expected and desired differences like whether the prompt is output after *stoppped records, GDB MI output is still different in sync and async modes. In sync mode, when a CLI execution command is entered, the "reason" field is missing in the *stopped async record. And in async mode, for some events, like program exits, the corresponding CLI output is missing in the CLI channel. Vis, diff between sync vs async modes: run ^running *running,thread-id="1" (gdb) ... - ~"[Inferior 1 (process 15882) exited normally]\n" =thread-exited,id="1",group-id="i1" =thread-group-exited,id="i1",exit-code="0" - *stopped + *stopped,reason="exited-normally" si ... (gdb) ~"0x000000000045e033\t29\t memset (&args, 0, sizeof args);\n" - *stopped,frame=...,thread-id="1",stopped-threads="all",core="0" + *stopped,reason="end-stepping-range",frame=...,thread-id="1",stopped-threads="all",core="0" (gdb) In addition, in both cases, when a MI execution command is entered, and a breakpoint triggers, the event is sent to the console too. But some events like program exits have the CLI output missing in the CLI channel: -exec-run ^running *running,thread-id="1" (gdb) ... =thread-exited,id="1",group-id="i1" =thread-group-exited,id="i1",exit-code="0" - *stopped + *stopped,reason="exited-normally" We'll want to make background commands always possible by default. IOW, make target-async be the default. But, in order to do that, we'll need to emulate MI sync on top of an async target. That means we'll have yet another combination to care for in the testsuite. Rather than making the testsuite cope with all these differences, I thought it better to just fix GDB to always have the complete output, no matter whether it's in sync or async mode. This is all related to interpreter-exec, and the corresponding uiout switching. (Typing a CLI command directly in MI is shorthand for running it through -interpreter-exec console.) In sync mode, when a CLI command is active, normal_stop is called when the current interpreter and uiout are CLI's. So print_XXX_reason prints the stop reason to CLI uiout (only), and we don't show it in MI. In async mode the stop event is processed when we're back in the MI interpreter, so the stop reason is printed directly to the MI uiout. Fix this by making run control event printing roughly independent of whatever is the current interpreter or uiout. That is, move these prints to interpreter observers, that know whether to print or be quiet, and if printing, which uiout to print to. In the case of the console/tui interpreters, only print if the top interpreter. For MI, always print. Breakpoint hits / normal stops are already handled similarly -- MI has a normal_stop observer that prints the event to both MI and the CLI, though that could be cleaned up further in the direction of this patch. This also makes all of: (gdb) foo and (gdb) interpreter-exec MI "-exec-foo" and (gdb) -exec-foo and (gdb) -interpreter-exec console "foo" print as expected. Tested on x86_64 Fedora 20, sync and async modes. gdb/ 2014-05-29 Pedro Alves <palves@redhat.com> PR gdb/13860 * cli/cli-interp.c: Include infrun.h and observer.h. (cli_uiout, cli_interp): New globals. (cli_on_signal_received, cli_on_end_stepping_range) (cli_on_signal_exited, cli_on_exited, cli_on_no_history): New functions. (cli_interpreter_init): Install them as 'end_stepping_range', 'signal_received' 'signal_exited', 'exited' and 'no_history' observers. (_initialize_cli_interp): Remove cli_interp local. * infrun.c (handle_inferior_event): Call the several stop reason observers instead of printing the stop reason directly. (end_stepping_range): New function. (print_end_stepping_range_reason, print_signal_exited_reason) (print_exited_reason, print_signal_received_reason) (print_no_history_reason): Make static, and add an uiout parameter. Print to that instead of to CURRENT_UIOUT. * infrun.h (print_end_stepping_range_reason) (print_signal_exited_reason, print_exited_reason) (print_signal_received_reason print_no_history_reason): New declarations. * mi/mi-common.h (struct mi_interp): Rename 'uiout' field to 'mi_uiout'. <cli_uiout>: New field. * mi/mi-interp.c (mi_interpreter_init): Adjust. Create the new uiout for CLI output. Install 'signal_received', 'end_stepping_range', 'signal_exited', 'exited' and 'no_history' observers. (find_mi_interpreter, mi_interp_data, mi_on_signal_received) (mi_on_end_stepping_range, mi_on_signal_exited, mi_on_exited) (mi_on_no_history): New functions. (ui_out_free_cleanup): Delete function. (mi_on_normal_stop): Don't allocate a new uiout for CLI output, instead use the one already stored in the MI interpreter data. (mi_ui_out): Adjust. * tui/tui-interp.c: Include infrun.h and observer.h. (tui_interp): New global. (tui_on_signal_received, tui_on_end_stepping_range) (tui_on_signal_exited, tui_on_exited) (tui_on_no_history): New functions. (tui_init): Install them as 'end_stepping_range', 'signal_received' 'signal_exited', 'exited' and 'no_history' observers. (_initialize_tui_interp): Delete tui_interp local. gdb/doc/ 2014-05-29 Pedro Alves <palves@redhat.com> PR gdb/13860 * observer.texi (signal_received, end_stepping_range) (signal_exited, exited, no_history): New observer subjects. gdb/testsuite/ 2014-05-29 Pedro Alves <palves@redhat.com> PR gdb/13860 * gdb.mi/mi-cli.exp: Always expect "end-stepping-range" stop reason, even in sync mode.
2014-05-29 14:09:45 +02:00
#include "infrun.h"
#include "observer.h"
2003-02-06 06:30:17 +01:00
/* These are the ui_out and the interpreter for the console
interpreter. */
PR gdb/13860 - Make MI sync vs async output (closer to) the same. Ignoring expected and desired differences like whether the prompt is output after *stoppped records, GDB MI output is still different in sync and async modes. In sync mode, when a CLI execution command is entered, the "reason" field is missing in the *stopped async record. And in async mode, for some events, like program exits, the corresponding CLI output is missing in the CLI channel. Vis, diff between sync vs async modes: run ^running *running,thread-id="1" (gdb) ... - ~"[Inferior 1 (process 15882) exited normally]\n" =thread-exited,id="1",group-id="i1" =thread-group-exited,id="i1",exit-code="0" - *stopped + *stopped,reason="exited-normally" si ... (gdb) ~"0x000000000045e033\t29\t memset (&args, 0, sizeof args);\n" - *stopped,frame=...,thread-id="1",stopped-threads="all",core="0" + *stopped,reason="end-stepping-range",frame=...,thread-id="1",stopped-threads="all",core="0" (gdb) In addition, in both cases, when a MI execution command is entered, and a breakpoint triggers, the event is sent to the console too. But some events like program exits have the CLI output missing in the CLI channel: -exec-run ^running *running,thread-id="1" (gdb) ... =thread-exited,id="1",group-id="i1" =thread-group-exited,id="i1",exit-code="0" - *stopped + *stopped,reason="exited-normally" We'll want to make background commands always possible by default. IOW, make target-async be the default. But, in order to do that, we'll need to emulate MI sync on top of an async target. That means we'll have yet another combination to care for in the testsuite. Rather than making the testsuite cope with all these differences, I thought it better to just fix GDB to always have the complete output, no matter whether it's in sync or async mode. This is all related to interpreter-exec, and the corresponding uiout switching. (Typing a CLI command directly in MI is shorthand for running it through -interpreter-exec console.) In sync mode, when a CLI command is active, normal_stop is called when the current interpreter and uiout are CLI's. So print_XXX_reason prints the stop reason to CLI uiout (only), and we don't show it in MI. In async mode the stop event is processed when we're back in the MI interpreter, so the stop reason is printed directly to the MI uiout. Fix this by making run control event printing roughly independent of whatever is the current interpreter or uiout. That is, move these prints to interpreter observers, that know whether to print or be quiet, and if printing, which uiout to print to. In the case of the console/tui interpreters, only print if the top interpreter. For MI, always print. Breakpoint hits / normal stops are already handled similarly -- MI has a normal_stop observer that prints the event to both MI and the CLI, though that could be cleaned up further in the direction of this patch. This also makes all of: (gdb) foo and (gdb) interpreter-exec MI "-exec-foo" and (gdb) -exec-foo and (gdb) -interpreter-exec console "foo" print as expected. Tested on x86_64 Fedora 20, sync and async modes. gdb/ 2014-05-29 Pedro Alves <palves@redhat.com> PR gdb/13860 * cli/cli-interp.c: Include infrun.h and observer.h. (cli_uiout, cli_interp): New globals. (cli_on_signal_received, cli_on_end_stepping_range) (cli_on_signal_exited, cli_on_exited, cli_on_no_history): New functions. (cli_interpreter_init): Install them as 'end_stepping_range', 'signal_received' 'signal_exited', 'exited' and 'no_history' observers. (_initialize_cli_interp): Remove cli_interp local. * infrun.c (handle_inferior_event): Call the several stop reason observers instead of printing the stop reason directly. (end_stepping_range): New function. (print_end_stepping_range_reason, print_signal_exited_reason) (print_exited_reason, print_signal_received_reason) (print_no_history_reason): Make static, and add an uiout parameter. Print to that instead of to CURRENT_UIOUT. * infrun.h (print_end_stepping_range_reason) (print_signal_exited_reason, print_exited_reason) (print_signal_received_reason print_no_history_reason): New declarations. * mi/mi-common.h (struct mi_interp): Rename 'uiout' field to 'mi_uiout'. <cli_uiout>: New field. * mi/mi-interp.c (mi_interpreter_init): Adjust. Create the new uiout for CLI output. Install 'signal_received', 'end_stepping_range', 'signal_exited', 'exited' and 'no_history' observers. (find_mi_interpreter, mi_interp_data, mi_on_signal_received) (mi_on_end_stepping_range, mi_on_signal_exited, mi_on_exited) (mi_on_no_history): New functions. (ui_out_free_cleanup): Delete function. (mi_on_normal_stop): Don't allocate a new uiout for CLI output, instead use the one already stored in the MI interpreter data. (mi_ui_out): Adjust. * tui/tui-interp.c: Include infrun.h and observer.h. (tui_interp): New global. (tui_on_signal_received, tui_on_end_stepping_range) (tui_on_signal_exited, tui_on_exited) (tui_on_no_history): New functions. (tui_init): Install them as 'end_stepping_range', 'signal_received' 'signal_exited', 'exited' and 'no_history' observers. (_initialize_tui_interp): Delete tui_interp local. gdb/doc/ 2014-05-29 Pedro Alves <palves@redhat.com> PR gdb/13860 * observer.texi (signal_received, end_stepping_range) (signal_exited, exited, no_history): New observer subjects. gdb/testsuite/ 2014-05-29 Pedro Alves <palves@redhat.com> PR gdb/13860 * gdb.mi/mi-cli.exp: Always expect "end-stepping-range" stop reason, even in sync mode.
2014-05-29 14:09:45 +02:00
struct ui_out *cli_uiout;
static struct interp *cli_interp;
2003-02-06 06:30:17 +01:00
/* Longjmp-safe wrapper for "execute_command". */
static struct gdb_exception safe_execute_command (struct ui_out *uiout,
char *command,
int from_tty);
PR gdb/13860 - Make MI sync vs async output (closer to) the same. Ignoring expected and desired differences like whether the prompt is output after *stoppped records, GDB MI output is still different in sync and async modes. In sync mode, when a CLI execution command is entered, the "reason" field is missing in the *stopped async record. And in async mode, for some events, like program exits, the corresponding CLI output is missing in the CLI channel. Vis, diff between sync vs async modes: run ^running *running,thread-id="1" (gdb) ... - ~"[Inferior 1 (process 15882) exited normally]\n" =thread-exited,id="1",group-id="i1" =thread-group-exited,id="i1",exit-code="0" - *stopped + *stopped,reason="exited-normally" si ... (gdb) ~"0x000000000045e033\t29\t memset (&args, 0, sizeof args);\n" - *stopped,frame=...,thread-id="1",stopped-threads="all",core="0" + *stopped,reason="end-stepping-range",frame=...,thread-id="1",stopped-threads="all",core="0" (gdb) In addition, in both cases, when a MI execution command is entered, and a breakpoint triggers, the event is sent to the console too. But some events like program exits have the CLI output missing in the CLI channel: -exec-run ^running *running,thread-id="1" (gdb) ... =thread-exited,id="1",group-id="i1" =thread-group-exited,id="i1",exit-code="0" - *stopped + *stopped,reason="exited-normally" We'll want to make background commands always possible by default. IOW, make target-async be the default. But, in order to do that, we'll need to emulate MI sync on top of an async target. That means we'll have yet another combination to care for in the testsuite. Rather than making the testsuite cope with all these differences, I thought it better to just fix GDB to always have the complete output, no matter whether it's in sync or async mode. This is all related to interpreter-exec, and the corresponding uiout switching. (Typing a CLI command directly in MI is shorthand for running it through -interpreter-exec console.) In sync mode, when a CLI command is active, normal_stop is called when the current interpreter and uiout are CLI's. So print_XXX_reason prints the stop reason to CLI uiout (only), and we don't show it in MI. In async mode the stop event is processed when we're back in the MI interpreter, so the stop reason is printed directly to the MI uiout. Fix this by making run control event printing roughly independent of whatever is the current interpreter or uiout. That is, move these prints to interpreter observers, that know whether to print or be quiet, and if printing, which uiout to print to. In the case of the console/tui interpreters, only print if the top interpreter. For MI, always print. Breakpoint hits / normal stops are already handled similarly -- MI has a normal_stop observer that prints the event to both MI and the CLI, though that could be cleaned up further in the direction of this patch. This also makes all of: (gdb) foo and (gdb) interpreter-exec MI "-exec-foo" and (gdb) -exec-foo and (gdb) -interpreter-exec console "foo" print as expected. Tested on x86_64 Fedora 20, sync and async modes. gdb/ 2014-05-29 Pedro Alves <palves@redhat.com> PR gdb/13860 * cli/cli-interp.c: Include infrun.h and observer.h. (cli_uiout, cli_interp): New globals. (cli_on_signal_received, cli_on_end_stepping_range) (cli_on_signal_exited, cli_on_exited, cli_on_no_history): New functions. (cli_interpreter_init): Install them as 'end_stepping_range', 'signal_received' 'signal_exited', 'exited' and 'no_history' observers. (_initialize_cli_interp): Remove cli_interp local. * infrun.c (handle_inferior_event): Call the several stop reason observers instead of printing the stop reason directly. (end_stepping_range): New function. (print_end_stepping_range_reason, print_signal_exited_reason) (print_exited_reason, print_signal_received_reason) (print_no_history_reason): Make static, and add an uiout parameter. Print to that instead of to CURRENT_UIOUT. * infrun.h (print_end_stepping_range_reason) (print_signal_exited_reason, print_exited_reason) (print_signal_received_reason print_no_history_reason): New declarations. * mi/mi-common.h (struct mi_interp): Rename 'uiout' field to 'mi_uiout'. <cli_uiout>: New field. * mi/mi-interp.c (mi_interpreter_init): Adjust. Create the new uiout for CLI output. Install 'signal_received', 'end_stepping_range', 'signal_exited', 'exited' and 'no_history' observers. (find_mi_interpreter, mi_interp_data, mi_on_signal_received) (mi_on_end_stepping_range, mi_on_signal_exited, mi_on_exited) (mi_on_no_history): New functions. (ui_out_free_cleanup): Delete function. (mi_on_normal_stop): Don't allocate a new uiout for CLI output, instead use the one already stored in the MI interpreter data. (mi_ui_out): Adjust. * tui/tui-interp.c: Include infrun.h and observer.h. (tui_interp): New global. (tui_on_signal_received, tui_on_end_stepping_range) (tui_on_signal_exited, tui_on_exited) (tui_on_no_history): New functions. (tui_init): Install them as 'end_stepping_range', 'signal_received' 'signal_exited', 'exited' and 'no_history' observers. (_initialize_tui_interp): Delete tui_interp local. gdb/doc/ 2014-05-29 Pedro Alves <palves@redhat.com> PR gdb/13860 * observer.texi (signal_received, end_stepping_range) (signal_exited, exited, no_history): New observer subjects. gdb/testsuite/ 2014-05-29 Pedro Alves <palves@redhat.com> PR gdb/13860 * gdb.mi/mi-cli.exp: Always expect "end-stepping-range" stop reason, even in sync mode.
2014-05-29 14:09:45 +02:00
/* Observers for several run control events. If the interpreter is
quiet (i.e., another interpreter is being run with
interpreter-exec), print nothing. */
Replace "struct continuation" mechanism by something more extensible This adds an object oriented replacement for the "struct continuation" mechanism, and converts the stepping commands (step, next, stepi, nexti) and the "finish" commands to use it. It adds a new thread "class" (struct thread_fsm) that contains the necessary info and callbacks to manage the state machine of a thread's execution command. This allows getting rid of some hacks. E.g., in fetch_inferior_event and normal_stop we no longer need to know whether a thread is doing a multi-step (e.g., step N). This effectively makes the intermediate_continuations unused -- they'll be garbage collected in a separate patch. (They were never a proper abstraction, IMO. See how fetch_inferior_event needs to check step_multi before knowing whether to call INF_EXEC_CONTINUE or INF_EXEC_COMPLETE.) The target async vs !async uiout hacks in mi_on_normal_stop go away too. print_stop_event is no longer called from normal_stop. Instead it is now called from within each interpreter's normal_stop observer. This clears the path to make each interpreter print a stop event the way it sees fit. Currently we have some hacks in common code to differenciate CLI vs TUI vs MI around this area. The "finish" command's FSM class stores the return value plus that value's position in the value history, so that those can be printed to both MI and CLI's streams. This fixes the CLI "finish" command when run from MI -- it now also includes the function's return value in the CLI stream: (gdb) ~"callee3 (strarg=0x400730 \"A string argument.\") at src/gdb/testsuite/gdb.mi/basics.c:35\n" ~"35\t}\n" +~"Value returned is $1 = 0\n" *stopped,reason="function-finished",frame=...,gdb-result-var="$1",return-value="0",thread-id="1",stopped-threads="all",core="0" -FAIL: gdb.mi/mi-cli.exp: CLI finish: check CLI output +PASS: gdb.mi/mi-cli.exp: CLI finish: check CLI output gdb/ChangeLog: 2015-09-09 Pedro Alves <palves@redhat.com> * Makefile.in (COMMON_OBS): Add thread-fsm.o. * breakpoint.c (handle_jit_event): Print debug output. (bpstat_what): Split event callback handling to ... (bpstat_run_callbacks): ... this new function. (momentary_bkpt_print_it): No longer handle bp_finish here. * breakpoint.h (bpstat_run_callbacks): Declare. * gdbthread.h (struct thread_info) <step_multi>: Delete field. <thread_fsm>: New field. (thread_cancel_execution_command): Declare. * infcmd.c: Include thread-fsm.h. (struct step_command_fsm): New. (step_command_fsm_ops): New global. (new_step_command_fsm, step_command_fsm_prepare): New functions. (step_1): Adjust to use step_command_fsm_prepare and prepare_one_step. (struct step_1_continuation_args): Delete. (step_1_continuation): Delete. (step_command_fsm_should_stop): New function. (step_once): Delete. (step_command_fsm_clean_up, step_command_fsm_async_reply_reason) (prepare_one_step): New function, based on step_once. (until_next_command): Remove step_multi reference. (struct return_value_info): New. (print_return_value): Rename to ... (print_return_value_1): ... this. New struct return_value_info parameter. Adjust. (print_return_value): Reimplement as wrapper around print_return_value_1. (struct finish_command_fsm): New. (finish_command_continuation): Delete. (finish_command_fsm_ops): New global. (new_finish_command_fsm, finish_command_fsm_should_stop): New functions. (finish_command_fsm_clean_up, finish_command_fsm_return_value): New. (finish_command_continuation_free_arg): Delete. (finish_command_fsm_async_reply_reason): New. (finish_backward, finish_forward): Change symbol parameter to a finish_command_fsm. Adjust. (finish_command): Create a finish_command_fsm. Adjust. * infrun.c: Include "thread-fsm.h". (clear_proceed_status_thread): Delete the thread's FSM. (infrun_thread_stop_requested_callback): Cancel the thread's execution command. (clean_up_just_stopped_threads_fsms): New function. (fetch_inferior_event): Handle the event_thread's should_stop method saying the command isn't done yet. (process_event_stop_test): Run breakpoint callbacks here. (print_stop_event): Rename to ... (print_stop_location): ... this. (restore_current_uiout_cleanup): New function. (print_stop_event): Reimplement. (normal_stop): No longer notify the end_stepping_range observers here handle "step N" nor "finish" here. No longer call print_stop_event here. * infrun.h (struct return_value_info): Forward declare. (print_return_value): Declare. (print_stop_event): Change prototype. * thread-fsm.c: New file. * thread-fsm.h: New file. * thread.c: Include "thread-fsm.h". (thread_cancel_execution_command): New function. (clear_thread_inferior_resources): Call it. * cli/cli-interp.c (cli_on_normal_stop): New function. (cli_interpreter_init): Install cli_on_normal_stop as normal_stop observer. * mi/mi-interp.c: Include "thread-fsm.h". (restore_current_uiout_cleanup): Delete. (mi_on_normal_stop): If the thread has an FSM associated, and it finished, ask it for the async-reply-reason to print. Always call print_stop_event here, regardless of the top-level interpreter. Check bpstat_what to tell whether an asynchronous breakpoint hit triggered. * tui/tui-interp.c (tui_on_normal_stop): New function. (tui_init): Install tui_on_normal_stop as normal_stop observer. gdb/testsuite/ChangeLog: 2015-09-09 Pedro Alves <palves@redhat.com> * gdb.mi/mi-cli.exp: Add CLI finish tests.
2015-09-09 19:23:24 +02:00
/* Observer for the normal_stop notification. */
static void
cli_on_normal_stop (struct bpstats *bs, int print_frame)
{
if (!interp_quiet_p (cli_interp))
{
if (print_frame)
print_stop_event (cli_uiout);
}
}
PR gdb/13860 - Make MI sync vs async output (closer to) the same. Ignoring expected and desired differences like whether the prompt is output after *stoppped records, GDB MI output is still different in sync and async modes. In sync mode, when a CLI execution command is entered, the "reason" field is missing in the *stopped async record. And in async mode, for some events, like program exits, the corresponding CLI output is missing in the CLI channel. Vis, diff between sync vs async modes: run ^running *running,thread-id="1" (gdb) ... - ~"[Inferior 1 (process 15882) exited normally]\n" =thread-exited,id="1",group-id="i1" =thread-group-exited,id="i1",exit-code="0" - *stopped + *stopped,reason="exited-normally" si ... (gdb) ~"0x000000000045e033\t29\t memset (&args, 0, sizeof args);\n" - *stopped,frame=...,thread-id="1",stopped-threads="all",core="0" + *stopped,reason="end-stepping-range",frame=...,thread-id="1",stopped-threads="all",core="0" (gdb) In addition, in both cases, when a MI execution command is entered, and a breakpoint triggers, the event is sent to the console too. But some events like program exits have the CLI output missing in the CLI channel: -exec-run ^running *running,thread-id="1" (gdb) ... =thread-exited,id="1",group-id="i1" =thread-group-exited,id="i1",exit-code="0" - *stopped + *stopped,reason="exited-normally" We'll want to make background commands always possible by default. IOW, make target-async be the default. But, in order to do that, we'll need to emulate MI sync on top of an async target. That means we'll have yet another combination to care for in the testsuite. Rather than making the testsuite cope with all these differences, I thought it better to just fix GDB to always have the complete output, no matter whether it's in sync or async mode. This is all related to interpreter-exec, and the corresponding uiout switching. (Typing a CLI command directly in MI is shorthand for running it through -interpreter-exec console.) In sync mode, when a CLI command is active, normal_stop is called when the current interpreter and uiout are CLI's. So print_XXX_reason prints the stop reason to CLI uiout (only), and we don't show it in MI. In async mode the stop event is processed when we're back in the MI interpreter, so the stop reason is printed directly to the MI uiout. Fix this by making run control event printing roughly independent of whatever is the current interpreter or uiout. That is, move these prints to interpreter observers, that know whether to print or be quiet, and if printing, which uiout to print to. In the case of the console/tui interpreters, only print if the top interpreter. For MI, always print. Breakpoint hits / normal stops are already handled similarly -- MI has a normal_stop observer that prints the event to both MI and the CLI, though that could be cleaned up further in the direction of this patch. This also makes all of: (gdb) foo and (gdb) interpreter-exec MI "-exec-foo" and (gdb) -exec-foo and (gdb) -interpreter-exec console "foo" print as expected. Tested on x86_64 Fedora 20, sync and async modes. gdb/ 2014-05-29 Pedro Alves <palves@redhat.com> PR gdb/13860 * cli/cli-interp.c: Include infrun.h and observer.h. (cli_uiout, cli_interp): New globals. (cli_on_signal_received, cli_on_end_stepping_range) (cli_on_signal_exited, cli_on_exited, cli_on_no_history): New functions. (cli_interpreter_init): Install them as 'end_stepping_range', 'signal_received' 'signal_exited', 'exited' and 'no_history' observers. (_initialize_cli_interp): Remove cli_interp local. * infrun.c (handle_inferior_event): Call the several stop reason observers instead of printing the stop reason directly. (end_stepping_range): New function. (print_end_stepping_range_reason, print_signal_exited_reason) (print_exited_reason, print_signal_received_reason) (print_no_history_reason): Make static, and add an uiout parameter. Print to that instead of to CURRENT_UIOUT. * infrun.h (print_end_stepping_range_reason) (print_signal_exited_reason, print_exited_reason) (print_signal_received_reason print_no_history_reason): New declarations. * mi/mi-common.h (struct mi_interp): Rename 'uiout' field to 'mi_uiout'. <cli_uiout>: New field. * mi/mi-interp.c (mi_interpreter_init): Adjust. Create the new uiout for CLI output. Install 'signal_received', 'end_stepping_range', 'signal_exited', 'exited' and 'no_history' observers. (find_mi_interpreter, mi_interp_data, mi_on_signal_received) (mi_on_end_stepping_range, mi_on_signal_exited, mi_on_exited) (mi_on_no_history): New functions. (ui_out_free_cleanup): Delete function. (mi_on_normal_stop): Don't allocate a new uiout for CLI output, instead use the one already stored in the MI interpreter data. (mi_ui_out): Adjust. * tui/tui-interp.c: Include infrun.h and observer.h. (tui_interp): New global. (tui_on_signal_received, tui_on_end_stepping_range) (tui_on_signal_exited, tui_on_exited) (tui_on_no_history): New functions. (tui_init): Install them as 'end_stepping_range', 'signal_received' 'signal_exited', 'exited' and 'no_history' observers. (_initialize_tui_interp): Delete tui_interp local. gdb/doc/ 2014-05-29 Pedro Alves <palves@redhat.com> PR gdb/13860 * observer.texi (signal_received, end_stepping_range) (signal_exited, exited, no_history): New observer subjects. gdb/testsuite/ 2014-05-29 Pedro Alves <palves@redhat.com> PR gdb/13860 * gdb.mi/mi-cli.exp: Always expect "end-stepping-range" stop reason, even in sync mode.
2014-05-29 14:09:45 +02:00
/* Observer for the signal_received notification. */
static void
cli_on_signal_received (enum gdb_signal siggnal)
{
if (!interp_quiet_p (cli_interp))
print_signal_received_reason (cli_uiout, siggnal);
}
/* Observer for the end_stepping_range notification. */
static void
cli_on_end_stepping_range (void)
{
if (!interp_quiet_p (cli_interp))
print_end_stepping_range_reason (cli_uiout);
}
/* Observer for the signalled notification. */
static void
cli_on_signal_exited (enum gdb_signal siggnal)
{
if (!interp_quiet_p (cli_interp))
print_signal_exited_reason (cli_uiout, siggnal);
}
/* Observer for the exited notification. */
static void
cli_on_exited (int exitstatus)
{
if (!interp_quiet_p (cli_interp))
print_exited_reason (cli_uiout, exitstatus);
}
/* Observer for the no_history notification. */
static void
cli_on_no_history (void)
{
if (!interp_quiet_p (cli_interp))
print_no_history_reason (cli_uiout);
}
Make display_gdb_prompt CLI-only. Enabling target-async by default will require implementing sync execution on top of an async target, much like foreground command are implemented on the CLI in async mode. In order to do that, we will need better control of when to print the MI prompt. Currently the interp->display_prompt_p hook is all we have, and MI just always returns false, meaning, make display_gdb_prompt a no-op. We'll need to be able to know to print the MI prompt in some of the conditions that display_gdb_prompt is called from the core, but not all. This is all a litte twisted currently. As we can see, display_gdb_prompt is really CLI specific, so make the console interpreters (console/tui) themselves call it. To be able to do that, and add a few different observers that the interpreters can use to distinguish when or why the the prompt is being printed: #1 - one called whenever a command is cancelled due to an error. #2 - another for when a foreground command just finished. In both cases, CLI wants to print the prompt, while MI doesn't. MI will want to print the prompt in the second case when in a special MI mode. The display_gdb_prompt call in interp_set made me pause. The comment there reads: /* 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... */ But, that looks very much like a no-op to me currently: - the MI interpreter always return false in the prompt hook, meaning actually display no prompt. - the interpreter used at that point is still quiet. And the console/tui interpreters return false in the prompt hook if they're quiet, meaning actually display no prompt. The only remaining possible use would then be the readline magic. But whatever that might have been, it's not reacheable today either, because display_gdb_prompt returns early, before touching readline if the interpreter returns false in the display_prompt_p hook. Tested on x86_64 Fedora 20, sync and async modes. gdb/ 2014-05-29 Pedro Alves <palves@redhat.com> * cli/cli-interp.c (cli_interpreter_display_prompt_p): Delete. (_initialize_cli_interp): Adjust. * event-loop.c: Include "observer.h". (start_event_loop): Notify 'command_error' observers instead of calling display_gdb_prompt. Remove FIXME comment. * event-top.c (display_gdb_prompt): Remove call into the interpreters. * inf-loop.c: Include "observer.h". (inferior_event_handler): Notify 'command_error' observers instead of calling display_gdb_prompt. * infrun.c (fetch_inferior_event): Notify 'sync_execution_done' observers instead of calling display_gdb_prompt. * interps.c (interp_set): Don't call display_gdb_prompt. (current_interp_display_prompt_p): Delete. * interps.h (interp_prompt_p): Delete declaration. (interp_prompt_p_ftype): Delete. (struct interp_procs) <prompt_proc_p>: Delete field. (current_interp_display_prompt_p): Delete declaration. * mi-interp.c (mi_interpreter_prompt_p): Delete. (_initialize_mi_interp): Adjust. * tui-interp.c (tui_init): Install 'sync_execution_done' and 'command_error' observers. (tui_on_sync_execution_done, tui_on_command_error): New functions. (tui_display_prompt_p): Delete. (_initialize_tui_interp): Adjust. gdb/doc/ 2014-05-29 Pedro Alves <palves@redhat.com> * observer.texi (sync_execution_done, command_error): New subjects.
2014-05-23 12:37:12 +02:00
/* Observer for the sync_execution_done notification. */
static void
cli_on_sync_execution_done (void)
{
if (!interp_quiet_p (cli_interp))
display_gdb_prompt (NULL);
}
/* Observer for the command_error notification. */
static void
cli_on_command_error (void)
{
if (!interp_quiet_p (cli_interp))
display_gdb_prompt (NULL);
}
2003-02-06 06:30:17 +01:00
/* These implement the cli out interpreter: */
static void *
gdb/ 2011-09-12 Pedro Alves <pedro@codesourcery.com> Matt Rice <ratmice@gmail.com> PR gdb/13175 * interps.c (struct interp) <interpreter_out>: Delete field. (interp_new): Remove the data and uiout parameters and adjust. (interp_set): Only set the current_uiout from the interpreter's uiout after initializing the interpreter. Adjust call to init_proc. (interp_ui_out): Adjust to call procs->ui_out_proc. (interp_data, interp_name): New. * interps.h (interp_init_ftype): Add `self' parameter. (interp_ui_out_ftype): New typedef. (struct interp_procs) <ui_out_proc>: New method pointer. (interp_new): Remove the data and uiout parameters. (interp_data, interp_name): Declare. * tui/tui-interp.c (tui_init): Adjust prototype. (tui_ui_out): New. (_initialize_tui_interp): Install tui_ui_out. Don't instanciate tui_out here. Adjust call to interp_new. * tui/tui-io.c (tui_initialize_io): Don't set current_uiout here. * cli/cli-interp.c (cli_interpreter_init): Adjust prototype. (cli_ui_out): New. (_initialize_cli_interp): Install it. Adjust call to interp_new. * mi/mi-common.h (struct mi_interp) <uiout>: New field. * mi/mi-interp.c (mi_interpreter_init): Adjust prototype. Initialize mi->uiout depending on the mi_version as extracted from the interpreter's name. (mi_ui_out): New. (_initialize_mi_interp): Install mi_ui_out. Adjust calls to interp_new. Don't allocate the ui_out's of the interpreters here. gdb/testsuite/ 2011-09-12 Matt Rice <ratmice@gmail.com> Pedro Alves <pedro@codesourcery.com> PR gdb/13175 * gdb.base/interp.exp: New tests. * gdb.base/interp.c: New file.
2011-09-12 23:25:22 +02:00
cli_interpreter_init (struct interp *self, int top_level)
2003-02-06 06:30:17 +01:00
{
PR gdb/13860 - Make MI sync vs async output (closer to) the same. Ignoring expected and desired differences like whether the prompt is output after *stoppped records, GDB MI output is still different in sync and async modes. In sync mode, when a CLI execution command is entered, the "reason" field is missing in the *stopped async record. And in async mode, for some events, like program exits, the corresponding CLI output is missing in the CLI channel. Vis, diff between sync vs async modes: run ^running *running,thread-id="1" (gdb) ... - ~"[Inferior 1 (process 15882) exited normally]\n" =thread-exited,id="1",group-id="i1" =thread-group-exited,id="i1",exit-code="0" - *stopped + *stopped,reason="exited-normally" si ... (gdb) ~"0x000000000045e033\t29\t memset (&args, 0, sizeof args);\n" - *stopped,frame=...,thread-id="1",stopped-threads="all",core="0" + *stopped,reason="end-stepping-range",frame=...,thread-id="1",stopped-threads="all",core="0" (gdb) In addition, in both cases, when a MI execution command is entered, and a breakpoint triggers, the event is sent to the console too. But some events like program exits have the CLI output missing in the CLI channel: -exec-run ^running *running,thread-id="1" (gdb) ... =thread-exited,id="1",group-id="i1" =thread-group-exited,id="i1",exit-code="0" - *stopped + *stopped,reason="exited-normally" We'll want to make background commands always possible by default. IOW, make target-async be the default. But, in order to do that, we'll need to emulate MI sync on top of an async target. That means we'll have yet another combination to care for in the testsuite. Rather than making the testsuite cope with all these differences, I thought it better to just fix GDB to always have the complete output, no matter whether it's in sync or async mode. This is all related to interpreter-exec, and the corresponding uiout switching. (Typing a CLI command directly in MI is shorthand for running it through -interpreter-exec console.) In sync mode, when a CLI command is active, normal_stop is called when the current interpreter and uiout are CLI's. So print_XXX_reason prints the stop reason to CLI uiout (only), and we don't show it in MI. In async mode the stop event is processed when we're back in the MI interpreter, so the stop reason is printed directly to the MI uiout. Fix this by making run control event printing roughly independent of whatever is the current interpreter or uiout. That is, move these prints to interpreter observers, that know whether to print or be quiet, and if printing, which uiout to print to. In the case of the console/tui interpreters, only print if the top interpreter. For MI, always print. Breakpoint hits / normal stops are already handled similarly -- MI has a normal_stop observer that prints the event to both MI and the CLI, though that could be cleaned up further in the direction of this patch. This also makes all of: (gdb) foo and (gdb) interpreter-exec MI "-exec-foo" and (gdb) -exec-foo and (gdb) -interpreter-exec console "foo" print as expected. Tested on x86_64 Fedora 20, sync and async modes. gdb/ 2014-05-29 Pedro Alves <palves@redhat.com> PR gdb/13860 * cli/cli-interp.c: Include infrun.h and observer.h. (cli_uiout, cli_interp): New globals. (cli_on_signal_received, cli_on_end_stepping_range) (cli_on_signal_exited, cli_on_exited, cli_on_no_history): New functions. (cli_interpreter_init): Install them as 'end_stepping_range', 'signal_received' 'signal_exited', 'exited' and 'no_history' observers. (_initialize_cli_interp): Remove cli_interp local. * infrun.c (handle_inferior_event): Call the several stop reason observers instead of printing the stop reason directly. (end_stepping_range): New function. (print_end_stepping_range_reason, print_signal_exited_reason) (print_exited_reason, print_signal_received_reason) (print_no_history_reason): Make static, and add an uiout parameter. Print to that instead of to CURRENT_UIOUT. * infrun.h (print_end_stepping_range_reason) (print_signal_exited_reason, print_exited_reason) (print_signal_received_reason print_no_history_reason): New declarations. * mi/mi-common.h (struct mi_interp): Rename 'uiout' field to 'mi_uiout'. <cli_uiout>: New field. * mi/mi-interp.c (mi_interpreter_init): Adjust. Create the new uiout for CLI output. Install 'signal_received', 'end_stepping_range', 'signal_exited', 'exited' and 'no_history' observers. (find_mi_interpreter, mi_interp_data, mi_on_signal_received) (mi_on_end_stepping_range, mi_on_signal_exited, mi_on_exited) (mi_on_no_history): New functions. (ui_out_free_cleanup): Delete function. (mi_on_normal_stop): Don't allocate a new uiout for CLI output, instead use the one already stored in the MI interpreter data. (mi_ui_out): Adjust. * tui/tui-interp.c: Include infrun.h and observer.h. (tui_interp): New global. (tui_on_signal_received, tui_on_end_stepping_range) (tui_on_signal_exited, tui_on_exited) (tui_on_no_history): New functions. (tui_init): Install them as 'end_stepping_range', 'signal_received' 'signal_exited', 'exited' and 'no_history' observers. (_initialize_tui_interp): Delete tui_interp local. gdb/doc/ 2014-05-29 Pedro Alves <palves@redhat.com> PR gdb/13860 * observer.texi (signal_received, end_stepping_range) (signal_exited, exited, no_history): New observer subjects. gdb/testsuite/ 2014-05-29 Pedro Alves <palves@redhat.com> PR gdb/13860 * gdb.mi/mi-cli.exp: Always expect "end-stepping-range" stop reason, even in sync mode.
2014-05-29 14:09:45 +02:00
/* If changing this, remember to update tui-interp.c as well. */
Replace "struct continuation" mechanism by something more extensible This adds an object oriented replacement for the "struct continuation" mechanism, and converts the stepping commands (step, next, stepi, nexti) and the "finish" commands to use it. It adds a new thread "class" (struct thread_fsm) that contains the necessary info and callbacks to manage the state machine of a thread's execution command. This allows getting rid of some hacks. E.g., in fetch_inferior_event and normal_stop we no longer need to know whether a thread is doing a multi-step (e.g., step N). This effectively makes the intermediate_continuations unused -- they'll be garbage collected in a separate patch. (They were never a proper abstraction, IMO. See how fetch_inferior_event needs to check step_multi before knowing whether to call INF_EXEC_CONTINUE or INF_EXEC_COMPLETE.) The target async vs !async uiout hacks in mi_on_normal_stop go away too. print_stop_event is no longer called from normal_stop. Instead it is now called from within each interpreter's normal_stop observer. This clears the path to make each interpreter print a stop event the way it sees fit. Currently we have some hacks in common code to differenciate CLI vs TUI vs MI around this area. The "finish" command's FSM class stores the return value plus that value's position in the value history, so that those can be printed to both MI and CLI's streams. This fixes the CLI "finish" command when run from MI -- it now also includes the function's return value in the CLI stream: (gdb) ~"callee3 (strarg=0x400730 \"A string argument.\") at src/gdb/testsuite/gdb.mi/basics.c:35\n" ~"35\t}\n" +~"Value returned is $1 = 0\n" *stopped,reason="function-finished",frame=...,gdb-result-var="$1",return-value="0",thread-id="1",stopped-threads="all",core="0" -FAIL: gdb.mi/mi-cli.exp: CLI finish: check CLI output +PASS: gdb.mi/mi-cli.exp: CLI finish: check CLI output gdb/ChangeLog: 2015-09-09 Pedro Alves <palves@redhat.com> * Makefile.in (COMMON_OBS): Add thread-fsm.o. * breakpoint.c (handle_jit_event): Print debug output. (bpstat_what): Split event callback handling to ... (bpstat_run_callbacks): ... this new function. (momentary_bkpt_print_it): No longer handle bp_finish here. * breakpoint.h (bpstat_run_callbacks): Declare. * gdbthread.h (struct thread_info) <step_multi>: Delete field. <thread_fsm>: New field. (thread_cancel_execution_command): Declare. * infcmd.c: Include thread-fsm.h. (struct step_command_fsm): New. (step_command_fsm_ops): New global. (new_step_command_fsm, step_command_fsm_prepare): New functions. (step_1): Adjust to use step_command_fsm_prepare and prepare_one_step. (struct step_1_continuation_args): Delete. (step_1_continuation): Delete. (step_command_fsm_should_stop): New function. (step_once): Delete. (step_command_fsm_clean_up, step_command_fsm_async_reply_reason) (prepare_one_step): New function, based on step_once. (until_next_command): Remove step_multi reference. (struct return_value_info): New. (print_return_value): Rename to ... (print_return_value_1): ... this. New struct return_value_info parameter. Adjust. (print_return_value): Reimplement as wrapper around print_return_value_1. (struct finish_command_fsm): New. (finish_command_continuation): Delete. (finish_command_fsm_ops): New global. (new_finish_command_fsm, finish_command_fsm_should_stop): New functions. (finish_command_fsm_clean_up, finish_command_fsm_return_value): New. (finish_command_continuation_free_arg): Delete. (finish_command_fsm_async_reply_reason): New. (finish_backward, finish_forward): Change symbol parameter to a finish_command_fsm. Adjust. (finish_command): Create a finish_command_fsm. Adjust. * infrun.c: Include "thread-fsm.h". (clear_proceed_status_thread): Delete the thread's FSM. (infrun_thread_stop_requested_callback): Cancel the thread's execution command. (clean_up_just_stopped_threads_fsms): New function. (fetch_inferior_event): Handle the event_thread's should_stop method saying the command isn't done yet. (process_event_stop_test): Run breakpoint callbacks here. (print_stop_event): Rename to ... (print_stop_location): ... this. (restore_current_uiout_cleanup): New function. (print_stop_event): Reimplement. (normal_stop): No longer notify the end_stepping_range observers here handle "step N" nor "finish" here. No longer call print_stop_event here. * infrun.h (struct return_value_info): Forward declare. (print_return_value): Declare. (print_stop_event): Change prototype. * thread-fsm.c: New file. * thread-fsm.h: New file. * thread.c: Include "thread-fsm.h". (thread_cancel_execution_command): New function. (clear_thread_inferior_resources): Call it. * cli/cli-interp.c (cli_on_normal_stop): New function. (cli_interpreter_init): Install cli_on_normal_stop as normal_stop observer. * mi/mi-interp.c: Include "thread-fsm.h". (restore_current_uiout_cleanup): Delete. (mi_on_normal_stop): If the thread has an FSM associated, and it finished, ask it for the async-reply-reason to print. Always call print_stop_event here, regardless of the top-level interpreter. Check bpstat_what to tell whether an asynchronous breakpoint hit triggered. * tui/tui-interp.c (tui_on_normal_stop): New function. (tui_init): Install tui_on_normal_stop as normal_stop observer. gdb/testsuite/ChangeLog: 2015-09-09 Pedro Alves <palves@redhat.com> * gdb.mi/mi-cli.exp: Add CLI finish tests.
2015-09-09 19:23:24 +02:00
observer_attach_normal_stop (cli_on_normal_stop);
PR gdb/13860 - Make MI sync vs async output (closer to) the same. Ignoring expected and desired differences like whether the prompt is output after *stoppped records, GDB MI output is still different in sync and async modes. In sync mode, when a CLI execution command is entered, the "reason" field is missing in the *stopped async record. And in async mode, for some events, like program exits, the corresponding CLI output is missing in the CLI channel. Vis, diff between sync vs async modes: run ^running *running,thread-id="1" (gdb) ... - ~"[Inferior 1 (process 15882) exited normally]\n" =thread-exited,id="1",group-id="i1" =thread-group-exited,id="i1",exit-code="0" - *stopped + *stopped,reason="exited-normally" si ... (gdb) ~"0x000000000045e033\t29\t memset (&args, 0, sizeof args);\n" - *stopped,frame=...,thread-id="1",stopped-threads="all",core="0" + *stopped,reason="end-stepping-range",frame=...,thread-id="1",stopped-threads="all",core="0" (gdb) In addition, in both cases, when a MI execution command is entered, and a breakpoint triggers, the event is sent to the console too. But some events like program exits have the CLI output missing in the CLI channel: -exec-run ^running *running,thread-id="1" (gdb) ... =thread-exited,id="1",group-id="i1" =thread-group-exited,id="i1",exit-code="0" - *stopped + *stopped,reason="exited-normally" We'll want to make background commands always possible by default. IOW, make target-async be the default. But, in order to do that, we'll need to emulate MI sync on top of an async target. That means we'll have yet another combination to care for in the testsuite. Rather than making the testsuite cope with all these differences, I thought it better to just fix GDB to always have the complete output, no matter whether it's in sync or async mode. This is all related to interpreter-exec, and the corresponding uiout switching. (Typing a CLI command directly in MI is shorthand for running it through -interpreter-exec console.) In sync mode, when a CLI command is active, normal_stop is called when the current interpreter and uiout are CLI's. So print_XXX_reason prints the stop reason to CLI uiout (only), and we don't show it in MI. In async mode the stop event is processed when we're back in the MI interpreter, so the stop reason is printed directly to the MI uiout. Fix this by making run control event printing roughly independent of whatever is the current interpreter or uiout. That is, move these prints to interpreter observers, that know whether to print or be quiet, and if printing, which uiout to print to. In the case of the console/tui interpreters, only print if the top interpreter. For MI, always print. Breakpoint hits / normal stops are already handled similarly -- MI has a normal_stop observer that prints the event to both MI and the CLI, though that could be cleaned up further in the direction of this patch. This also makes all of: (gdb) foo and (gdb) interpreter-exec MI "-exec-foo" and (gdb) -exec-foo and (gdb) -interpreter-exec console "foo" print as expected. Tested on x86_64 Fedora 20, sync and async modes. gdb/ 2014-05-29 Pedro Alves <palves@redhat.com> PR gdb/13860 * cli/cli-interp.c: Include infrun.h and observer.h. (cli_uiout, cli_interp): New globals. (cli_on_signal_received, cli_on_end_stepping_range) (cli_on_signal_exited, cli_on_exited, cli_on_no_history): New functions. (cli_interpreter_init): Install them as 'end_stepping_range', 'signal_received' 'signal_exited', 'exited' and 'no_history' observers. (_initialize_cli_interp): Remove cli_interp local. * infrun.c (handle_inferior_event): Call the several stop reason observers instead of printing the stop reason directly. (end_stepping_range): New function. (print_end_stepping_range_reason, print_signal_exited_reason) (print_exited_reason, print_signal_received_reason) (print_no_history_reason): Make static, and add an uiout parameter. Print to that instead of to CURRENT_UIOUT. * infrun.h (print_end_stepping_range_reason) (print_signal_exited_reason, print_exited_reason) (print_signal_received_reason print_no_history_reason): New declarations. * mi/mi-common.h (struct mi_interp): Rename 'uiout' field to 'mi_uiout'. <cli_uiout>: New field. * mi/mi-interp.c (mi_interpreter_init): Adjust. Create the new uiout for CLI output. Install 'signal_received', 'end_stepping_range', 'signal_exited', 'exited' and 'no_history' observers. (find_mi_interpreter, mi_interp_data, mi_on_signal_received) (mi_on_end_stepping_range, mi_on_signal_exited, mi_on_exited) (mi_on_no_history): New functions. (ui_out_free_cleanup): Delete function. (mi_on_normal_stop): Don't allocate a new uiout for CLI output, instead use the one already stored in the MI interpreter data. (mi_ui_out): Adjust. * tui/tui-interp.c: Include infrun.h and observer.h. (tui_interp): New global. (tui_on_signal_received, tui_on_end_stepping_range) (tui_on_signal_exited, tui_on_exited) (tui_on_no_history): New functions. (tui_init): Install them as 'end_stepping_range', 'signal_received' 'signal_exited', 'exited' and 'no_history' observers. (_initialize_tui_interp): Delete tui_interp local. gdb/doc/ 2014-05-29 Pedro Alves <palves@redhat.com> PR gdb/13860 * observer.texi (signal_received, end_stepping_range) (signal_exited, exited, no_history): New observer subjects. gdb/testsuite/ 2014-05-29 Pedro Alves <palves@redhat.com> PR gdb/13860 * gdb.mi/mi-cli.exp: Always expect "end-stepping-range" stop reason, even in sync mode.
2014-05-29 14:09:45 +02:00
observer_attach_end_stepping_range (cli_on_end_stepping_range);
observer_attach_signal_received (cli_on_signal_received);
observer_attach_signal_exited (cli_on_signal_exited);
observer_attach_exited (cli_on_exited);
observer_attach_no_history (cli_on_no_history);
Make display_gdb_prompt CLI-only. Enabling target-async by default will require implementing sync execution on top of an async target, much like foreground command are implemented on the CLI in async mode. In order to do that, we will need better control of when to print the MI prompt. Currently the interp->display_prompt_p hook is all we have, and MI just always returns false, meaning, make display_gdb_prompt a no-op. We'll need to be able to know to print the MI prompt in some of the conditions that display_gdb_prompt is called from the core, but not all. This is all a litte twisted currently. As we can see, display_gdb_prompt is really CLI specific, so make the console interpreters (console/tui) themselves call it. To be able to do that, and add a few different observers that the interpreters can use to distinguish when or why the the prompt is being printed: #1 - one called whenever a command is cancelled due to an error. #2 - another for when a foreground command just finished. In both cases, CLI wants to print the prompt, while MI doesn't. MI will want to print the prompt in the second case when in a special MI mode. The display_gdb_prompt call in interp_set made me pause. The comment there reads: /* 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... */ But, that looks very much like a no-op to me currently: - the MI interpreter always return false in the prompt hook, meaning actually display no prompt. - the interpreter used at that point is still quiet. And the console/tui interpreters return false in the prompt hook if they're quiet, meaning actually display no prompt. The only remaining possible use would then be the readline magic. But whatever that might have been, it's not reacheable today either, because display_gdb_prompt returns early, before touching readline if the interpreter returns false in the display_prompt_p hook. Tested on x86_64 Fedora 20, sync and async modes. gdb/ 2014-05-29 Pedro Alves <palves@redhat.com> * cli/cli-interp.c (cli_interpreter_display_prompt_p): Delete. (_initialize_cli_interp): Adjust. * event-loop.c: Include "observer.h". (start_event_loop): Notify 'command_error' observers instead of calling display_gdb_prompt. Remove FIXME comment. * event-top.c (display_gdb_prompt): Remove call into the interpreters. * inf-loop.c: Include "observer.h". (inferior_event_handler): Notify 'command_error' observers instead of calling display_gdb_prompt. * infrun.c (fetch_inferior_event): Notify 'sync_execution_done' observers instead of calling display_gdb_prompt. * interps.c (interp_set): Don't call display_gdb_prompt. (current_interp_display_prompt_p): Delete. * interps.h (interp_prompt_p): Delete declaration. (interp_prompt_p_ftype): Delete. (struct interp_procs) <prompt_proc_p>: Delete field. (current_interp_display_prompt_p): Delete declaration. * mi-interp.c (mi_interpreter_prompt_p): Delete. (_initialize_mi_interp): Adjust. * tui-interp.c (tui_init): Install 'sync_execution_done' and 'command_error' observers. (tui_on_sync_execution_done, tui_on_command_error): New functions. (tui_display_prompt_p): Delete. (_initialize_tui_interp): Adjust. gdb/doc/ 2014-05-29 Pedro Alves <palves@redhat.com> * observer.texi (sync_execution_done, command_error): New subjects.
2014-05-23 12:37:12 +02:00
observer_attach_sync_execution_done (cli_on_sync_execution_done);
observer_attach_command_error (cli_on_command_error);
PR gdb/13860 - Make MI sync vs async output (closer to) the same. Ignoring expected and desired differences like whether the prompt is output after *stoppped records, GDB MI output is still different in sync and async modes. In sync mode, when a CLI execution command is entered, the "reason" field is missing in the *stopped async record. And in async mode, for some events, like program exits, the corresponding CLI output is missing in the CLI channel. Vis, diff between sync vs async modes: run ^running *running,thread-id="1" (gdb) ... - ~"[Inferior 1 (process 15882) exited normally]\n" =thread-exited,id="1",group-id="i1" =thread-group-exited,id="i1",exit-code="0" - *stopped + *stopped,reason="exited-normally" si ... (gdb) ~"0x000000000045e033\t29\t memset (&args, 0, sizeof args);\n" - *stopped,frame=...,thread-id="1",stopped-threads="all",core="0" + *stopped,reason="end-stepping-range",frame=...,thread-id="1",stopped-threads="all",core="0" (gdb) In addition, in both cases, when a MI execution command is entered, and a breakpoint triggers, the event is sent to the console too. But some events like program exits have the CLI output missing in the CLI channel: -exec-run ^running *running,thread-id="1" (gdb) ... =thread-exited,id="1",group-id="i1" =thread-group-exited,id="i1",exit-code="0" - *stopped + *stopped,reason="exited-normally" We'll want to make background commands always possible by default. IOW, make target-async be the default. But, in order to do that, we'll need to emulate MI sync on top of an async target. That means we'll have yet another combination to care for in the testsuite. Rather than making the testsuite cope with all these differences, I thought it better to just fix GDB to always have the complete output, no matter whether it's in sync or async mode. This is all related to interpreter-exec, and the corresponding uiout switching. (Typing a CLI command directly in MI is shorthand for running it through -interpreter-exec console.) In sync mode, when a CLI command is active, normal_stop is called when the current interpreter and uiout are CLI's. So print_XXX_reason prints the stop reason to CLI uiout (only), and we don't show it in MI. In async mode the stop event is processed when we're back in the MI interpreter, so the stop reason is printed directly to the MI uiout. Fix this by making run control event printing roughly independent of whatever is the current interpreter or uiout. That is, move these prints to interpreter observers, that know whether to print or be quiet, and if printing, which uiout to print to. In the case of the console/tui interpreters, only print if the top interpreter. For MI, always print. Breakpoint hits / normal stops are already handled similarly -- MI has a normal_stop observer that prints the event to both MI and the CLI, though that could be cleaned up further in the direction of this patch. This also makes all of: (gdb) foo and (gdb) interpreter-exec MI "-exec-foo" and (gdb) -exec-foo and (gdb) -interpreter-exec console "foo" print as expected. Tested on x86_64 Fedora 20, sync and async modes. gdb/ 2014-05-29 Pedro Alves <palves@redhat.com> PR gdb/13860 * cli/cli-interp.c: Include infrun.h and observer.h. (cli_uiout, cli_interp): New globals. (cli_on_signal_received, cli_on_end_stepping_range) (cli_on_signal_exited, cli_on_exited, cli_on_no_history): New functions. (cli_interpreter_init): Install them as 'end_stepping_range', 'signal_received' 'signal_exited', 'exited' and 'no_history' observers. (_initialize_cli_interp): Remove cli_interp local. * infrun.c (handle_inferior_event): Call the several stop reason observers instead of printing the stop reason directly. (end_stepping_range): New function. (print_end_stepping_range_reason, print_signal_exited_reason) (print_exited_reason, print_signal_received_reason) (print_no_history_reason): Make static, and add an uiout parameter. Print to that instead of to CURRENT_UIOUT. * infrun.h (print_end_stepping_range_reason) (print_signal_exited_reason, print_exited_reason) (print_signal_received_reason print_no_history_reason): New declarations. * mi/mi-common.h (struct mi_interp): Rename 'uiout' field to 'mi_uiout'. <cli_uiout>: New field. * mi/mi-interp.c (mi_interpreter_init): Adjust. Create the new uiout for CLI output. Install 'signal_received', 'end_stepping_range', 'signal_exited', 'exited' and 'no_history' observers. (find_mi_interpreter, mi_interp_data, mi_on_signal_received) (mi_on_end_stepping_range, mi_on_signal_exited, mi_on_exited) (mi_on_no_history): New functions. (ui_out_free_cleanup): Delete function. (mi_on_normal_stop): Don't allocate a new uiout for CLI output, instead use the one already stored in the MI interpreter data. (mi_ui_out): Adjust. * tui/tui-interp.c: Include infrun.h and observer.h. (tui_interp): New global. (tui_on_signal_received, tui_on_end_stepping_range) (tui_on_signal_exited, tui_on_exited) (tui_on_no_history): New functions. (tui_init): Install them as 'end_stepping_range', 'signal_received' 'signal_exited', 'exited' and 'no_history' observers. (_initialize_tui_interp): Delete tui_interp local. gdb/doc/ 2014-05-29 Pedro Alves <palves@redhat.com> PR gdb/13860 * observer.texi (signal_received, end_stepping_range) (signal_exited, exited, no_history): New observer subjects. gdb/testsuite/ 2014-05-29 Pedro Alves <palves@redhat.com> PR gdb/13860 * gdb.mi/mi-cli.exp: Always expect "end-stepping-range" stop reason, even in sync mode.
2014-05-29 14:09:45 +02:00
2003-02-06 06:30:17 +01:00
return NULL;
}
static int
cli_interpreter_resume (void *data)
{
struct ui_file *stream;
2003-02-06 06:30:17 +01:00
/*sync_execution = 1; */
/* gdb_setup_readline will change gdb_stdout. If the CLI was
previously writing to gdb_stdout, then set it to the new
gdb_stdout afterwards. */
stream = cli_out_set_stream (cli_uiout, gdb_stdout);
if (stream != gdb_stdout)
{
cli_out_set_stream (cli_uiout, stream);
stream = NULL;
}
2003-02-06 06:30:17 +01:00
gdb_setup_readline ();
if (stream != NULL)
cli_out_set_stream (cli_uiout, gdb_stdout);
2003-02-06 06:30:17 +01:00
return 1;
}
static int
cli_interpreter_suspend (void *data)
{
gdb_disable_readline ();
return 1;
}
static struct gdb_exception
2003-02-06 06:30:17 +01:00
cli_interpreter_exec (void *data, const char *command_str)
{
struct ui_file *old_stream;
struct gdb_exception result;
2003-02-06 06:30:17 +01:00
/* FIXME: cagney/2003-02-01: Need to const char *propogate
safe_execute_command. */
Add casts to memory allocation related calls Most allocation functions (if not all) return a void* pointing to the allocated memory. In C++, we need to add an explicit cast when assigning the result to a pointer to another type (which is the case more often than not). The content of this patch is taken from Pedro's branch, from commit "(mostly) auto-generated patch to insert casts needed for C++". I validated that the changes make sense and manually reflowed the code to make it respect the coding style. I also found multiple places where I could use XNEW/XNEWVEC/XRESIZEVEC/etc. Thanks a lot to whoever did that automated script to insert casts, doing it completely by hand would have taken a ridiculous amount of time. Only files built on x86 with --enable-targets=all are modified. This means that all other -nat.c files are untouched and will have to be dealt with later by using appropiate compilers. Or maybe we can try to build them with a regular g++ just to know where to add casts, I don't know. I built-tested this with --enable-targets=all and reg-tested. Here's the changelog entry, which was not too bad to make despite the size, thanks to David Malcom's script. I fixed some bits by hand, but there might be some wrong parts left (hopefully not). gdb/ChangeLog: * aarch64-linux-tdep.c (aarch64_stap_parse_special_token): Add cast to allocation result assignment. * ada-exp.y (write_object_renaming): Likewise. (write_ambiguous_var): Likewise. (ada_nget_field_index): Likewise. (write_var_or_type): Likewise. * ada-lang.c (ada_decode_symbol): Likewise. (ada_value_assign): Likewise. (value_pointer): Likewise. (cache_symbol): Likewise. (add_nonlocal_symbols): Likewise. (ada_name_for_lookup): Likewise. (symbol_completion_add): Likewise. (ada_to_fixed_type_1): Likewise. (ada_get_next_arg): Likewise. (defns_collected): Likewise. * ada-lex.l (processId): Likewise. (processString): Likewise. * ada-tasks.c (read_known_tasks_array): Likewise. (read_known_tasks_list): Likewise. * ada-typeprint.c (decoded_type_name): Likewise. * addrmap.c (addrmap_mutable_create_fixed): Likewise. * amd64-tdep.c (amd64_push_arguments): Likewise. (amd64_displaced_step_copy_insn): Likewise. (amd64_classify_insn_at): Likewise. (amd64_relocate_instruction): Likewise. * amd64obsd-tdep.c (amd64obsd_sigtramp_p): Likewise. * arch-utils.c (simple_displaced_step_copy_insn): Likewise. (initialize_current_architecture): Likewise. * arm-linux-tdep.c (arm_stap_parse_special_token): Likewise. * arm-symbian-tdep.c (arm_symbian_osabi_sniffer): Likewise. * arm-tdep.c (arm_exidx_new_objfile): Likewise. (arm_push_dummy_call): Likewise. (extend_buffer_earlier): Likewise. (arm_adjust_breakpoint_address): Likewise. (arm_skip_stub): Likewise. * auto-load.c (filename_is_in_pattern): Likewise. (maybe_add_script_file): Likewise. (maybe_add_script_text): Likewise. (auto_load_objfile_script_1): Likewise. * auxv.c (ld_so_xfer_auxv): Likewise. * ax-general.c (new_agent_expr): Likewise. (grow_expr): Likewise. (ax_reg_mask): Likewise. * bcache.c (bcache_full): Likewise. * breakpoint.c (program_breakpoint_here_p): Likewise. * btrace.c (parse_xml_raw): Likewise. * build-id.c (build_id_to_debug_bfd): Likewise. * buildsym.c (end_symtab_with_blockvector): Likewise. * c-exp.y (string_exp): Likewise. (qualified_name): Likewise. (write_destructor_name): Likewise. (operator_stoken): Likewise. (parse_number): Likewise. (scan_macro_expansion): Likewise. (yylex): Likewise. (c_print_token): Likewise. * c-lang.c (c_get_string): Likewise. (emit_numeric_character): Likewise. * charset.c (wchar_iterate): Likewise. * cli/cli-cmds.c (complete_command): Likewise. (make_command): Likewise. * cli/cli-dump.c (restore_section_callback): Likewise. (restore_binary_file): Likewise. * cli/cli-interp.c (cli_interpreter_exec): Likewise. * cli/cli-script.c (execute_control_command): Likewise. * cli/cli-setshow.c (do_set_command): Likewise. * coff-pe-read.c (add_pe_forwarded_sym): Likewise. (read_pe_exported_syms): Likewise. * coffread.c (coff_read_struct_type): Likewise. (coff_read_enum_type): Likewise. * common/btrace-common.c (btrace_data_append): Likewise. * common/buffer.c (buffer_grow): Likewise. * common/filestuff.c (gdb_fopen_cloexec): Likewise. * common/format.c (parse_format_string): Likewise. * common/gdb_vecs.c (delim_string_to_char_ptr_vec_append): Likewise. * common/xml-utils.c (xml_escape_text): Likewise. * compile/compile-object-load.c (copy_sections): Likewise. (compile_object_load): Likewise. * compile/compile-object-run.c (compile_object_run): Likewise. * completer.c (filename_completer): Likewise. * corefile.c (read_memory_typed_address): Likewise. (write_memory_unsigned_integer): Likewise. (write_memory_signed_integer): Likewise. (complete_set_gnutarget): Likewise. * corelow.c (get_core_register_section): Likewise. * cp-name-parser.y (d_grab): Likewise. (allocate_info): Likewise. (cp_new_demangle_parse_info): Likewise. * cp-namespace.c (cp_scan_for_anonymous_namespaces): Likewise. (cp_lookup_symbol_in_namespace): Likewise. (lookup_namespace_scope): Likewise. (find_symbol_in_baseclass): Likewise. (cp_lookup_nested_symbol): Likewise. (cp_lookup_transparent_type_loop): Likewise. * cp-support.c (copy_string_to_obstack): Likewise. (make_symbol_overload_list): Likewise. (make_symbol_overload_list_namespace): Likewise. (make_symbol_overload_list_adl_namespace): Likewise. (first_component_command): Likewise. * cp-valprint.c (cp_print_value): Likewise. * ctf.c (ctf_xfer_partial): Likewise. * d-exp.y (StringExp): Likewise. * d-namespace.c (d_lookup_symbol_in_module): Likewise. (lookup_module_scope): Likewise. (find_symbol_in_baseclass): Likewise. (d_lookup_nested_symbol): Likewise. * dbxread.c (find_stab_function_addr): Likewise. (read_dbx_symtab): Likewise. (dbx_end_psymtab): Likewise. (cp_set_block_scope): Likewise. * dcache.c (dcache_alloc): Likewise. * demangle.c (_initialize_demangler): Likewise. * dicos-tdep.c (dicos_load_module_p): Likewise. * dictionary.c (dict_create_hashed_expandable): Likewise. (dict_create_linear_expandable): Likewise. (expand_hashtable): Likewise. (add_symbol_linear_expandable): Likewise. * dwarf2-frame.c (add_cie): Likewise. (add_fde): Likewise. (dwarf2_build_frame_info): Likewise. * dwarf2expr.c (dwarf_expr_grow_stack): Likewise. (dwarf_expr_fetch_address): Likewise. (add_piece): Likewise. (execute_stack_op): Likewise. * dwarf2loc.c (chain_candidate): Likewise. (dwarf_entry_parameter_to_value): Likewise. (read_pieced_value): Likewise. (write_pieced_value): Likewise. * dwarf2read.c (dwarf2_read_section): Likewise. (add_type_unit): Likewise. (read_comp_units_from_section): Likewise. (fixup_go_packaging): Likewise. (dwarf2_compute_name): Likewise. (dwarf2_physname): Likewise. (create_dwo_unit_in_dwp_v1): Likewise. (create_dwo_unit_in_dwp_v2): Likewise. (read_func_scope): Likewise. (read_call_site_scope): Likewise. (dwarf2_attach_fields_to_type): Likewise. (process_structure_scope): Likewise. (mark_common_block_symbol_computed): Likewise. (read_common_block): Likewise. (abbrev_table_read_table): Likewise. (guess_partial_die_structure_name): Likewise. (fixup_partial_die): Likewise. (add_file_name): Likewise. (dwarf2_const_value_data): Likewise. (dwarf2_const_value_attr): Likewise. (build_error_marker_type): Likewise. (guess_full_die_structure_name): Likewise. (anonymous_struct_prefix): Likewise. (typename_concat): Likewise. (dwarf2_canonicalize_name): Likewise. (dwarf2_name): Likewise. (write_constant_as_bytes): Likewise. (dwarf2_fetch_constant_bytes): Likewise. (copy_string): Likewise. (parse_macro_definition): Likewise. * elfread.c (elf_symfile_segments): Likewise. (elf_rel_plt_read): Likewise. (elf_gnu_ifunc_resolve_by_cache): Likewise. (elf_gnu_ifunc_resolve_by_got): Likewise. (elf_read_minimal_symbols): Likewise. (elf_gnu_ifunc_record_cache): Likewise. * event-top.c (top_level_prompt): Likewise. (command_line_handler): Likewise. * exec.c (resize_section_table): Likewise. * expprint.c (print_subexp_standard): Likewise. * fbsd-tdep.c (fbsd_collect_regset_section_cb): Likewise. * findcmd.c (parse_find_args): Likewise. * findvar.c (address_from_register): Likewise. * frame.c (get_prev_frame_always): Likewise. * gdb_bfd.c (gdb_bfd_ref): Likewise. (get_section_descriptor): Likewise. * gdb_obstack.c (obconcat): Likewise. (obstack_strdup): Likewise. * gdbtypes.c (lookup_function_type_with_arguments): Likewise. (create_set_type): Likewise. (lookup_unsigned_typename): Likewise. (lookup_signed_typename): Likewise. (resolve_dynamic_union): Likewise. (resolve_dynamic_struct): Likewise. (add_dyn_prop): Likewise. (copy_dynamic_prop_list): Likewise. (arch_flags_type): Likewise. (append_composite_type_field_raw): Likewise. * gdbtypes.h (INIT_FUNC_SPECIFIC): Likewise. * gnu-v3-abi.c (gnuv3_rtti_type): Likewise. * go-exp.y (string_exp): Likewise. * go-lang.c (go_demangle): Likewise. * guile/guile.c (compute_scheme_string): Likewise. * guile/scm-cmd.c (gdbscm_parse_command_name): Likewise. (gdbscm_canonicalize_command_name): Likewise. * guile/scm-ports.c (ioscm_init_stdio_buffers): Likewise. (ioscm_init_memory_port): Likewise. (ioscm_reinit_memory_port): Likewise. * guile/scm-utils.c (gdbscm_gc_xstrdup): Likewise. (gdbscm_gc_dup_argv): Likewise. * h8300-tdep.c (h8300_push_dummy_call): Likewise. * hppa-tdep.c (internalize_unwinds): Likewise. (read_unwind_info): Likewise. * i386-cygwin-tdep.c (core_process_module_section): Likewise. (windows_core_xfer_shared_libraries): Likewise. * i386-tdep.c (i386_displaced_step_copy_insn): Likewise. (i386_stap_parse_special_token_triplet): Likewise. (i386_stap_parse_special_token_three_arg_disp): Likewise. * i386obsd-tdep.c (i386obsd_sigtramp_p): Likewise. * inf-child.c (inf_child_fileio_readlink): Likewise. * inf-ptrace.c (inf_ptrace_fetch_register): Likewise. (inf_ptrace_store_register): Likewise. * infrun.c (follow_exec): Likewise. (displaced_step_prepare_throw): Likewise. (save_stop_context): Likewise. (save_infcall_suspend_state): Likewise. * jit.c (jit_read_descriptor): Likewise. (jit_read_code_entry): Likewise. (jit_symtab_line_mapping_add_impl): Likewise. (finalize_symtab): Likewise. (jit_unwind_reg_get_impl): Likewise. * jv-exp.y (QualifiedName): Likewise. * jv-lang.c (get_java_utf8_name): Likewise. (type_from_class): Likewise. (java_demangle_type_signature): Likewise. (java_class_name_from_physname): Likewise. * jv-typeprint.c (java_type_print_base): Likewise. * jv-valprint.c (java_value_print): Likewise. * language.c (add_language): Likewise. * linespec.c (add_sal_to_sals_basic): Likewise. (add_sal_to_sals): Likewise. (decode_objc): Likewise. (find_linespec_symbols): Likewise. * linux-fork.c (fork_save_infrun_state): Likewise. * linux-nat.c (linux_nat_detach): Likewise. (linux_nat_fileio_readlink): Likewise. * linux-record.c (record_linux_sockaddr): Likewise. (record_linux_msghdr): Likewise. (Do): Likewise. * linux-tdep.c (linux_core_info_proc_mappings): Likewise. (linux_collect_regset_section_cb): Likewise. (linux_get_siginfo_data): Likewise. * linux-thread-db.c (try_thread_db_load_from_pdir_1): Likewise. (try_thread_db_load_from_dir): Likewise. (thread_db_load_search): Likewise. (info_auto_load_libthread_db): Likewise. * m32c-tdep.c (m32c_m16c_address_to_pointer): Likewise. (m32c_m16c_pointer_to_address): Likewise. * m68hc11-tdep.c (m68hc11_pseudo_register_write): Likewise. * m68k-tdep.c (m68k_get_longjmp_target): Likewise. * machoread.c (macho_check_dsym): Likewise. * macroexp.c (resize_buffer): Likewise. (gather_arguments): Likewise. (maybe_expand): Likewise. * macrotab.c (new_macro_key): Likewise. (new_source_file): Likewise. (new_macro_definition): Likewise. * mdebugread.c (parse_symbol): Likewise. (parse_type): Likewise. (parse_partial_symbols): Likewise. (psymtab_to_symtab_1): Likewise. * mem-break.c (default_memory_insert_breakpoint): Likewise. * mi/mi-cmd-break.c (mi_argv_to_format): Likewise. * mi/mi-main.c (mi_cmd_data_read_memory): Likewise. (mi_cmd_data_read_memory_bytes): Likewise. (mi_cmd_data_write_memory_bytes): Likewise. (mi_cmd_trace_frame_collected): Likewise. * mi/mi-parse.c (mi_parse_argv): Likewise. (mi_parse): Likewise. * minidebug.c (lzma_open): Likewise. (lzma_pread): Likewise. * mips-tdep.c (mips_read_fp_register_single): Likewise. (mips_print_fp_register): Likewise. * mipsnbsd-tdep.c (mipsnbsd_get_longjmp_target): Likewise. * mipsread.c (read_alphacoff_dynamic_symtab): Likewise. * mt-tdep.c (mt_register_name): Likewise. (mt_registers_info): Likewise. (mt_push_dummy_call): Likewise. * namespace.c (add_using_directive): Likewise. * nat/linux-btrace.c (perf_event_read): Likewise. (linux_enable_bts): Likewise. * nat/linux-osdata.c (linux_common_core_of_thread): Likewise. * nat/linux-ptrace.c (linux_ptrace_test_ret_to_nx): Likewise. * nto-tdep.c (nto_find_and_open_solib): Likewise. (nto_parse_redirection): Likewise. * objc-lang.c (objc_demangle): Likewise. (find_methods): Likewise. * objfiles.c (get_objfile_bfd_data): Likewise. (set_objfile_main_name): Likewise. (allocate_objfile): Likewise. (objfile_relocate): Likewise. (update_section_map): Likewise. * osabi.c (generic_elf_osabi_sniff_abi_tag_sections): Likewise. * p-exp.y (exp): Likewise. (yylex): Likewise. * p-valprint.c (pascal_object_print_value): Likewise. * parse.c (initialize_expout): Likewise. (mark_completion_tag): Likewise. (copy_name): Likewise. (parse_float): Likewise. (type_stack_reserve): Likewise. * ppc-linux-tdep.c (ppc_stap_parse_special_token): Likewise. (ppu2spu_prev_register): Likewise. * ppc-ravenscar-thread.c (supply_register_at_address): Likewise. * printcmd.c (printf_wide_c_string): Likewise. (printf_pointer): Likewise. * probe.c (parse_probes): Likewise. * python/py-cmd.c (gdbpy_parse_command_name): Likewise. (cmdpy_init): Likewise. * python/py-gdb-readline.c (gdbpy_readline_wrapper): Likewise. * python/py-symtab.c (set_sal): Likewise. * python/py-unwind.c (pyuw_sniffer): Likewise. * python/python.c (python_interactive_command): Likewise. (compute_python_string): Likewise. * ravenscar-thread.c (get_running_thread_id): Likewise. * record-full.c (record_full_exec_insn): Likewise. (record_full_core_open_1): Likewise. * regcache.c (regcache_raw_read_signed): Likewise. (regcache_raw_read_unsigned): Likewise. (regcache_cooked_read_signed): Likewise. (regcache_cooked_read_unsigned): Likewise. * remote-fileio.c (remote_fileio_func_open): Likewise. (remote_fileio_func_rename): Likewise. (remote_fileio_func_unlink): Likewise. (remote_fileio_func_stat): Likewise. (remote_fileio_func_system): Likewise. * remote-mips.c (mips_xfer_memory): Likewise. (mips_load_srec): Likewise. (pmon_end_download): Likewise. * remote.c (new_remote_state): Likewise. (map_regcache_remote_table): Likewise. (remote_register_number_and_offset): Likewise. (init_remote_state): Likewise. (get_memory_packet_size): Likewise. (remote_pass_signals): Likewise. (remote_program_signals): Likewise. (remote_start_remote): Likewise. (remote_check_symbols): Likewise. (remote_query_supported): Likewise. (extended_remote_attach): Likewise. (process_g_packet): Likewise. (store_registers_using_G): Likewise. (putpkt_binary): Likewise. (read_frame): Likewise. (compare_sections_command): Likewise. (remote_hostio_pread): Likewise. (remote_hostio_readlink): Likewise. (remote_file_put): Likewise. (remote_file_get): Likewise. (remote_pid_to_exec_file): Likewise. (_initialize_remote): Likewise. * rs6000-aix-tdep.c (rs6000_aix_ld_info_to_xml): Likewise. (rs6000_aix_core_xfer_shared_libraries_aix): Likewise. * rs6000-tdep.c (ppc_displaced_step_copy_insn): Likewise. (bfd_uses_spe_extensions): Likewise. * s390-linux-tdep.c (s390_displaced_step_copy_insn): Likewise. * score-tdep.c (score7_malloc_and_get_memblock): Likewise. * solib-dsbt.c (decode_loadmap): Likewise. (fetch_loadmap): Likewise. (scan_dyntag): Likewise. (enable_break): Likewise. (dsbt_relocate_main_executable): Likewise. * solib-frv.c (fetch_loadmap): Likewise. (enable_break2): Likewise. (frv_relocate_main_executable): Likewise. * solib-spu.c (spu_relocate_main_executable): Likewise. (spu_bfd_open): Likewise. * solib-svr4.c (lm_info_read): Likewise. (read_program_header): Likewise. (find_program_interpreter): Likewise. (scan_dyntag): Likewise. (elf_locate_base): Likewise. (open_symbol_file_object): Likewise. (read_program_headers_from_bfd): Likewise. (svr4_relocate_main_executable): Likewise. * solib-target.c (solib_target_relocate_section_addresses): Likewise. * solib.c (solib_find_1): Likewise. (exec_file_find): Likewise. (solib_find): Likewise. * source.c (openp): Likewise. (print_source_lines_base): Likewise. (forward_search_command): Likewise. * sparc-ravenscar-thread.c (supply_register_at_address): Likewise. * spu-tdep.c (spu2ppu_prev_register): Likewise. (spu_get_overlay_table): Likewise. * stabsread.c (patch_block_stabs): Likewise. (define_symbol): Likewise. (again:): Likewise. (read_member_functions): Likewise. (read_one_struct_field): Likewise. (read_enum_type): Likewise. (common_block_start): Likewise. * stack.c (read_frame_arg): Likewise. (backtrace_command): Likewise. * stap-probe.c (stap_parse_register_operand): Likewise. * symfile.c (syms_from_objfile_1): Likewise. (find_separate_debug_file): Likewise. (load_command): Likewise. (load_progress): Likewise. (load_section_callback): Likewise. (reread_symbols): Likewise. (add_filename_language): Likewise. (allocate_compunit_symtab): Likewise. (read_target_long_array): Likewise. (simple_read_overlay_table): Likewise. * symtab.c (symbol_set_names): Likewise. (resize_symbol_cache): Likewise. (rbreak_command): Likewise. (completion_list_add_name): Likewise. (completion_list_objc_symbol): Likewise. (add_filename_to_list): Likewise. * target-descriptions.c (maint_print_c_tdesc_cmd): Likewise. * target-memory.c (target_write_memory_blocks): Likewise. * target.c (target_read_string): Likewise. (read_whatever_is_readable): Likewise. (target_read_alloc_1): Likewise. (simple_search_memory): Likewise. (target_fileio_read_alloc_1): Likewise. * tilegx-tdep.c (tilegx_push_dummy_call): Likewise. * top.c (command_line_input): Likewise. * tracefile-tfile.c (tfile_fetch_registers): Likewise. * tracefile.c (tracefile_fetch_registers): Likewise. * tracepoint.c (add_memrange): Likewise. (init_collection_list): Likewise. (add_aexpr): Likewise. (trace_dump_actions): Likewise. (parse_trace_status): Likewise. (parse_tracepoint_definition): Likewise. (parse_tsv_definition): Likewise. (parse_static_tracepoint_marker_definition): Likewise. * tui/tui-file.c (tui_sfileopen): Likewise. (tui_file_adjust_strbuf): Likewise. * tui/tui-io.c (tui_expand_tabs): Likewise. * tui/tui-source.c (tui_set_source_content): Likewise. * typeprint.c (find_global_typedef): Likewise. * ui-file.c (do_ui_file_xstrdup): Likewise. (ui_file_obsavestring): Likewise. (mem_file_write): Likewise. * utils.c (make_hex_string): Likewise. (get_regcomp_error): Likewise. (puts_filtered_tabular): Likewise. (gdb_realpath_keepfile): Likewise. (ldirname): Likewise. (gdb_bfd_errmsg): Likewise. (substitute_path_component): Likewise. * valops.c (search_struct_method): Likewise. (find_oload_champ_namespace_loop): Likewise. * valprint.c (print_decimal_chars): Likewise. (read_string): Likewise. (generic_emit_char): Likewise. * varobj.c (varobj_delete): Likewise. (varobj_value_get_print_value): Likewise. * vaxobsd-tdep.c (vaxobsd_sigtramp_sniffer): Likewise. * windows-tdep.c (display_one_tib): Likewise. * xcoffread.c (read_xcoff_symtab): Likewise. (process_xcoff_symbol): Likewise. (swap_sym): Likewise. (scan_xcoff_symtab): Likewise. (xcoff_initial_scan): Likewise. * xml-support.c (gdb_xml_end_element): Likewise. (xml_process_xincludes): Likewise. (xml_fetch_content_from_file): Likewise. * xml-syscall.c (xml_list_of_syscalls): Likewise. * xstormy16-tdep.c (xstormy16_push_dummy_call): Likewise. gdb/gdbserver/ChangeLog: * ax.c (gdb_parse_agent_expr): Add cast to allocation result assignment. (gdb_unparse_agent_expr): Likewise. * hostio.c (require_data): Likewise. (handle_pread): Likewise. * linux-low.c (disable_regset): Likewise. (fetch_register): Likewise. (store_register): Likewise. (get_dynamic): Likewise. (linux_qxfer_libraries_svr4): Likewise. * mem-break.c (delete_fast_tracepoint_jump): Likewise. (set_fast_tracepoint_jump): Likewise. (uninsert_fast_tracepoint_jumps_at): Likewise. (reinsert_fast_tracepoint_jumps_at): Likewise. (validate_inserted_breakpoint): Likewise. (clone_agent_expr): Likewise. * regcache.c (init_register_cache): Likewise. * remote-utils.c (putpkt_binary_1): Likewise. (decode_M_packet): Likewise. (decode_X_packet): Likewise. (look_up_one_symbol): Likewise. (relocate_instruction): Likewise. (monitor_output): Likewise. * server.c (handle_search_memory): Likewise. (handle_qxfer_exec_file): Likewise. (handle_qxfer_libraries): Likewise. (handle_qxfer): Likewise. (handle_query): Likewise. (handle_v_cont): Likewise. (handle_v_run): Likewise. (captured_main): Likewise. * target.c (write_inferior_memory): Likewise. * thread-db.c (try_thread_db_load_from_dir): Likewise. * tracepoint.c (init_trace_buffer): Likewise. (add_tracepoint_action): Likewise. (add_traceframe): Likewise. (add_traceframe_block): Likewise. (cmd_qtdpsrc): Likewise. (cmd_qtdv): Likewise. (cmd_qtstatus): Likewise. (response_source): Likewise. (response_tsv): Likewise. (cmd_qtnotes): Likewise. (gdb_collect): Likewise. (initialize_tracepoint): Likewise.
2015-09-25 20:08:06 +02:00
char *str = (char *) alloca (strlen (command_str) + 1);
strcpy (str, command_str);
2003-02-06 06:30:17 +01:00
/* 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.
2003-02-06 06:30:17 +01:00
It is important that it gets reset everytime, since the user
could set gdb to use a different interpreter. */
2003-02-06 06:30:17 +01:00
old_stream = cli_out_set_stream (cli_uiout, gdb_stdout);
result = safe_execute_command (cli_uiout, str, 1);
cli_out_set_stream (cli_uiout, old_stream);
return result;
}
static struct gdb_exception
safe_execute_command (struct ui_out *command_uiout, char *command, int from_tty)
2003-02-06 06:30:17 +01:00
{
Normalize TRY_CATCH exception handling block This normalizes some exception catch blocks that check for ex.reason to look like this: ~~~ volatile gdb_exception ex; TRY_CATCH (ex, RETURN_MASK_ALL) { ... } if (ex.reason < 0) { ... } ~~~ This is a preparation step for running a script that converts all TRY_CATCH uses to look like this instead: ~~~ TRY { ... } CATCH (ex, RETURN_MASK_ALL) { ... } END_CATCH ~~~ The motivation for that change is being able to reimplent TRY/CATCH in terms of C++ try/catch. This commit makes it so that: - no condition other than ex.reason < 0 is checked in the if predicate - there's no "else" block to check whether no exception was caught - there's no code between the TRY_CATCH (TRY) block and the 'if (ex.reason < 0)' block (CATCH). - the exception object is no longer referred to outside the if/catch block. Note the local volatile exception objects that are currently defined inside functions that use TRY_CATCH will disappear. In cases it's more convenient to still refer to the exception outside the catch block, a new non-volatile local is added and copy to that object is made within the catch block. The following patches should make this all clearer. gdb/ChangeLog: 2015-03-07 Pedro Alves <palves@redhat.com> * amd64-tdep.c (amd64_frame_cache, amd64_sigtramp_frame_cache) (amd64_epilogue_frame_cache): Normal exception handling code. * break-catch-throw.c (check_status_exception_catchpoint) (re_set_exception_catchpoint): Ditto. * cli/cli-interp.c (safe_execute_command): * cli/cli-script.c (script_from_file): Ditto. * compile/compile-c-symbols.c (generate_c_for_for_one_variable): Ditto. * compile/compile-object-run.c (compile_object_run): Ditto. * cp-abi.c (baseclass_offset): Ditto. * cp-valprint.c (cp_print_value): Ditto. * exceptions.c (catch_exceptions_with_msg): * frame-unwind.c (frame_unwind_try_unwinder): Ditto. * frame.c (get_frame_address_in_block_if_available): Ditto. * i386-tdep.c (i386_frame_cache, i386_epilogue_frame_cache) (i386_sigtramp_frame_cache): Ditto. * infcmd.c (post_create_inferior): Ditto. * linespec.c (parse_linespec, find_linespec_symbols): * p-valprint.c (pascal_object_print_value): Ditto. * parse.c (parse_expression_for_completion): Ditto. * python/py-finishbreakpoint.c (bpfinishpy_init): Ditto. * remote.c (remote_get_noisy_reply): Ditto. * s390-linux-tdep.c (s390_frame_unwind_cache): Ditto. * solib-svr4.c (solib_svr4_r_map): Ditto.
2015-03-07 15:50:04 +01:00
struct gdb_exception e = exception_none;
struct ui_out *saved_uiout;
/* Save and override the global ``struct ui_out'' builder. */
2011-08-04 Pedro Alves <pedro@codesourcery.com> * ui-out.h (uiout): Rename to ... (current_uiout): ... this. * ui-out.c (uiout): Rename to ... (current_uiout): ... this. * ada-lang.c (print_it_exception, print_one_exception) (print_mention_exception): Adjust. * breakpoint.c (watchpoint_check): Adjust. (print_breakpoint_location, print_one_breakpoint, breakpoint_1) (default_collect_info, watchpoints_info, print_one_catch_fork) (print_one_catch_vfork, print_one_catch_syscall) (print_one_catch_exec, mention, print_it_ranged_breakpoint) (print_one_ranged_breakpoint, print_mention_ranged_breakpoint) (print_it_watchpoint, print_mention_watchpoint) (print_it_masked_watchpoint, print_mention_masked_watchpoint) (print_it_exception_catchpoint, print_one_exception_catchpoint) (print_mention_exception_catchpoint, say_where, bkpt_print_it) (bkpt_print_mention, momentary_bkpt_print_it) (tracepoint_print_mention, update_static_tracepoint) (tracepoints_info, save_breakpoints): Adjust. * cli-out.c (field_separator): Adjust. * cp-abi.c (list_cp_abis, show_cp_abi_cmd): Adjust. * exceptions.c (catch_exceptions_with_msg, catch_errors): Adjust. * frame.c (get_current_frame): Adjust. * infcmd.c (run_command_1, print_return_value): Adjust. * inferior.c (inferior_command, info_inferiors_command): Adjust. * infrun.c (print_end_stepping_range_reason): Adjust. (print_signal_exited_reason, print_exited_reason): Adjust. (print_signal_received_reason, print_no_history_reason): Adjust. * interps.c (interp_set): Adjust. * osdata.c (info_osdata_command): Adjust. * progspace.c (maintenance_info_program_spaces_command): Adjust. * remote-fileio.c (remote_fileio_request): Adjust. * remote.c (show_remote_cmd): Adjust. * solib.c (info_sharedlibrary_command): Adjust. * source.c (print_source_lines_base): Adjust. * stack.c (print_stack_frame): Adjust. (do_gdb_disassembly, print_frame_info, print_frame): Adjust. * symfile-mem.c (add_vsyscall_page): Adjust. * symfile.c (load_progress, generic_load) (print_transfer_performance): Adjust. * thread.c (info_threads_command, restore_selected_frame) (thread_command): Adjust. * top.c (make_cleanup_restore_ui_file): Adjust. * tracepoint.c (tvariables_info_1, trace_status_mi, tfind_1) (print_one_static_tracepoint_marker): Adjust. * cli/cli-cmds.c (print_disassembly): Adjust. * cli/cli-decode.c (print_doc_line): Adjust. * cli/cli-interp.c (safe_execute_command): Adjust. * cli/cli-logging.c (set_logging_redirect, pop_output_files) (handle_redirections): Adjust. * cli/cli-script.c (show_user_1): Adjust. * cli/cli-setshow.c (do_setshow_command, cmd_show_list): Adjust. * mi/mi-cmd-break.c (breakpoint_notify): Adjust. * mi/mi-cmd-disas.c (mi_cmd_disassemble): Adjust. * mi/mi-cmd-env.c (mi_cmd_env_pwd, mi_cmd_env_path) (mi_cmd_env_dir): Adjust. * mi/mi-cmd-file.c (mi_cmd_file_list_exec_source_file) (print_partial_file_name, mi_cmd_file_list_exec_source_files): Adjust. * mi/mi-cmd-stack.c (mi_cmd_stack_list_frames) (mi_cmd_stack_info_depth, mi_cmd_stack_list_args) (list_args_or_locals): Adjust. * mi/mi-cmd-var.c (print_varobj, mi_cmd_var_create) (mi_cmd_var_delete, mi_cmd_var_set_format, mi_cmd_var_set_frozen) (mi_cmd_var_show_format, mi_cmd_var_info_num_children) (mi_cmd_var_list_children, mi_cmd_var_info_type) (mi_cmd_var_info_path_expression, mi_cmd_var_info_expression) (mi_cmd_var_show_attributes, mi_cmd_var_evaluate_expression) (mi_cmd_var_assign, mi_cmd_var_update, varobj_update_one): Adjust. * mi/mi-interp.c (mi_on_normal_stop): Adjust. * mi/mi-main.c (mi_cmd_gdb_exit, mi_cmd_thread_select) (mi_cmd_thread_list_ids, mi_cmd_thread_info, print_one_inferior) (list_available_thread_groups, mi_cmd_list_thread_groups) (mi_cmd_data_list_register_names) (mi_cmd_data_list_changed_registers) (mi_cmd_data_list_register_values, get_register) (mi_cmd_data_evaluate_expression, mi_cmd_data_read_memory) (mi_cmd_data_read_memory_bytes, mi_cmd_list_features) (mi_cmd_list_target_features, mi_cmd_add_inferior) (mi_execute_command, mi_load_progress): Adjust. * mi/mi-symbol-cmds.c (mi_cmd_symbol_list_lines): Adjust. * python/py-auto-load.c (print_script, info_auto_load_scripts): Adjust. * python/py-breakpoint.c (bppy_get_commands): Adjust. * tui/tui-interp.c (tui_command_loop): Adjust. * tui/tui-io.c (tui_setup_io, tui_initialize_io): Adjust.
2011-08-04 21:10:14 +02:00
saved_uiout = current_uiout;
current_uiout = command_uiout;
Split TRY_CATCH into TRY + CATCH This patch splits the TRY_CATCH macro into three, so that we go from this: ~~~ volatile gdb_exception ex; TRY_CATCH (ex, RETURN_MASK_ERROR) { } if (ex.reason < 0) { } ~~~ to this: ~~~ TRY { } CATCH (ex, RETURN_MASK_ERROR) { } END_CATCH ~~~ Thus, we'll be getting rid of the local volatile exception object, and declaring the caught exception in the catch block. This allows reimplementing TRY/CATCH in terms of C++ exceptions when building in C++ mode, while still allowing to build GDB in C mode (using setjmp/longjmp), as a transition step. TBC, after this patch, is it _not_ valid to have code between the TRY and the CATCH blocks, like: TRY { } // some code here. CATCH (ex, RETURN_MASK_ERROR) { } END_CATCH Just like it isn't valid to do that with C++'s native try/catch. By switching to creating the exception object inside the CATCH block scope, we can get rid of all the explicitly allocated volatile exception objects all over the tree, and map the CATCH block more directly to C++'s catch blocks. The majority of the TRY_CATCH -> TRY+CATCH+END_CATCH conversion was done with a script, rerun from scratch at every rebase, no manual editing involved. After the mechanical conversion, a few places needed manual intervention, to fix preexisting cases where we were using the exception object outside of the TRY_CATCH block, and cases where we were using "else" after a 'if (ex.reason) < 0)' [a CATCH after this patch]. The result was folded into this patch so that GDB still builds at each incremental step. END_CATCH is necessary for two reasons: First, because we name the exception object in the CATCH block, which requires creating a scope, which in turn must be closed somewhere. Declaring the exception variable in the initializer field of a for block, like: #define CATCH(EXCEPTION, mask) \ for (struct gdb_exception EXCEPTION; \ exceptions_state_mc_catch (&EXCEPTION, MASK); \ EXCEPTION = exception_none) would avoid needing END_CATCH, but alas, in C mode, we build with C90, which doesn't allow mixed declarations and code. Second, because when TRY/CATCH are wired to real C++ try/catch, as long as we need to handle cleanup chains, even if there's no CATCH block that wants to catch the exception, we need for stop at every frame in the unwind chain and run cleanups, then rethrow. That will be done in END_CATCH. After we require C++, we'll still need TRY/CATCH/END_CATCH until cleanups are completely phased out -- TRY/CATCH in C++ mode will save/restore the current cleanup chain, like in C mode, and END_CATCH catches otherwise uncaugh exceptions, runs cleanups and rethrows, so that C++ cleanups and exceptions can coexist. IMO, this still makes the TRY/CATCH code look a bit more like a newcomer would expect, so IMO worth it even if we weren't considering C++. gdb/ChangeLog. 2015-03-07 Pedro Alves <palves@redhat.com> * common/common-exceptions.c (struct catcher) <exception>: No longer a pointer to volatile exception. Now an exception value. <mask>: Delete field. (exceptions_state_mc_init): Remove all parameters. Adjust. (exceptions_state_mc): No longer pop the catcher here. (exceptions_state_mc_catch): New function. (throw_exception): Adjust. * common/common-exceptions.h (exceptions_state_mc_init): Remove all parameters. (exceptions_state_mc_catch): Declare. (TRY_CATCH): Rename to ... (TRY): ... this. Remove EXCEPTION and MASK parameters. (CATCH, END_CATCH): New. All callers adjusted. gdb/gdbserver/ChangeLog: 2015-03-07 Pedro Alves <palves@redhat.com> Adjust all callers of TRY_CATCH to use TRY/CATCH/END_CATCH instead.
2015-03-07 16:14:14 +01:00
TRY
{
execute_command (command, from_tty);
}
Split TRY_CATCH into TRY + CATCH This patch splits the TRY_CATCH macro into three, so that we go from this: ~~~ volatile gdb_exception ex; TRY_CATCH (ex, RETURN_MASK_ERROR) { } if (ex.reason < 0) { } ~~~ to this: ~~~ TRY { } CATCH (ex, RETURN_MASK_ERROR) { } END_CATCH ~~~ Thus, we'll be getting rid of the local volatile exception object, and declaring the caught exception in the catch block. This allows reimplementing TRY/CATCH in terms of C++ exceptions when building in C++ mode, while still allowing to build GDB in C mode (using setjmp/longjmp), as a transition step. TBC, after this patch, is it _not_ valid to have code between the TRY and the CATCH blocks, like: TRY { } // some code here. CATCH (ex, RETURN_MASK_ERROR) { } END_CATCH Just like it isn't valid to do that with C++'s native try/catch. By switching to creating the exception object inside the CATCH block scope, we can get rid of all the explicitly allocated volatile exception objects all over the tree, and map the CATCH block more directly to C++'s catch blocks. The majority of the TRY_CATCH -> TRY+CATCH+END_CATCH conversion was done with a script, rerun from scratch at every rebase, no manual editing involved. After the mechanical conversion, a few places needed manual intervention, to fix preexisting cases where we were using the exception object outside of the TRY_CATCH block, and cases where we were using "else" after a 'if (ex.reason) < 0)' [a CATCH after this patch]. The result was folded into this patch so that GDB still builds at each incremental step. END_CATCH is necessary for two reasons: First, because we name the exception object in the CATCH block, which requires creating a scope, which in turn must be closed somewhere. Declaring the exception variable in the initializer field of a for block, like: #define CATCH(EXCEPTION, mask) \ for (struct gdb_exception EXCEPTION; \ exceptions_state_mc_catch (&EXCEPTION, MASK); \ EXCEPTION = exception_none) would avoid needing END_CATCH, but alas, in C mode, we build with C90, which doesn't allow mixed declarations and code. Second, because when TRY/CATCH are wired to real C++ try/catch, as long as we need to handle cleanup chains, even if there's no CATCH block that wants to catch the exception, we need for stop at every frame in the unwind chain and run cleanups, then rethrow. That will be done in END_CATCH. After we require C++, we'll still need TRY/CATCH/END_CATCH until cleanups are completely phased out -- TRY/CATCH in C++ mode will save/restore the current cleanup chain, like in C mode, and END_CATCH catches otherwise uncaugh exceptions, runs cleanups and rethrows, so that C++ cleanups and exceptions can coexist. IMO, this still makes the TRY/CATCH code look a bit more like a newcomer would expect, so IMO worth it even if we weren't considering C++. gdb/ChangeLog. 2015-03-07 Pedro Alves <palves@redhat.com> * common/common-exceptions.c (struct catcher) <exception>: No longer a pointer to volatile exception. Now an exception value. <mask>: Delete field. (exceptions_state_mc_init): Remove all parameters. Adjust. (exceptions_state_mc): No longer pop the catcher here. (exceptions_state_mc_catch): New function. (throw_exception): Adjust. * common/common-exceptions.h (exceptions_state_mc_init): Remove all parameters. (exceptions_state_mc_catch): Declare. (TRY_CATCH): Rename to ... (TRY): ... this. Remove EXCEPTION and MASK parameters. (CATCH, END_CATCH): New. All callers adjusted. gdb/gdbserver/ChangeLog: 2015-03-07 Pedro Alves <palves@redhat.com> Adjust all callers of TRY_CATCH to use TRY/CATCH/END_CATCH instead.
2015-03-07 16:14:14 +01:00
CATCH (exception, RETURN_MASK_ALL)
Normalize TRY_CATCH exception handling block This normalizes some exception catch blocks that check for ex.reason to look like this: ~~~ volatile gdb_exception ex; TRY_CATCH (ex, RETURN_MASK_ALL) { ... } if (ex.reason < 0) { ... } ~~~ This is a preparation step for running a script that converts all TRY_CATCH uses to look like this instead: ~~~ TRY { ... } CATCH (ex, RETURN_MASK_ALL) { ... } END_CATCH ~~~ The motivation for that change is being able to reimplent TRY/CATCH in terms of C++ try/catch. This commit makes it so that: - no condition other than ex.reason < 0 is checked in the if predicate - there's no "else" block to check whether no exception was caught - there's no code between the TRY_CATCH (TRY) block and the 'if (ex.reason < 0)' block (CATCH). - the exception object is no longer referred to outside the if/catch block. Note the local volatile exception objects that are currently defined inside functions that use TRY_CATCH will disappear. In cases it's more convenient to still refer to the exception outside the catch block, a new non-volatile local is added and copy to that object is made within the catch block. The following patches should make this all clearer. gdb/ChangeLog: 2015-03-07 Pedro Alves <palves@redhat.com> * amd64-tdep.c (amd64_frame_cache, amd64_sigtramp_frame_cache) (amd64_epilogue_frame_cache): Normal exception handling code. * break-catch-throw.c (check_status_exception_catchpoint) (re_set_exception_catchpoint): Ditto. * cli/cli-interp.c (safe_execute_command): * cli/cli-script.c (script_from_file): Ditto. * compile/compile-c-symbols.c (generate_c_for_for_one_variable): Ditto. * compile/compile-object-run.c (compile_object_run): Ditto. * cp-abi.c (baseclass_offset): Ditto. * cp-valprint.c (cp_print_value): Ditto. * exceptions.c (catch_exceptions_with_msg): * frame-unwind.c (frame_unwind_try_unwinder): Ditto. * frame.c (get_frame_address_in_block_if_available): Ditto. * i386-tdep.c (i386_frame_cache, i386_epilogue_frame_cache) (i386_sigtramp_frame_cache): Ditto. * infcmd.c (post_create_inferior): Ditto. * linespec.c (parse_linespec, find_linespec_symbols): * p-valprint.c (pascal_object_print_value): Ditto. * parse.c (parse_expression_for_completion): Ditto. * python/py-finishbreakpoint.c (bpfinishpy_init): Ditto. * remote.c (remote_get_noisy_reply): Ditto. * s390-linux-tdep.c (s390_frame_unwind_cache): Ditto. * solib-svr4.c (solib_svr4_r_map): Ditto.
2015-03-07 15:50:04 +01:00
{
e = exception;
}
Split TRY_CATCH into TRY + CATCH This patch splits the TRY_CATCH macro into three, so that we go from this: ~~~ volatile gdb_exception ex; TRY_CATCH (ex, RETURN_MASK_ERROR) { } if (ex.reason < 0) { } ~~~ to this: ~~~ TRY { } CATCH (ex, RETURN_MASK_ERROR) { } END_CATCH ~~~ Thus, we'll be getting rid of the local volatile exception object, and declaring the caught exception in the catch block. This allows reimplementing TRY/CATCH in terms of C++ exceptions when building in C++ mode, while still allowing to build GDB in C mode (using setjmp/longjmp), as a transition step. TBC, after this patch, is it _not_ valid to have code between the TRY and the CATCH blocks, like: TRY { } // some code here. CATCH (ex, RETURN_MASK_ERROR) { } END_CATCH Just like it isn't valid to do that with C++'s native try/catch. By switching to creating the exception object inside the CATCH block scope, we can get rid of all the explicitly allocated volatile exception objects all over the tree, and map the CATCH block more directly to C++'s catch blocks. The majority of the TRY_CATCH -> TRY+CATCH+END_CATCH conversion was done with a script, rerun from scratch at every rebase, no manual editing involved. After the mechanical conversion, a few places needed manual intervention, to fix preexisting cases where we were using the exception object outside of the TRY_CATCH block, and cases where we were using "else" after a 'if (ex.reason) < 0)' [a CATCH after this patch]. The result was folded into this patch so that GDB still builds at each incremental step. END_CATCH is necessary for two reasons: First, because we name the exception object in the CATCH block, which requires creating a scope, which in turn must be closed somewhere. Declaring the exception variable in the initializer field of a for block, like: #define CATCH(EXCEPTION, mask) \ for (struct gdb_exception EXCEPTION; \ exceptions_state_mc_catch (&EXCEPTION, MASK); \ EXCEPTION = exception_none) would avoid needing END_CATCH, but alas, in C mode, we build with C90, which doesn't allow mixed declarations and code. Second, because when TRY/CATCH are wired to real C++ try/catch, as long as we need to handle cleanup chains, even if there's no CATCH block that wants to catch the exception, we need for stop at every frame in the unwind chain and run cleanups, then rethrow. That will be done in END_CATCH. After we require C++, we'll still need TRY/CATCH/END_CATCH until cleanups are completely phased out -- TRY/CATCH in C++ mode will save/restore the current cleanup chain, like in C mode, and END_CATCH catches otherwise uncaugh exceptions, runs cleanups and rethrows, so that C++ cleanups and exceptions can coexist. IMO, this still makes the TRY/CATCH code look a bit more like a newcomer would expect, so IMO worth it even if we weren't considering C++. gdb/ChangeLog. 2015-03-07 Pedro Alves <palves@redhat.com> * common/common-exceptions.c (struct catcher) <exception>: No longer a pointer to volatile exception. Now an exception value. <mask>: Delete field. (exceptions_state_mc_init): Remove all parameters. Adjust. (exceptions_state_mc): No longer pop the catcher here. (exceptions_state_mc_catch): New function. (throw_exception): Adjust. * common/common-exceptions.h (exceptions_state_mc_init): Remove all parameters. (exceptions_state_mc_catch): Declare. (TRY_CATCH): Rename to ... (TRY): ... this. Remove EXCEPTION and MASK parameters. (CATCH, END_CATCH): New. All callers adjusted. gdb/gdbserver/ChangeLog: 2015-03-07 Pedro Alves <palves@redhat.com> Adjust all callers of TRY_CATCH to use TRY/CATCH/END_CATCH instead.
2015-03-07 16:14:14 +01:00
END_CATCH
/* Restore the global builder. */
2011-08-04 Pedro Alves <pedro@codesourcery.com> * ui-out.h (uiout): Rename to ... (current_uiout): ... this. * ui-out.c (uiout): Rename to ... (current_uiout): ... this. * ada-lang.c (print_it_exception, print_one_exception) (print_mention_exception): Adjust. * breakpoint.c (watchpoint_check): Adjust. (print_breakpoint_location, print_one_breakpoint, breakpoint_1) (default_collect_info, watchpoints_info, print_one_catch_fork) (print_one_catch_vfork, print_one_catch_syscall) (print_one_catch_exec, mention, print_it_ranged_breakpoint) (print_one_ranged_breakpoint, print_mention_ranged_breakpoint) (print_it_watchpoint, print_mention_watchpoint) (print_it_masked_watchpoint, print_mention_masked_watchpoint) (print_it_exception_catchpoint, print_one_exception_catchpoint) (print_mention_exception_catchpoint, say_where, bkpt_print_it) (bkpt_print_mention, momentary_bkpt_print_it) (tracepoint_print_mention, update_static_tracepoint) (tracepoints_info, save_breakpoints): Adjust. * cli-out.c (field_separator): Adjust. * cp-abi.c (list_cp_abis, show_cp_abi_cmd): Adjust. * exceptions.c (catch_exceptions_with_msg, catch_errors): Adjust. * frame.c (get_current_frame): Adjust. * infcmd.c (run_command_1, print_return_value): Adjust. * inferior.c (inferior_command, info_inferiors_command): Adjust. * infrun.c (print_end_stepping_range_reason): Adjust. (print_signal_exited_reason, print_exited_reason): Adjust. (print_signal_received_reason, print_no_history_reason): Adjust. * interps.c (interp_set): Adjust. * osdata.c (info_osdata_command): Adjust. * progspace.c (maintenance_info_program_spaces_command): Adjust. * remote-fileio.c (remote_fileio_request): Adjust. * remote.c (show_remote_cmd): Adjust. * solib.c (info_sharedlibrary_command): Adjust. * source.c (print_source_lines_base): Adjust. * stack.c (print_stack_frame): Adjust. (do_gdb_disassembly, print_frame_info, print_frame): Adjust. * symfile-mem.c (add_vsyscall_page): Adjust. * symfile.c (load_progress, generic_load) (print_transfer_performance): Adjust. * thread.c (info_threads_command, restore_selected_frame) (thread_command): Adjust. * top.c (make_cleanup_restore_ui_file): Adjust. * tracepoint.c (tvariables_info_1, trace_status_mi, tfind_1) (print_one_static_tracepoint_marker): Adjust. * cli/cli-cmds.c (print_disassembly): Adjust. * cli/cli-decode.c (print_doc_line): Adjust. * cli/cli-interp.c (safe_execute_command): Adjust. * cli/cli-logging.c (set_logging_redirect, pop_output_files) (handle_redirections): Adjust. * cli/cli-script.c (show_user_1): Adjust. * cli/cli-setshow.c (do_setshow_command, cmd_show_list): Adjust. * mi/mi-cmd-break.c (breakpoint_notify): Adjust. * mi/mi-cmd-disas.c (mi_cmd_disassemble): Adjust. * mi/mi-cmd-env.c (mi_cmd_env_pwd, mi_cmd_env_path) (mi_cmd_env_dir): Adjust. * mi/mi-cmd-file.c (mi_cmd_file_list_exec_source_file) (print_partial_file_name, mi_cmd_file_list_exec_source_files): Adjust. * mi/mi-cmd-stack.c (mi_cmd_stack_list_frames) (mi_cmd_stack_info_depth, mi_cmd_stack_list_args) (list_args_or_locals): Adjust. * mi/mi-cmd-var.c (print_varobj, mi_cmd_var_create) (mi_cmd_var_delete, mi_cmd_var_set_format, mi_cmd_var_set_frozen) (mi_cmd_var_show_format, mi_cmd_var_info_num_children) (mi_cmd_var_list_children, mi_cmd_var_info_type) (mi_cmd_var_info_path_expression, mi_cmd_var_info_expression) (mi_cmd_var_show_attributes, mi_cmd_var_evaluate_expression) (mi_cmd_var_assign, mi_cmd_var_update, varobj_update_one): Adjust. * mi/mi-interp.c (mi_on_normal_stop): Adjust. * mi/mi-main.c (mi_cmd_gdb_exit, mi_cmd_thread_select) (mi_cmd_thread_list_ids, mi_cmd_thread_info, print_one_inferior) (list_available_thread_groups, mi_cmd_list_thread_groups) (mi_cmd_data_list_register_names) (mi_cmd_data_list_changed_registers) (mi_cmd_data_list_register_values, get_register) (mi_cmd_data_evaluate_expression, mi_cmd_data_read_memory) (mi_cmd_data_read_memory_bytes, mi_cmd_list_features) (mi_cmd_list_target_features, mi_cmd_add_inferior) (mi_execute_command, mi_load_progress): Adjust. * mi/mi-symbol-cmds.c (mi_cmd_symbol_list_lines): Adjust. * python/py-auto-load.c (print_script, info_auto_load_scripts): Adjust. * python/py-breakpoint.c (bppy_get_commands): Adjust. * tui/tui-interp.c (tui_command_loop): Adjust. * tui/tui-io.c (tui_setup_io, tui_initialize_io): Adjust.
2011-08-04 21:10:14 +02:00
current_uiout = saved_uiout;
/* FIXME: cagney/2005-01-13: This shouldn't be needed. Instead the
caller should print the exception. */
exception_print (gdb_stderr, e);
return e;
2003-02-06 06:30:17 +01:00
}
gdb/ 2011-09-12 Pedro Alves <pedro@codesourcery.com> Matt Rice <ratmice@gmail.com> PR gdb/13175 * interps.c (struct interp) <interpreter_out>: Delete field. (interp_new): Remove the data and uiout parameters and adjust. (interp_set): Only set the current_uiout from the interpreter's uiout after initializing the interpreter. Adjust call to init_proc. (interp_ui_out): Adjust to call procs->ui_out_proc. (interp_data, interp_name): New. * interps.h (interp_init_ftype): Add `self' parameter. (interp_ui_out_ftype): New typedef. (struct interp_procs) <ui_out_proc>: New method pointer. (interp_new): Remove the data and uiout parameters. (interp_data, interp_name): Declare. * tui/tui-interp.c (tui_init): Adjust prototype. (tui_ui_out): New. (_initialize_tui_interp): Install tui_ui_out. Don't instanciate tui_out here. Adjust call to interp_new. * tui/tui-io.c (tui_initialize_io): Don't set current_uiout here. * cli/cli-interp.c (cli_interpreter_init): Adjust prototype. (cli_ui_out): New. (_initialize_cli_interp): Install it. Adjust call to interp_new. * mi/mi-common.h (struct mi_interp) <uiout>: New field. * mi/mi-interp.c (mi_interpreter_init): Adjust prototype. Initialize mi->uiout depending on the mi_version as extracted from the interpreter's name. (mi_ui_out): New. (_initialize_mi_interp): Install mi_ui_out. Adjust calls to interp_new. Don't allocate the ui_out's of the interpreters here. gdb/testsuite/ 2011-09-12 Matt Rice <ratmice@gmail.com> Pedro Alves <pedro@codesourcery.com> PR gdb/13175 * gdb.base/interp.exp: New tests. * gdb.base/interp.c: New file.
2011-09-12 23:25:22 +02:00
static struct ui_out *
cli_ui_out (struct interp *self)
{
return cli_uiout;
}
2003-02-06 06:30:17 +01:00
/* Standard gdb initialization hook. */
2003-06-08 Andrew Cagney <cagney@redhat.com> * acinclude.m4 (gcc_AC_CHECK_DECL, (gcc_AC_CHECK_DECL): Stolen from GCC's acinclude.m4. * configure.in: Check for getopt's delcaration. * aclocal.m4, config.in, configure: Re-generate. * main.c (error_init): Delete declaration. * defs.h (error_init): Declare. * rs6000-tdep.c (rs6000_fetch_pointer_argument): Make static. (rs6000_convert_from_func_ptr_addr): Make static. (_initialize_rs6000_tdep): Add declaration. * cli/cli-cmds.c (dont_repeat): Delete declaration. (show_commands, set_verbose, show_history): Delete declaration. * top.h (set_verbose): Add declaration. (show_history, set_history, show_commands): Add declaration. (do_restore_instream_cleanup): Add declaration. * objc-lang.c (specialcmp): Make static. (print_object_command): Make static. (find_objc_msgsend): Make static. (find_objc_msgcall_submethod_helper): Make static. (find_objc_msgcall_submethod): Make static. (_initialize_objc_language): Add declaration. (find_implementation_from_class): Make static. (find_implementation): Make static. * objc-exp.y (yylex): Delete lookup_struct_typedef declaration. * objc-lang.h (lookup_struct_typedef): Add declaration. * cli/cli-interp.c (_initialize_cli_interp): Add declaration. * cli/cli-script.c (clear_hook_in_cleanup): Make static. (do_restore_user_call_depth): Make static. (do_restore_instream_cleanup): Delete declaration. (dont_repeat): Delete declaration. * cli/cli-decode.c (add_abbrev_cmd): Delete function. * cli/cli-dump.c (_initialize_cli_dump): Add declaration. * reggroups.c (_initialize_reggroup): Add declaration. * cp-support.c (_initialize_cp_support): Add declaration. * cp-abi.c (_initialize_cp_abi): Add declaration. * hpacc-abi.c (_initialize_hpacc_abi): Add declaration. * gnu-v3-abi.c (gnuv3_baseclass_offset): Make static. (_initialize_gnu_v3_abi): Add declaration. * gnu-v2-abi.c (gnuv2_value_rtti_type): Make static. (_initialize_gnu_v2_abi): Add declaration. * frame-base.c (_initialize_frame_base): Add declaration. * doublest.c (floatformat_from_length): Make static. * frame-unwind.c (_initialize_frame_unwind): Add declaration. * frame.c (create_sentinel_frame): Make static. (_initialize_frame): Add declaration. * top.c (do_catch_errors): Make static. (gdb_rl_operate_and_get_next_completion): Make static. * typeprint.c: Include "typeprint.h". * sentinel-frame.c (sentinel_frame_prev_register): Make static. (sentinel_frame_this_id): Make static. * p-valprint.c (_initialize_pascal_valprint): Add declaration. * ui-out.c (make_cleanup_ui_out_begin_end): Delete function. * dwarf2-frame.c (dwarf2_frame_cache): Make static. * p-exp.y (push_current_type, pop_current_type): ISO C declaration. * dwarf2expr.h (dwarf_expr_context): ISO C declaration. * maint.c (maintenance_print_architecture): Make static. * signals/signals.c (_initialize_signals): Add declaration. * std-regs.c (_initialize_frame_reg): Add declaration. * jv-exp.y (push_variable): ISO C definition. (push_qualified_expression_name): Ditto. * memattr.c (_initialize_mem): Add declaration. * remote.c (remote_check_watch_resources): Make static. (remote_stopped_by_watchpoint): Make static. (remote_stopped_data_address): Make static. * d10v-tdep.c (nr_dmap_regs): Make static. (a0_regnum): Make static. (d10v_frame_unwind_cache): Make static. (d10v_frame_p): Make static. * osabi.c (show_osabi): Make static. (_initialize_gdb_osabi): Add extern declaration. * gdbtypes.c (make_qualified_type): Make static. (safe_parse_type): Make static. * macrocmd.c (_initialize_macrocmd): Add extern declaration. * macrotab.c (macro_bcache_free): Make static. * interps.c (interp_set_quiet): Make static. (interpreter_exec_cmd): Make static. * stack.h (select_frame_command): New file. * stack.c: Include "stack.h". (select_frame_command_wrapper): Delete function. (select_frame_command): Make global. * infcall.c: Include "infcall.h". * linespec.c: Include "linespec.h". * symfile.c (sections_overlap): Make static. * cp-support.h (cp_initialize_namespace): ISO C declaration. * charset.c (_initialize_charset): Add missing prototype. * regcache.c (init_legacy_regcache_descr): Make static. (do_regcache_xfree): Make static. (regcache_xfer_part): Make static. (_initialize_regcache): Add missing prototype. * breakpoint.c (parse_breakpoint_sals): Make static. (breakpoint_sals_to_pc): Make static. * interps.h (clear_interpreter_hooks): ISO C declaration. * Makefile.in (stack_h): Define. (stack.o, typeprint.o, mi-main.o): Update dependencies. (mi-cmd-stack.o, infcall.o, linespec.o): Update dependencies. Index: mi/ChangeLog 2003-06-08 Andrew Cagney <cagney@redhat.com> * mi-parse.c (_initialize_mi_parse): Delete function. * mi-main.c: Include "mi-main.h". * mi-interp.c (_initialize_mi_interp): Add declaration. * mi-cmd-stack.c: Include "stack.h". (select_frame_command_wrapper): Delete extern declaration. (mi_cmd_stack_select_frame): Replace select_frame_command_wrapper with select_frame_command.
2003-06-08 20:27:14 +02:00
extern initialize_file_ftype _initialize_cli_interp; /* -Wmissing-prototypes */
2003-02-06 06:30:17 +01:00
void
_initialize_cli_interp (void)
{
static const struct interp_procs procs = {
cli_interpreter_init, /* init_proc */
cli_interpreter_resume, /* resume_proc */
cli_interpreter_suspend, /* suspend_proc */
cli_interpreter_exec, /* exec_proc */
cli_ui_out, /* ui_out_proc */
NULL, /* set_logging_proc */
cli_command_loop /* command_loop_proc */
2003-02-06 06:30:17 +01:00
};
/* Create a default uiout builder for the CLI. */
2003-02-06 06:30:17 +01:00
cli_uiout = cli_out_new (gdb_stdout);
gdb/ 2011-09-12 Pedro Alves <pedro@codesourcery.com> Matt Rice <ratmice@gmail.com> PR gdb/13175 * interps.c (struct interp) <interpreter_out>: Delete field. (interp_new): Remove the data and uiout parameters and adjust. (interp_set): Only set the current_uiout from the interpreter's uiout after initializing the interpreter. Adjust call to init_proc. (interp_ui_out): Adjust to call procs->ui_out_proc. (interp_data, interp_name): New. * interps.h (interp_init_ftype): Add `self' parameter. (interp_ui_out_ftype): New typedef. (struct interp_procs) <ui_out_proc>: New method pointer. (interp_new): Remove the data and uiout parameters. (interp_data, interp_name): Declare. * tui/tui-interp.c (tui_init): Adjust prototype. (tui_ui_out): New. (_initialize_tui_interp): Install tui_ui_out. Don't instanciate tui_out here. Adjust call to interp_new. * tui/tui-io.c (tui_initialize_io): Don't set current_uiout here. * cli/cli-interp.c (cli_interpreter_init): Adjust prototype. (cli_ui_out): New. (_initialize_cli_interp): Install it. Adjust call to interp_new. * mi/mi-common.h (struct mi_interp) <uiout>: New field. * mi/mi-interp.c (mi_interpreter_init): Adjust prototype. Initialize mi->uiout depending on the mi_version as extracted from the interpreter's name. (mi_ui_out): New. (_initialize_mi_interp): Install mi_ui_out. Adjust calls to interp_new. Don't allocate the ui_out's of the interpreters here. gdb/testsuite/ 2011-09-12 Matt Rice <ratmice@gmail.com> Pedro Alves <pedro@codesourcery.com> PR gdb/13175 * gdb.base/interp.exp: New tests. * gdb.base/interp.c: New file.
2011-09-12 23:25:22 +02:00
cli_interp = interp_new (INTERP_CONSOLE, &procs);
2003-02-06 06:30:17 +01:00
interp_add (cli_interp);
}