From 37ff521c6cd8ac6fbac642d1daece57f1e1ce460 Mon Sep 17 00:00:00 2001 From: Chungyi Chi Date: Wed, 26 Aug 2020 22:08:43 +0800 Subject: [PATCH] gdb/gdb: Fix advance/until and multiple locations Assume is able to expand to multiple ones and insert a breakpoint for each one. --- gdb/ChangeLog | 5 +++ gdb/breakpoint.c | 108 +++++++++++++++++++++++------------------------ 2 files changed, 58 insertions(+), 55 deletions(-) diff --git a/gdb/ChangeLog b/gdb/ChangeLog index ceff808d82..86827ca7d7 100644 --- a/gdb/ChangeLog +++ b/gdb/ChangeLog @@ -1,3 +1,8 @@ +2020-08-26 Chungyi Chi + + * breakpoint.c (until_break_command): Assume is able to + expand to multiple ones and insert a breakpoint for each one. + 2020-08-25 Shahab Vahedi * MAINTAINERS: Add ARC target and maintainer. diff --git a/gdb/breakpoint.c b/gdb/breakpoint.c index ef8e54f634..645bd11b30 100644 --- a/gdb/breakpoint.c +++ b/gdb/breakpoint.c @@ -11023,74 +11023,72 @@ until_break_command (const char *arg, int from_tty, int anywhere) : decode_line_1 (location.get (), DECODE_LINE_FUNFIRSTLINE, NULL, NULL, 0)); - if (sals.size () != 1) - error (_("Couldn't get information on specified line.")); - - symtab_and_line &sal = sals[0]; - if (*arg) error (_("Junk at end of arguments.")); - resolve_sal_pc (&sal); - - tp = inferior_thread (); - thread = tp->global_num; - - /* Note linespec handling above invalidates the frame chain. - Installing a breakpoint also invalidates the frame chain (as it - may need to switch threads), so do any frame handling before - that. */ - - frame = get_selected_frame (NULL); - frame_gdbarch = get_frame_arch (frame); - stack_frame_id = get_stack_frame_id (frame); - caller_frame_id = frame_unwind_caller_id (frame); + for (size_t i = 0; i < sals.size (); i++) + { + symtab_and_line &sal = sals[i]; + resolve_sal_pc (&sal); + tp = inferior_thread (); + thread = tp->global_num; - /* Keep within the current frame, or in frames called by the current - one. */ + /* Note linespec handling above invalidates the frame chain. + Installing a breakpoint also invalidates the frame chain (as it + may need to switch threads), so do any frame handling before + that. */ - breakpoint_up caller_breakpoint; + frame = get_selected_frame (NULL); + frame_gdbarch = get_frame_arch (frame); + stack_frame_id = get_stack_frame_id (frame); + caller_frame_id = frame_unwind_caller_id (frame); - gdb::optional lj_deleter; + /* Keep within the current frame, or in frames called by the current + one. */ - if (frame_id_p (caller_frame_id)) - { - struct symtab_and_line sal2; - struct gdbarch *caller_gdbarch; + breakpoint_up caller_breakpoint; - sal2 = find_pc_line (frame_unwind_caller_pc (frame), 0); - sal2.pc = frame_unwind_caller_pc (frame); - caller_gdbarch = frame_unwind_caller_arch (frame); - caller_breakpoint = set_momentary_breakpoint (caller_gdbarch, - sal2, - caller_frame_id, - bp_until); + gdb::optional lj_deleter; - set_longjmp_breakpoint (tp, caller_frame_id); - lj_deleter.emplace (thread); - } + if (frame_id_p (caller_frame_id)) + { + struct symtab_and_line sal2; + struct gdbarch *caller_gdbarch; + + sal2 = find_pc_line (frame_unwind_caller_pc (frame), 0); + sal2.pc = frame_unwind_caller_pc (frame); + caller_gdbarch = frame_unwind_caller_arch (frame); + caller_breakpoint = set_momentary_breakpoint (caller_gdbarch, + sal2, + caller_frame_id, + bp_until); + + set_longjmp_breakpoint (tp, caller_frame_id); + lj_deleter.emplace (thread); + } - /* set_momentary_breakpoint could invalidate FRAME. */ - frame = NULL; + /* set_momentary_breakpoint could invalidate FRAME. */ + frame = NULL; - breakpoint_up location_breakpoint; - if (anywhere) - /* If the user told us to continue until a specified location, - we don't specify a frame at which we need to stop. */ - location_breakpoint = set_momentary_breakpoint (frame_gdbarch, sal, - null_frame_id, bp_until); - else - /* Otherwise, specify the selected frame, because we want to stop - only at the very same frame. */ - location_breakpoint = set_momentary_breakpoint (frame_gdbarch, sal, - stack_frame_id, bp_until); + breakpoint_up location_breakpoint; + if (anywhere) + /* If the user told us to continue until a specified location, + we don't specify a frame at which we need to stop. */ + location_breakpoint = set_momentary_breakpoint (frame_gdbarch, sal, + null_frame_id, bp_until); + else + /* Otherwise, specify the selected frame, because we want to stop + only at the very same frame. */ + location_breakpoint = set_momentary_breakpoint (frame_gdbarch, sal, + stack_frame_id, bp_until); - tp->thread_fsm = new until_break_fsm (command_interp (), tp->global_num, - std::move (location_breakpoint), - std::move (caller_breakpoint)); + tp->thread_fsm = new until_break_fsm (command_interp (), tp->global_num, + std::move (location_breakpoint), + std::move (caller_breakpoint)); - if (lj_deleter) - lj_deleter->release (); + if (lj_deleter) + lj_deleter->release (); + } proceed (-1, GDB_SIGNAL_DEFAULT); } -- 2.17.1