From 352a134dbc95cd3ee0b0a1f0dc38321718354eb7 Mon Sep 17 00:00:00 2001 From: Vladimir Prus Date: Thu, 24 Apr 2008 11:13:44 +0000 Subject: exec_cleanup murder. * breakpoint.c (until_break_command_continuation): Add the 'error' parameter. Directly delete the breakoint as opposed to running cleanups. (until_break_command): Install continuation only after starting the target. Don't use exec cleanups, use ordinary cleanups. Discard cleanups is successfully started the target in async mode. (make_cleanup_delete_breakpoint): Remove. * breakpoint.h (make_cleanup_delete_breakpoint): Remove declaration. * defs.h (do_exec_cleanups, make_exec_cleanup): Remove declarations. (struct continations): Add the 'error' parameter to the continuation_hook field. (add_continuation, do_all_continuations) (add_intermediate_continuation) (do_all_intermediate_continuations): Add the 'error' parameter. * exceptions.c (throw_exception): Don't call do_exec_cleanups. * inf-loop.c (inferior_event_handler): Instead of calling discard_all_continuations, use do_all_continuations with 1 as 'error' parameter. Pass 0 as 'error' parameter in existing uses of discard_all_continuations. * infcmd.c (step_1): Do not use exec cleanup. For async case, discard cleanups. (step_once): Install continuation only after resuming the target. (step_1_continuation): Disable longjmp breakpoint on error. (finish_command_continuation): Add the error parameter. Delete the finish breakpoint directly, do not use cleanups. (finish_command): Do not use exec_cleanups. Always setup continuation. For sync case, immediately run them. (attach_command_continuation): Add the error parameter. * infrun.c (fetch_inferior_event): Do not use exec cleanups to remove step_resume_breakpoint -- adjust delete it directly. * interps.c (interp_set): Adjust call to do_all_continations. * mi/mi-interp.c (mi_interpreter_exec_continuation): Do not do exec cleanups. * mi/mi-main.c (mi_cmd_target_select): Do not do exec cleanups. (mi_cmd_execute): Do not use exec_cleanup. (mi_execute_async_cli_command): Simplify the string concatenation logic. Do no use exec cleanup. (mi_exec_async_cli_cmd_continuation): New parameter error. Free last_async_command. * top.c (command_line_handler_continuation): New parameter error. * utils.c (exec_cleanup_chain, make_exec_cleanup) (do_exec_cleanups): Remove. (add_continuation, do_all_continations) (add_intermediate_continuation) (do_all_intermediate_continuations): New parameter error. --- gdb/infcmd.c | 145 +++++++++++++++++++++++++---------------------------------- 1 file changed, 62 insertions(+), 83 deletions(-) (limited to 'gdb/infcmd.c') diff --git a/gdb/infcmd.c b/gdb/infcmd.c index 22a4abb7ec1..867dadf5cce 100644 --- a/gdb/infcmd.c +++ b/gdb/infcmd.c @@ -72,7 +72,8 @@ static void nofp_registers_info (char *, int); static void print_return_value (struct type *func_type, struct type *value_type); -static void finish_command_continuation (struct continuation_arg *); +static void finish_command_continuation (struct continuation_arg *, + int error_p); static void until_next_command (int); @@ -106,7 +107,7 @@ static void jump_command (char *, int); static void step_1 (int, int, char *); static void step_once (int skip_subroutines, int single_inst, int count); -static void step_1_continuation (struct continuation_arg *arg); +static void step_1_continuation (struct continuation_arg *arg, int error_p); static void next_command (char *, int); @@ -701,7 +702,7 @@ step_1 (int skip_subroutines, int single_inst, char *count_string) { int count = 1; struct frame_info *frame; - struct cleanup *cleanups = 0; + struct cleanup *cleanups = make_cleanup (null_cleanup, NULL); int async_exec = 0; ERROR_NO_INFERIOR; @@ -727,10 +728,7 @@ step_1 (int skip_subroutines, int single_inst, char *count_string) if (!single_inst || skip_subroutines) /* leave si command alone */ { enable_longjmp_breakpoint (); - if (!target_can_async_p ()) - cleanups = make_cleanup (disable_longjmp_breakpoint_cleanup, 0 /*ignore*/); - else - make_exec_cleanup (disable_longjmp_breakpoint_cleanup, 0 /*ignore*/); + make_cleanup (disable_longjmp_breakpoint_cleanup, 0 /*ignore*/); } /* In synchronous case, all is well, just use the regular for loop. */ @@ -782,8 +780,7 @@ which has no line number information.\n"), name); break; } - if (!single_inst || skip_subroutines) - do_cleanups (cleanups); + do_cleanups (cleanups); return; } /* In case of asynchronous target things get complicated, do only @@ -792,8 +789,10 @@ which has no line number information.\n"), name); and handle them one at the time, through step_once(). */ else { - if (target_can_async_p ()) - step_once (skip_subroutines, single_inst, count); + step_once (skip_subroutines, single_inst, count); + /* We are running, and the contination is installed. It will + disable the longjmp breakpoint as appropriate. */ + discard_cleanups (cleanups); } } @@ -803,21 +802,26 @@ which has no line number information.\n"), name); proceed(), via step_once(). Basically it is like step_once and step_1_continuation are co-recursive. */ static void -step_1_continuation (struct continuation_arg *arg) +step_1_continuation (struct continuation_arg *arg, int error_p) { - int count; - int skip_subroutines; - int single_inst; - - skip_subroutines = arg->data.integer; - single_inst = arg->next->data.integer; - count = arg->next->next->data.integer; - - if (stop_step) - step_once (skip_subroutines, single_inst, count - 1); + if (error_p) + disable_longjmp_breakpoint (); else - if (!single_inst || skip_subroutines) - do_exec_cleanups (ALL_CLEANUPS); + { + int count; + int skip_subroutines; + int single_inst; + + skip_subroutines = arg->data.integer; + single_inst = arg->next->data.integer; + count = arg->next->next->data.integer; + + if (stop_step) + step_once (skip_subroutines, single_inst, count - 1); + else + if (!single_inst || skip_subroutines) + disable_longjmp_breakpoint (); + } } /* Do just one step operation. If count >1 we will have to set up a @@ -881,6 +885,7 @@ which has no line number information.\n"), name); step_over_calls = STEP_OVER_ALL; step_multi = (count > 1); + proceed ((CORE_ADDR) -1, TARGET_SIGNAL_DEFAULT, 1); arg1 = (struct continuation_arg *) xmalloc (sizeof (struct continuation_arg)); arg2 = @@ -894,7 +899,6 @@ which has no line number information.\n"), name); arg3->next = NULL; arg3->data.integer = count; add_intermediate_continuation (step_1_continuation, arg1); - proceed ((CORE_ADDR) -1, TARGET_SIGNAL_DEFAULT, 1); } } @@ -1251,7 +1255,7 @@ print_return_value (struct type *func_type, struct type *value_type) called via the cmd_continuation pointer. */ static void -finish_command_continuation (struct continuation_arg *arg) +finish_command_continuation (struct continuation_arg *arg, int error_p) { struct symbol *function; struct breakpoint *breakpoint; @@ -1261,21 +1265,24 @@ finish_command_continuation (struct continuation_arg *arg) function = (struct symbol *) arg->next->data.pointer; cleanups = (struct cleanup *) arg->next->next->data.pointer; - if (bpstat_find_breakpoint (stop_bpstat, breakpoint) != NULL - && function != NULL) + if (!error_p) { - struct type *value_type; - - value_type = TYPE_TARGET_TYPE (SYMBOL_TYPE (function)); - if (!value_type) - internal_error (__FILE__, __LINE__, - _("finish_command: function has no target type")); - - if (TYPE_CODE (value_type) != TYPE_CODE_VOID) - print_return_value (SYMBOL_TYPE (function), value_type); + if (bpstat_find_breakpoint (stop_bpstat, breakpoint) != NULL + && function != NULL) + { + struct type *value_type; + + value_type = TYPE_TARGET_TYPE (SYMBOL_TYPE (function)); + if (!value_type) + internal_error (__FILE__, __LINE__, + _("finish_command: function has no target type")); + + if (TYPE_CODE (value_type) != TYPE_CODE_VOID) + print_return_value (SYMBOL_TYPE (function), value_type); + } } - do_exec_cleanups (cleanups); + delete_breakpoint (breakpoint); } /* "finish": Set a temporary breakpoint at the place the selected @@ -1326,10 +1333,7 @@ finish_command (char *arg, int from_tty) breakpoint = set_momentary_breakpoint (sal, get_frame_id (frame), bp_finish); - if (!target_can_async_p ()) - old_chain = make_cleanup_delete_breakpoint (breakpoint); - else - old_chain = make_exec_cleanup_delete_breakpoint (breakpoint); + old_chain = make_cleanup_delete_breakpoint (breakpoint); /* Find the function we will return from. */ @@ -1346,51 +1350,26 @@ finish_command (char *arg, int from_tty) proceed_to_finish = 1; /* We want stop_registers, please... */ proceed ((CORE_ADDR) -1, TARGET_SIGNAL_DEFAULT, 0); - /* If running asynchronously and the target support asynchronous - execution, set things up for the rest of the finish command to be - completed later on, when gdb has detected that the target has - stopped, in fetch_inferior_event. - Setup it only after proceed, so that if proceed throws, we don't - set continuation. */ - if (target_can_async_p ()) - { - arg1 = - (struct continuation_arg *) xmalloc (sizeof (struct continuation_arg)); - arg2 = - (struct continuation_arg *) xmalloc (sizeof (struct continuation_arg)); - arg3 = - (struct continuation_arg *) xmalloc (sizeof (struct continuation_arg)); - arg1->next = arg2; - arg2->next = arg3; - arg3->next = NULL; - arg1->data.pointer = breakpoint; - arg2->data.pointer = function; - arg3->data.pointer = old_chain; - add_continuation (finish_command_continuation, arg1); - } + arg1 = + (struct continuation_arg *) xmalloc (sizeof (struct continuation_arg)); + arg2 = + (struct continuation_arg *) xmalloc (sizeof (struct continuation_arg)); + arg3 = + (struct continuation_arg *) xmalloc (sizeof (struct continuation_arg)); + arg1->next = arg2; + arg2->next = arg3; + arg3->next = NULL; + arg1->data.pointer = breakpoint; + arg2->data.pointer = function; + arg3->data.pointer = old_chain; + add_continuation (finish_command_continuation, arg1); /* Do this only if not running asynchronously or if the target cannot do async execution. Otherwise, complete this command when the target actually stops, in fetch_inferior_event. */ + discard_cleanups (old_chain); if (!target_can_async_p ()) - { - /* Did we stop at our breakpoint? */ - if (bpstat_find_breakpoint (stop_bpstat, breakpoint) != NULL - && function != NULL) - { - struct type *value_type; - - value_type = TYPE_TARGET_TYPE (SYMBOL_TYPE (function)); - if (!value_type) - internal_error (__FILE__, __LINE__, - _("finish_command: function has no target type")); - - if (TYPE_CODE (value_type) != TYPE_CODE_VOID) - print_return_value (SYMBOL_TYPE (function), value_type); - } - - do_cleanups (old_chain); - } + do_all_continuations (0); } @@ -1936,7 +1915,7 @@ attach_command_post_wait (char *args, int from_tty, int async_exec) } static void -attach_command_continuation (struct continuation_arg *arg) +attach_command_continuation (struct continuation_arg *arg, int error_p) { char *args; int from_tty; -- cgit v1.2.1