RAII-fy make_cleanup_restore_current_thread & friends

After all the make_cleanup_restore_current_thread fixing, I thought
I'd convert that and its relatives (which are all cleanups) to RAII
classes.

scoped_restore_current_pspace_and_thread was put in a separate file to
avoid a circular dependency.

Tested on x86-64 Fedora 23, native and gdbserver.

gdb/ChangeLog:
2017-05-04  Pedro Alves  <palves@redhat.com>

	* Makefile.in (SFILES): Add progspace-and-thread.c.
	(HFILES_NO_SRCDIR): Add progspace-and-thread.h.
	(COMMON_OBS): Add progspace-and-thread.o.
	* breakpoint.c: Include "progspace-and-thread.h".
	(update_inserted_breakpoint_locations)
	(insert_breakpoint_locations, create_longjmp_master_breakpoint):
	Use scoped_restore_current_pspace_and_thread.
	(create_std_terminate_master_breakpoint): Use
	scoped_restore_current_program_space.
	(remove_breakpoint): Use scoped_restore_current_pspace_and_thread.
	(print_breakpoint_location): Use
	scoped_restore_current_program_space.
	(bp_loc_is_permanent): Use
	scoped_restore_current_pspace_and_thread.
	(resolve_sal_pc): Use scoped_restore_current_pspace_and_thread.
	(download_tracepoint_locations): Use
	scoped_restore_current_pspace_and_thread.
	(breakpoint_re_set): Use scoped_restore_current_pspace_and_thread.
	* exec.c (exec_close_1): Use scoped_restore_current_program_space.
	(enum step_over_calls_kind): Moved from inferior.h.
	(class scoped_restore_current_thread): New class.
	* gdbthread.h (make_cleanup_restore_current_thread): Delete
	declaration.
	(scoped_restore_current_thread): New class.
	* infcmd.c: Include "common/gdb_optional.h".
	(continue_1, proceed_after_attach): Use
	scoped_restore_current_thread.
	(notice_new_inferior): Use scoped_restore_current_thread.
	* inferior.c: Include "progspace-and-thread.h".
	(restore_inferior, save_current_inferior): Delete.
	(add_inferior_command, clone_inferior_command): Use
	scoped_restore_current_pspace_and_thread.
	* inferior.h (scoped_restore_current_inferior): New class.
	* infrun.c: Include "progspace-and-thread.h" and
	"common/gdb_optional.h".
	(follow_fork_inferior): Use
	scoped_restore_current_pspace_and_thread.
	(scoped_restore_exited_inferior): New class.
	(handle_vfork_child_exec_or_exit): Use
	scoped_restore_exited_inferior,
	scoped_restore_current_pspace_and_thread,
	scoped_restore_current_thread and scoped_restore.
	(fetch_inferior_event): Use scoped_restore_current_thread.
	* linespec.c (decode_line_full, decode_line_1): Use
	scoped_restore_current_program_space.
	* mi/mi-main.c: Include "progspace-and-thread.h".
	(exec_continue): Use scoped_restore_current_thread.
	(mi_cmd_exec_run): Use scoped_restore_current_pspace_and_thread.
	(mi_cmd_trace_frame_collected): Use scoped_restore_current_thread.
	* proc-service.c (ps_pglobal_lookup): Use
	scoped_restore_current_program_space.
	* progspace-and-thread.c: New file.
	* progspace-and-thread.h: New file.
	* progspace.c (release_program_space, clone_program_space): Use
	scoped_restore_current_program_space.
	(restore_program_space, save_current_program_space)
	(save_current_space_and_thread): Delete.
	(switch_to_program_space_and_thread): Moved to
	progspace-and-thread.c.
	* progspace.h (save_current_program_space)
	(save_current_space_and_thread): Delete declarations.
	(scoped_restore_current_program_space): New class.
	* remote.c (remote_btrace_maybe_reopen): Use
	scoped_restore_current_thread.
	* symtab.c: Include "progspace-and-thread.h".
	(skip_prologue_sal): Use scoped_restore_current_pspace_and_thread.
	* thread.c (print_thread_info_1): Use
	scoped_restore_current_thread.
	(struct current_thread_cleanup): Delete.
	(do_restore_current_thread_cleanup)
	(restore_current_thread_cleanup_dtor): Rename/convert both to ...
	(scoped_restore_current_thread::~scoped_restore_current_thread):
	... this new dtor.
	(make_cleanup_restore_current_thread): Rename/convert to ...
	(scoped_restore_current_thread::scoped_restore_current_thread):
	... this new ctor.
	(thread_apply_all_command): Use scoped_restore_current_thread.
	(thread_apply_command): Use scoped_restore_current_thread.
	* tracepoint.c (tdump_command): Use scoped_restore_current_thread.
	* varobj.c (value_of_root_1): Use scoped_restore_current_thread.
This commit is contained in:
Pedro Alves 2017-05-04 12:46:44 +01:00
parent f6223dbb50
commit 5ed8105e02
21 changed files with 454 additions and 416 deletions

View File

@ -1,3 +1,86 @@
2017-05-04 Pedro Alves <palves@redhat.com>
* Makefile.in (SFILES): Add progspace-and-thread.c.
(HFILES_NO_SRCDIR): Add progspace-and-thread.h.
(COMMON_OBS): Add progspace-and-thread.o.
* breakpoint.c: Include "progspace-and-thread.h".
(update_inserted_breakpoint_locations)
(insert_breakpoint_locations, create_longjmp_master_breakpoint):
Use scoped_restore_current_pspace_and_thread.
(create_std_terminate_master_breakpoint): Use
scoped_restore_current_program_space.
(remove_breakpoint): Use scoped_restore_current_pspace_and_thread.
(print_breakpoint_location): Use
scoped_restore_current_program_space.
(bp_loc_is_permanent): Use
scoped_restore_current_pspace_and_thread.
(resolve_sal_pc): Use scoped_restore_current_pspace_and_thread.
(download_tracepoint_locations): Use
scoped_restore_current_pspace_and_thread.
(breakpoint_re_set): Use scoped_restore_current_pspace_and_thread.
* exec.c (exec_close_1): Use scoped_restore_current_program_space.
(enum step_over_calls_kind): Moved from inferior.h.
(class scoped_restore_current_thread): New class.
* gdbthread.h (make_cleanup_restore_current_thread): Delete
declaration.
(scoped_restore_current_thread): New class.
* infcmd.c: Include "common/gdb_optional.h".
(continue_1, proceed_after_attach): Use
scoped_restore_current_thread.
(notice_new_inferior): Use scoped_restore_current_thread.
* inferior.c: Include "progspace-and-thread.h".
(restore_inferior, save_current_inferior): Delete.
(add_inferior_command, clone_inferior_command): Use
scoped_restore_current_pspace_and_thread.
* inferior.h (scoped_restore_current_inferior): New class.
* infrun.c: Include "progspace-and-thread.h" and
"common/gdb_optional.h".
(follow_fork_inferior): Use
scoped_restore_current_pspace_and_thread.
(scoped_restore_exited_inferior): New class.
(handle_vfork_child_exec_or_exit): Use
scoped_restore_exited_inferior,
scoped_restore_current_pspace_and_thread,
scoped_restore_current_thread and scoped_restore.
(fetch_inferior_event): Use scoped_restore_current_thread.
* linespec.c (decode_line_full, decode_line_1): Use
scoped_restore_current_program_space.
* mi/mi-main.c: Include "progspace-and-thread.h".
(exec_continue): Use scoped_restore_current_thread.
(mi_cmd_exec_run): Use scoped_restore_current_pspace_and_thread.
(mi_cmd_trace_frame_collected): Use scoped_restore_current_thread.
* proc-service.c (ps_pglobal_lookup): Use
scoped_restore_current_program_space.
* progspace-and-thread.c: New file.
* progspace-and-thread.h: New file.
* progspace.c (release_program_space, clone_program_space): Use
scoped_restore_current_program_space.
(restore_program_space, save_current_program_space)
(save_current_space_and_thread): Delete.
(switch_to_program_space_and_thread): Moved to
progspace-and-thread.c.
* progspace.h (save_current_program_space)
(save_current_space_and_thread): Delete declarations.
(scoped_restore_current_program_space): New class.
* remote.c (remote_btrace_maybe_reopen): Use
scoped_restore_current_thread.
* symtab.c: Include "progspace-and-thread.h".
(skip_prologue_sal): Use scoped_restore_current_pspace_and_thread.
* thread.c (print_thread_info_1): Use
scoped_restore_current_thread.
(struct current_thread_cleanup): Delete.
(do_restore_current_thread_cleanup)
(restore_current_thread_cleanup_dtor): Rename/convert both to ...
(scoped_restore_current_thread::~scoped_restore_current_thread):
... this new dtor.
(make_cleanup_restore_current_thread): Rename/convert to ...
(scoped_restore_current_thread::scoped_restore_current_thread):
... this new ctor.
(thread_apply_all_command): Use scoped_restore_current_thread.
(thread_apply_command): Use scoped_restore_current_thread.
* tracepoint.c (tdump_command): Use scoped_restore_current_thread.
* varobj.c (value_of_root_1): Use scoped_restore_current_thread.
2017-05-04 Pedro Alves <palves@redhat.com>
* thread.c (make_cleanup_restore_current_thread): Move

View File

@ -1148,6 +1148,7 @@ SFILES = \
probe.c \
proc-service.list \
progspace.c \
progspace-and-thread.c \
prologue-value.c \
psymtab.c \
record.c \
@ -1403,6 +1404,7 @@ HFILES_NO_SRCDIR = \
proc-utils.h \
procfs.h \
progspace.h \
progspace-and-thread.h \
prologue-value.h \
psympriv.h \
psymtab.h \
@ -1757,6 +1759,7 @@ COMMON_OBS = $(DEPFILES) $(CONFIG_OBS) $(YYOBJ) \
printcmd.o \
probe.o \
progspace.o \
progspace-and-thread.o \
prologue-value.o \
psymtab.o \
ptid.o \

View File

@ -80,6 +80,7 @@
#include "mi/mi-common.h"
#include "extension.h"
#include <algorithm>
#include "progspace-and-thread.h"
/* Enums for exception-handling support. */
enum exception_event_kind
@ -3065,7 +3066,7 @@ update_inserted_breakpoint_locations (void)
there was an error. */
tmp_error_stream.puts ("Warning:\n");
struct cleanup *cleanups = save_current_space_and_thread ();
scoped_restore_current_pspace_and_thread restore_pspace_thread;
ALL_BP_LOCATIONS (bl, blp_tmp)
{
@ -3101,8 +3102,6 @@ update_inserted_breakpoint_locations (void)
target_terminal_ours_for_output ();
error_stream (tmp_error_stream);
}
do_cleanups (cleanups);
}
/* Used when starting or continuing the program. */
@ -3124,7 +3123,7 @@ insert_breakpoint_locations (void)
there was an error. */
tmp_error_stream.puts ("Warning:\n");
struct cleanup *cleanups = save_current_space_and_thread ();
scoped_restore_current_pspace_and_thread restore_pspace_thread;
ALL_BP_LOCATIONS (bl, blp_tmp)
{
@ -3202,8 +3201,6 @@ You may have requested too many hardware breakpoints/watchpoints.\n");
target_terminal_ours_for_output ();
error_stream (tmp_error_stream);
}
do_cleanups (cleanups);
}
/* Used when the program stops.
@ -3489,9 +3486,8 @@ static void
create_longjmp_master_breakpoint (void)
{
struct program_space *pspace;
struct cleanup *old_chain;
old_chain = save_current_program_space ();
scoped_restore_current_program_space restore_pspace;
ALL_PSPACES (pspace)
{
@ -3595,8 +3591,6 @@ create_longjmp_master_breakpoint (void)
}
}
}
do_cleanups (old_chain);
}
/* Create a master std::terminate breakpoint. */
@ -3604,10 +3598,9 @@ static void
create_std_terminate_master_breakpoint (void)
{
struct program_space *pspace;
struct cleanup *old_chain;
const char *const func_name = "std::terminate()";
old_chain = save_current_program_space ();
scoped_restore_current_program_space restore_pspace;
ALL_PSPACES (pspace)
{
@ -3652,8 +3645,6 @@ create_std_terminate_master_breakpoint (void)
b->enable_state = bp_disabled;
}
}
do_cleanups (old_chain);
}
/* Install a master breakpoint on the unwinder's debug hook. */
@ -4077,9 +4068,6 @@ remove_breakpoint_1 (struct bp_location *bl, enum remove_bp_reason reason)
static int
remove_breakpoint (struct bp_location *bl)
{
int ret;
struct cleanup *old_chain;
/* BL is never in moribund_locations by our callers. */
gdb_assert (bl->owner != NULL);
@ -4087,14 +4075,11 @@ remove_breakpoint (struct bp_location *bl)
This should not ever happen. */
gdb_assert (bl->owner->type != bp_none);
old_chain = save_current_space_and_thread ();
scoped_restore_current_pspace_and_thread restore_pspace_thread;
switch_to_program_space_and_thread (bl->pspace);
ret = remove_breakpoint_1 (bl, REMOVE_BREAKPOINT);
do_cleanups (old_chain);
return ret;
return remove_breakpoint_1 (bl, REMOVE_BREAKPOINT);
}
/* Clear the "inserted" flag in all breakpoints. */
@ -6129,7 +6114,8 @@ print_breakpoint_location (struct breakpoint *b,
struct bp_location *loc)
{
struct ui_out *uiout = current_uiout;
struct cleanup *old_chain = save_current_program_space ();
scoped_restore_current_program_space restore_pspace;
if (loc != NULL && loc->shlib_disabled)
loc = NULL;
@ -6194,8 +6180,6 @@ print_breakpoint_location (struct breakpoint *b,
bp_location_condition_evaluator (loc));
uiout->text (")");
}
do_cleanups (old_chain);
}
static const char *
@ -9071,9 +9055,6 @@ program_breakpoint_here_p (struct gdbarch *gdbarch, CORE_ADDR address)
static int
bp_loc_is_permanent (struct bp_location *loc)
{
struct cleanup *cleanup;
int retval;
gdb_assert (loc != NULL);
/* If we have a catchpoint or a watchpoint, just return 0. We should not
@ -9083,14 +9064,9 @@ bp_loc_is_permanent (struct bp_location *loc)
if (!breakpoint_address_is_meaningful (loc->owner))
return 0;
cleanup = save_current_space_and_thread ();
scoped_restore_current_pspace_and_thread restore_pspace_thread;
switch_to_program_space_and_thread (loc->pspace);
retval = program_breakpoint_here_p (loc->gdbarch, loc->address);
do_cleanups (cleanup);
return retval;
return program_breakpoint_here_p (loc->gdbarch, loc->address);
}
/* Build a command list for the dprintf corresponding to the current
@ -9974,16 +9950,12 @@ resolve_sal_pc (struct symtab_and_line *sal)
if we have line numbers but no functions (as can
happen in assembly source). */
struct bound_minimal_symbol msym;
struct cleanup *old_chain = save_current_space_and_thread ();
scoped_restore_current_pspace_and_thread restore_pspace_thread;
switch_to_program_space_and_thread (sal->pspace);
msym = lookup_minimal_symbol_by_pc (sal->pc);
bound_minimal_symbol msym = lookup_minimal_symbol_by_pc (sal->pc);
if (msym.minsym)
sal->section = MSYMBOL_OBJ_SECTION (msym.objfile, msym.minsym);
do_cleanups (old_chain);
}
}
}
@ -12177,10 +12149,9 @@ static void
download_tracepoint_locations (void)
{
struct breakpoint *b;
struct cleanup *old_chain;
enum tribool can_download_tracepoint = TRIBOOL_UNKNOWN;
old_chain = save_current_space_and_thread ();
scoped_restore_current_pspace_and_thread restore_pspace_thread;
ALL_TRACEPOINTS (b)
{
@ -12224,8 +12195,6 @@ download_tracepoint_locations (void)
if (bp_location_downloaded)
observer_notify_breakpoint_modified (b);
}
do_cleanups (old_chain);
}
/* Swap the insertion/duplication state between two locations. */
@ -14506,32 +14475,32 @@ breakpoint_re_set (void)
struct breakpoint *b, *b_tmp;
enum language save_language;
int save_input_radix;
struct cleanup *old_chain;
save_language = current_language->la_language;
save_input_radix = input_radix;
old_chain = save_current_space_and_thread ();
/* Note: we must not try to insert locations until after all
breakpoints have been re-set. Otherwise, e.g., when re-setting
breakpoint 1, we'd insert the locations of breakpoint 2, which
hadn't been re-set yet, and thus may have stale locations. */
ALL_BREAKPOINTS_SAFE (b, b_tmp)
{
/* Format possible error msg. */
char *message = xstrprintf ("Error in re-setting breakpoint %d: ",
b->number);
struct cleanup *cleanups = make_cleanup (xfree, message);
catch_errors (breakpoint_re_set_one, b, message, RETURN_MASK_ALL);
do_cleanups (cleanups);
scoped_restore_current_pspace_and_thread restore_pspace_thread;
/* Note: we must not try to insert locations until after all
breakpoints have been re-set. Otherwise, e.g., when re-setting
breakpoint 1, we'd insert the locations of breakpoint 2, which
hadn't been re-set yet, and thus may have stale locations. */
ALL_BREAKPOINTS_SAFE (b, b_tmp)
{
/* Format possible error msg. */
char *message = xstrprintf ("Error in re-setting breakpoint %d: ",
b->number);
struct cleanup *cleanups = make_cleanup (xfree, message);
catch_errors (breakpoint_re_set_one, b, message, RETURN_MASK_ALL);
do_cleanups (cleanups);
}
set_language (save_language);
input_radix = save_input_radix;
jit_breakpoint_re_set ();
}
set_language (save_language);
input_radix = save_input_radix;
jit_breakpoint_re_set ();
do_cleanups (old_chain);
create_overlay_event_breakpoint ();
create_longjmp_master_breakpoint ();

View File

@ -113,17 +113,14 @@ static void
exec_close_1 (struct target_ops *self)
{
struct program_space *ss;
struct cleanup *old_chain;
scoped_restore_current_program_space restore_pspace;
old_chain = save_current_program_space ();
ALL_PSPACES (ss)
{
set_current_program_space (ss);
clear_section_table (current_target_sections);
exec_close ();
}
do_cleanups (old_chain);
{
set_current_program_space (ss);
clear_section_table (current_target_sections);
exec_close ();
}
}
void

View File

@ -592,7 +592,27 @@ extern int print_thread_events;
extern void print_thread_info (struct ui_out *uiout, char *requested_threads,
int pid);
extern struct cleanup *make_cleanup_restore_current_thread (void);
/* Save/restore current inferior/thread/frame. */
class scoped_restore_current_thread
{
public:
scoped_restore_current_thread ();
~scoped_restore_current_thread ();
/* Disable copy. */
scoped_restore_current_thread
(const scoped_restore_current_thread &) = delete;
void operator=
(const scoped_restore_current_thread &) = delete;
private:
thread_info *m_thread;
inferior *m_inf;
frame_id m_selected_frame_id;
int m_selected_frame_level;
bool m_was_stopped;
};
/* Returns a pointer into the thread_info corresponding to
INFERIOR_PTID. INFERIOR_PTID *must* be in the thread list. */

View File

@ -58,6 +58,7 @@
#include "thread-fsm.h"
#include "top.h"
#include "interps.h"
#include "common/gdb_optional.h"
/* Local functions: */
@ -730,10 +731,10 @@ continue_1 (int all_threads)
{
/* Don't error out if the current thread is running, because
there may be other stopped threads. */
struct cleanup *old_chain;
/* Backup current thread and selected frame. */
old_chain = make_cleanup_restore_current_thread ();
/* Backup current thread and selected frame and restore on scope
exit. */
scoped_restore_current_thread restore_thread;
iterate_over_threads (proceed_thread_callback, NULL);
@ -754,9 +755,6 @@ continue_1 (int all_threads)
*/
target_terminal_inferior ();
}
/* Restore selected ptid. */
do_cleanups (old_chain);
}
else
{
@ -2619,15 +2617,11 @@ proceed_after_attach (int pid)
{
/* Don't error out if the current thread is running, because
there may be other stopped threads. */
struct cleanup *old_chain;
/* Backup current thread and selected frame. */
old_chain = make_cleanup_restore_current_thread ();
scoped_restore_current_thread restore_thread;
iterate_over_threads (proceed_after_attach_callback, &pid);
/* Restore selected ptid. */
do_cleanups (old_chain);
}
/* See inferior.h. */
@ -2914,15 +2908,13 @@ attach_command (char *args, int from_tty)
void
notice_new_inferior (ptid_t ptid, int leave_running, int from_tty)
{
struct cleanup* old_chain;
enum attach_post_wait_mode mode;
enum attach_post_wait_mode mode
= leave_running ? ATTACH_POST_WAIT_RESUME : ATTACH_POST_WAIT_NOTHING;
old_chain = make_cleanup (null_cleanup, NULL);
gdb::optional<scoped_restore_current_thread> restore_thread;
mode = leave_running ? ATTACH_POST_WAIT_RESUME : ATTACH_POST_WAIT_NOTHING;
if (!ptid_equal (inferior_ptid, null_ptid))
make_cleanup_restore_current_thread ();
if (inferior_ptid != null_ptid)
restore_thread.emplace ();
/* Avoid reading registers -- we haven't fetched the target
description yet. */
@ -2951,13 +2943,10 @@ notice_new_inferior (ptid_t ptid, int leave_running, int from_tty)
add_inferior_continuation (attach_command_continuation, a,
attach_command_continuation_free_args);
do_cleanups (old_chain);
return;
}
attach_post_wait ("" /* args */, from_tty, mode);
do_cleanups (old_chain);
}
/*

View File

@ -35,6 +35,7 @@
#include "arch-utils.h"
#include "target-descriptions.h"
#include "readline/tilde.h"
#include "progspace-and-thread.h"
void _initialize_inferiors (void);
@ -72,30 +73,6 @@ set_current_inferior (struct inferior *inf)
current_inferior_ = inf;
}
/* A cleanups callback, helper for save_current_program_space
below. */
static void
restore_inferior (void *arg)
{
struct inferior *saved_inferior = (struct inferior *) arg;
set_current_inferior (saved_inferior);
}
/* Save the current program space so that it may be restored by a later
call to do_cleanups. Returns the struct cleanup pointer needed for
later doing the cleanup. */
struct cleanup *
save_current_inferior (void)
{
struct cleanup *old_chain = make_cleanup (restore_inferior,
current_inferior_);
return old_chain;
}
inferior::~inferior ()
{
inferior *inf = this;
@ -862,7 +839,7 @@ add_inferior_command (char *args, int from_tty)
}
}
save_current_space_and_thread ();
scoped_restore_current_pspace_and_thread restore_pspace_thread;
for (i = 0; i < copies; ++i)
{
@ -942,7 +919,7 @@ clone_inferior_command (char *args, int from_tty)
if (orginf == NULL)
orginf = current_inferior ();
save_current_space_and_thread ();
scoped_restore_current_pspace_and_thread restore_pspace_thread;
for (i = 0; i < copies; ++i)
{

View File

@ -540,7 +540,28 @@ extern int number_of_live_inferiors (void);
(not cores, not executables, real live processes). */
extern int have_live_inferiors (void);
extern struct cleanup *save_current_inferior (void);
/* Save/restore the current inferior. */
class scoped_restore_current_inferior
{
public:
scoped_restore_current_inferior ()
: m_saved_inf (current_inferior ())
{}
~scoped_restore_current_inferior ()
{ set_current_inferior (m_saved_inf); }
/* Disable copy. */
scoped_restore_current_inferior
(const scoped_restore_current_inferior &) = delete;
void operator=
(const scoped_restore_current_inferior &) = delete;
private:
inferior *m_saved_inf;
};
/* Traverse all inferiors. */

View File

@ -64,6 +64,8 @@
#include "event-loop.h"
#include "thread-fsm.h"
#include "common/enum-flags.h"
#include "progspace-and-thread.h"
#include "common/gdb_optional.h"
/* Prototypes for local functions */
@ -487,7 +489,6 @@ holding the child stopped. Try \"set detach-on-fork\" or \
else
{
struct inferior *parent_inf, *child_inf;
struct cleanup *old_chain;
/* Add process to GDB's tables. */
child_inf = add_inferior (ptid_get_pid (child_ptid));
@ -498,7 +499,7 @@ holding the child stopped. Try \"set detach-on-fork\" or \
child_inf->gdbarch = parent_inf->gdbarch;
copy_inferior_target_desc_info (child_inf, parent_inf);
old_chain = save_current_space_and_thread ();
scoped_restore_current_pspace_and_thread restore_pspace_thread;
inferior_ptid = child_ptid;
add_thread (inferior_ptid);
@ -536,8 +537,6 @@ holding the child stopped. Try \"set detach-on-fork\" or \
required. */
solib_create_inferior_hook (0);
}
do_cleanups (old_chain);
}
if (has_vforked)
@ -895,6 +894,22 @@ proceed_after_vfork_done (struct thread_info *thread,
return 0;
}
/* Save/restore inferior_ptid, current program space and current
inferior. Only use this if the current context points at an exited
inferior (and therefore there's no current thread to save). */
class scoped_restore_exited_inferior
{
public:
scoped_restore_exited_inferior ()
: m_saved_ptid (&inferior_ptid)
{}
private:
scoped_restore_tmpl<ptid_t> m_saved_ptid;
scoped_restore_current_program_space m_pspace;
scoped_restore_current_inferior m_inferior;
};
/* Called whenever we notice an exec or exit event, to handle
detaching or resuming a vfork parent. */
@ -914,7 +929,6 @@ handle_vfork_child_exec_or_exit (int exec)
if (inf->vfork_parent->pending_detach)
{
struct thread_info *tp;
struct cleanup *old_chain;
struct program_space *pspace;
struct address_space *aspace;
@ -922,16 +936,17 @@ handle_vfork_child_exec_or_exit (int exec)
inf->vfork_parent->pending_detach = 0;
gdb::optional<scoped_restore_exited_inferior>
maybe_restore_inferior;
gdb::optional<scoped_restore_current_pspace_and_thread>
maybe_restore_thread;
/* If we're handling a child exit, then inferior_ptid points
at the inferior's pid, not to a thread. */
if (!exec)
{
/* If we're handling a child exit, then inferior_ptid
points at the inferior's pid, not to a thread. */
old_chain = save_inferior_ptid ();
save_current_program_space ();
save_current_inferior ();
}
maybe_restore_inferior.emplace ();
else
old_chain = save_current_space_and_thread ();
maybe_restore_thread.emplace ();
/* We're letting loose of the parent. */
tp = any_live_thread_of_process (inf->vfork_parent->pid);
@ -979,8 +994,6 @@ handle_vfork_child_exec_or_exit (int exec)
/* Put it back. */
inf->pspace = pspace;
inf->aspace = aspace;
do_cleanups (old_chain);
}
else if (exec)
{
@ -998,7 +1011,6 @@ handle_vfork_child_exec_or_exit (int exec)
}
else
{
struct cleanup *old_chain;
struct program_space *pspace;
/* If this is a vfork child exiting, then the pspace and
@ -1010,10 +1022,11 @@ handle_vfork_child_exec_or_exit (int exec)
go ahead and create a new one for this exiting
inferior. */
/* Switch to null_ptid, so that clone_program_space doesn't want
to read the selected frame of a dead process. */
old_chain = save_inferior_ptid ();
inferior_ptid = null_ptid;
/* Switch to null_ptid while running clone_program_space, so
that clone_program_space doesn't want to read the
selected frame of a dead process. */
scoped_restore restore_ptid
= make_scoped_restore (&inferior_ptid, null_ptid);
/* This inferior is dead, so avoid giving the breakpoints
module the option to write through to it (cloning a
@ -1028,10 +1041,6 @@ handle_vfork_child_exec_or_exit (int exec)
inf->pspace = pspace;
inf->aspace = pspace->aspace;
/* Put back inferior_ptid. We'll continue mourning this
inferior. */
do_cleanups (old_chain);
resume_parent = inf->vfork_parent->pid;
/* Break the bonds. */
inf->vfork_parent->vfork_child = NULL;
@ -1045,7 +1054,7 @@ handle_vfork_child_exec_or_exit (int exec)
{
/* If the user wanted the parent to be running, let it go
free now. */
struct cleanup *old_chain = make_cleanup_restore_current_thread ();
scoped_restore_current_thread restore_thread;
if (debug_infrun)
fprintf_unfiltered (gdb_stdlog,
@ -1053,8 +1062,6 @@ handle_vfork_child_exec_or_exit (int exec)
resume_parent);
iterate_over_threads (proceed_after_vfork_done, &resume_parent);
do_cleanups (old_chain);
}
}
}
@ -3889,12 +3896,14 @@ fetch_inferior_event (void *client_data)
set_current_traceframe (-1);
}
gdb::optional<scoped_restore_current_thread> maybe_restore_thread;
if (non_stop)
/* In non-stop mode, the user/frontend should not notice a thread
switch due to internal events. Make sure we reverse to the
user selected thread and frame after handling the event and
running any breakpoint commands. */
make_cleanup_restore_current_thread ();
maybe_restore_thread.emplace ();
overlay_cache_invalid = 1;
/* Flush target cache before starting to handle each event. Target

View File

@ -2554,7 +2554,8 @@ decode_line_full (const struct event_location *location, int flags,
search_pspace, default_symtab,
default_line, canonical);
cleanups = make_cleanup (linespec_parser_delete, &parser);
save_current_program_space ();
scoped_restore_current_program_space restore_pspace;
result = event_location_to_sals (&parser, location);
state = PARSER_STATE (&parser);
@ -2616,7 +2617,8 @@ decode_line_1 (const struct event_location *location, int flags,
search_pspace, default_symtab,
default_line, NULL);
cleanups = make_cleanup (linespec_parser_delete, &parser);
save_current_program_space ();
scoped_restore_current_program_space restore_pspace;
result = event_location_to_sals (&parser, location);

View File

@ -59,6 +59,7 @@
#include <ctype.h>
#include "run-time-clock.h"
#include <chrono>
#include "progspace-and-thread.h"
enum
{
@ -274,8 +275,8 @@ exec_continue (char **argv, int argc)
See comment on infcmd.c:proceed_thread_callback for rationale. */
if (current_context->all || current_context->thread_group != -1)
{
scoped_restore_current_thread restore_thread;
int pid = 0;
struct cleanup *back_to = make_cleanup_restore_current_thread ();
if (!current_context->all)
{
@ -285,7 +286,6 @@ exec_continue (char **argv, int argc)
pid = inf->pid;
}
iterate_over_threads (proceed_thread_callback, &pid);
do_cleanups (back_to);
}
else
{
@ -468,10 +468,9 @@ mi_cmd_exec_run (const char *command, char **argv, int argc)
if (current_context->all)
{
struct cleanup *back_to = save_current_space_and_thread ();
scoped_restore_current_pspace_and_thread restore_pspace_thread;
iterate_over_inferiors (run_one_inferior, &start_p);
do_cleanups (back_to);
}
else
{
@ -2699,7 +2698,6 @@ print_variable_or_computed (const char *expression, enum print_values values)
void
mi_cmd_trace_frame_collected (const char *command, char **argv, int argc)
{
struct cleanup *old_chain;
struct bp_location *tloc;
int stepping_frame;
struct collection_list *clist;
@ -2762,7 +2760,7 @@ mi_cmd_trace_frame_collected (const char *command, char **argv, int argc)
/* This command only makes sense for the current frame, not the
selected frame. */
old_chain = make_cleanup_restore_current_thread ();
scoped_restore_current_thread restore_thread;
select_frame (get_current_frame ());
encode_actions (tloc, &tracepoint_list, &stepping_list);
@ -2918,8 +2916,6 @@ mi_cmd_trace_frame_collected (const char *command, char **argv, int argc)
do_cleanups (list_cleanup);
}
do_cleanups (old_chain);
}
void

View File

@ -112,25 +112,19 @@ ps_err_e
ps_pglobal_lookup (gdb_ps_prochandle_t ph, const char *obj,
const char *name, psaddr_t *sym_addr)
{
struct bound_minimal_symbol ms;
struct cleanup *old_chain = save_current_program_space ();
struct inferior *inf = find_inferior_ptid (ph->ptid);
ps_err_e result;
scoped_restore_current_program_space restore_pspace;
set_current_program_space (inf->pspace);
/* FIXME: kettenis/2000-09-03: What should we do with OBJ? */
ms = lookup_minimal_symbol (name, NULL, NULL);
bound_minimal_symbol ms = lookup_minimal_symbol (name, NULL, NULL);
if (ms.minsym == NULL)
result = PS_NOSYM;
else
{
*sym_addr = core_addr_to_ps_addr (BMSYMBOL_VALUE_ADDRESS (ms));
result = PS_OK;
}
return PS_NOSYM;
do_cleanups (old_chain);
return result;
*sym_addr = core_addr_to_ps_addr (BMSYMBOL_VALUE_ADDRESS (ms));
return PS_OK;
}
/* Read SIZE bytes from the target process PH at address ADDR and copy

View File

@ -0,0 +1,43 @@
/* Copyright (C) 2009-2017 Free Software Foundation, Inc.
This file is part of GDB.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>. */
#include "defs.h"
#include "progspace-and-thread.h"
/* See progspace-and-thread.h */
void
switch_to_program_space_and_thread (program_space *pspace)
{
inferior *inf = find_inferior_for_program_space (pspace);
if (inf != NULL && inf->pid != 0)
{
thread_info *tp = any_live_thread_of_process (inf->pid);
if (tp != NULL)
{
switch_to_thread (tp->ptid);
/* Switching thread switches pspace implicitly. We're
done. */
return;
}
}
switch_to_thread (null_ptid);
set_current_program_space (pspace);
}

View File

@ -0,0 +1,40 @@
/* Copyright (C) 2009-2017 Free Software Foundation, Inc.
This file is part of GDB.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>. */
#ifndef PROGSPACE_AND_THREAD_H
#define PROGSPACE_AND_THREAD_H
#include "progspace.h"
#include "gdbthread.h"
/* Save/restore the current program space, thread, inferior and frame.
Use this when you need to call
switch_to_program_space_and_thread. */
class scoped_restore_current_pspace_and_thread
{
scoped_restore_current_program_space m_restore_pspace;
scoped_restore_current_thread m_restore_thread;
};
/* Switches full context to program space PSPACE. Switches to the
first thread found bound to PSPACE, giving preference to the
current thread, if there's one and it isn't executing. */
void switch_to_program_space_and_thread (program_space *pspace);
#endif

View File

@ -156,10 +156,10 @@ add_program_space (struct address_space *aspace)
static void
release_program_space (struct program_space *pspace)
{
struct cleanup *old_chain = save_current_program_space ();
gdb_assert (pspace != current_program_space);
scoped_restore_current_program_space restore_pspace;
set_current_program_space (pspace);
breakpoint_program_space_exit (pspace);
@ -173,8 +173,6 @@ release_program_space (struct program_space *pspace)
/* Discard any data modules have associated with the PSPACE. */
program_space_free_data (pspace);
xfree (pspace);
do_cleanups (old_chain);
}
/* Copies program space SRC to DEST. Copies the main executable file,
@ -183,9 +181,7 @@ release_program_space (struct program_space *pspace)
struct program_space *
clone_program_space (struct program_space *dest, struct program_space *src)
{
struct cleanup *old_chain;
old_chain = save_current_program_space ();
scoped_restore_current_program_space restore_pspace;
set_current_program_space (dest);
@ -195,7 +191,6 @@ clone_program_space (struct program_space *dest, struct program_space *src)
if (src->symfile_object_file != NULL)
symbol_file_add_main (objfile_name (src->symfile_object_file), 0);
do_cleanups (old_chain);
return dest;
}
@ -217,30 +212,6 @@ set_current_program_space (struct program_space *pspace)
reinit_frame_cache ();
}
/* A cleanups callback, helper for save_current_program_space
below. */
static void
restore_program_space (void *arg)
{
struct program_space *saved_pspace = (struct program_space *) arg;
set_current_program_space (saved_pspace);
}
/* Save the current program space so that it may be restored by a later
call to do_cleanups. Returns the struct cleanup pointer needed for
later doing the cleanup. */
struct cleanup *
save_current_program_space (void)
{
struct cleanup *old_chain = make_cleanup (restore_program_space,
current_program_space);
return old_chain;
}
/* Returns true iff there's no inferior bound to PSPACE. */
int
@ -447,51 +418,6 @@ update_address_spaces (void)
inf->aspace = inf->pspace->aspace;
}
/* Save the current program space so that it may be restored by a later
call to do_cleanups. Returns the struct cleanup pointer needed for
later doing the cleanup. */
struct cleanup *
save_current_space_and_thread (void)
{
struct cleanup *old_chain;
/* If restoring to null thread, we need to restore the pspace as
well, hence, we need to save the current program space first. */
old_chain = save_current_program_space ();
/* There's no need to save the current inferior here.
That is handled by make_cleanup_restore_current_thread. */
make_cleanup_restore_current_thread ();
return old_chain;
}
/* See progspace.h */
void
switch_to_program_space_and_thread (struct program_space *pspace)
{
struct inferior *inf;
inf = find_inferior_for_program_space (pspace);
if (inf != NULL && inf->pid != 0)
{
struct thread_info *tp;
tp = any_live_thread_of_process (inf->pid);
if (tp != NULL)
{
switch_to_thread (tp->ptid);
/* Switching thread switches pspace implicitly. We're
done. */
return;
}
}
switch_to_thread (null_ptid);
set_current_program_space (pspace);
}
/* See progspace.h. */

View File

@ -251,11 +251,6 @@ extern int program_space_empty_p (struct program_space *pspace);
extern struct program_space *clone_program_space (struct program_space *dest,
struct program_space *src);
/* Save the current program space so that it may be restored by a later
call to do_cleanups. Returns the struct cleanup pointer needed for
later doing the cleanup. */
extern struct cleanup *save_current_program_space (void);
/* Sets PSPACE as the current program space. This is usually used
instead of set_current_space_and_thread when the current
thread/inferior is not important for the operations that follow.
@ -266,14 +261,27 @@ extern struct cleanup *save_current_program_space (void);
space. */
extern void set_current_program_space (struct program_space *pspace);
/* Saves the current thread (may be null), frame and program space in
the current cleanup chain. */
extern struct cleanup *save_current_space_and_thread (void);
/* Save/restore the current program space. */
/* Switches full context to program space PSPACE. Switches to the
first thread found bound to PSPACE, giving preference to the
current thread, if there's one and it isn't executing. */
extern void switch_to_program_space_and_thread (struct program_space *pspace);
class scoped_restore_current_program_space
{
public:
scoped_restore_current_program_space ()
: m_saved_pspace (current_program_space)
{}
~scoped_restore_current_program_space ()
{ set_current_program_space (m_saved_pspace); }
/* Disable copy. */
scoped_restore_current_program_space
(const scoped_restore_current_program_space &) = delete;
void operator=
(const scoped_restore_current_program_space &) = delete;
private:
program_space *m_saved_pspace;
};
/* Create a new address space object, and add it to the list. */
extern struct address_space *new_address_space (void);

View File

@ -13210,12 +13210,12 @@ static void
remote_btrace_maybe_reopen (void)
{
struct remote_state *rs = get_remote_state ();
struct cleanup *cleanup;
struct thread_info *tp;
int btrace_target_pushed = 0;
int warned = 0;
cleanup = make_cleanup_restore_current_thread ();
scoped_restore_current_thread restore_thread;
ALL_NON_EXITED_THREADS (tp)
{
set_general_thread (tp->ptid);
@ -13255,7 +13255,6 @@ remote_btrace_maybe_reopen (void)
tp->btrace.target->ptid = tp->ptid;
tp->btrace.target->conf = rs->btrace_config;
}
do_cleanups (cleanup);
}
/* Enable branch tracing. */

View File

@ -61,6 +61,7 @@
#include "parser-defs.h"
#include "completer.h"
#include "progspace-and-thread.h"
/* Forward declarations for local functions. */
@ -3551,7 +3552,6 @@ skip_prologue_sal (struct symtab_and_line *sal)
{
struct symbol *sym;
struct symtab_and_line start_sal;
struct cleanup *old_chain;
CORE_ADDR pc, saved_pc;
struct obj_section *section;
const char *name;
@ -3564,7 +3564,8 @@ skip_prologue_sal (struct symtab_and_line *sal)
if (sal->explicit_pc)
return;
old_chain = save_current_space_and_thread ();
scoped_restore_current_pspace_and_thread restore_pspace_thread;
switch_to_program_space_and_thread (sal->pspace);
sym = find_pc_sect_function (sal->pc, sal->section);
@ -3583,10 +3584,7 @@ skip_prologue_sal (struct symtab_and_line *sal)
= lookup_minimal_symbol_by_pc_section (sal->pc, sal->section);
if (msymbol.minsym == NULL)
{
do_cleanups (old_chain);
return;
}
return;
objfile = msymbol.objfile;
pc = BMSYMBOL_VALUE_ADDRESS (msymbol);
@ -3678,8 +3676,6 @@ skip_prologue_sal (struct symtab_and_line *sal)
start_sal = find_pc_sect_line (pc, section, 0);
}
do_cleanups (old_chain);
/* If we're already past the prologue, leave SAL unchanged. Otherwise
forward SAL to the end of the prologue. */
if (sal->pc >= pc)

View File

@ -1240,7 +1240,6 @@ print_thread_info_1 (struct ui_out *uiout, char *requested_threads,
{
struct thread_info *tp;
ptid_t current_ptid;
struct cleanup *old_chain;
const char *extra_info, *name, *target_id;
struct inferior *inf;
int default_inf_num = current_inferior ()->num;
@ -1248,8 +1247,7 @@ print_thread_info_1 (struct ui_out *uiout, char *requested_threads,
update_thread_list ();
current_ptid = inferior_ptid;
/* We'll be switching threads temporarily. */
old_chain = make_cleanup_restore_current_thread ();
struct cleanup *old_chain = make_cleanup (null_cleanup, NULL);
/* For backward compatibility, we make a list for MI. A table is
preferable for the CLI, though, because it shows table
@ -1296,98 +1294,104 @@ print_thread_info_1 (struct ui_out *uiout, char *requested_threads,
uiout->table_body ();
}
ALL_THREADS_BY_INFERIOR (inf, tp)
{
int core;
/* We'll be switching threads temporarily. */
{
scoped_restore_current_thread restore_thread;
if (!should_print_thread (requested_threads, default_inf_num,
global_ids, pid, tp))
continue;
ALL_THREADS_BY_INFERIOR (inf, tp)
{
int core;
ui_out_emit_tuple tuple_emitter (uiout, NULL);
if (!should_print_thread (requested_threads, default_inf_num,
global_ids, pid, tp))
continue;
if (!uiout->is_mi_like_p ())
{
if (tp->ptid == current_ptid)
uiout->field_string ("current", "*");
else
uiout->field_skip ("current");
}
ui_out_emit_tuple tuple_emitter (uiout, NULL);
if (!uiout->is_mi_like_p ())
uiout->field_string ("id-in-tg", print_thread_id (tp));
if (!uiout->is_mi_like_p ())
{
if (tp->ptid == current_ptid)
uiout->field_string ("current", "*");
else
uiout->field_skip ("current");
}
if (show_global_ids || uiout->is_mi_like_p ())
uiout->field_int ("id", tp->global_num);
if (!uiout->is_mi_like_p ())
uiout->field_string ("id-in-tg", print_thread_id (tp));
/* For the CLI, we stuff everything into the target-id field.
This is a gross hack to make the output come out looking
correct. The underlying problem here is that ui-out has no
way to specify that a field's space allocation should be
shared by several fields. For MI, we do the right thing
instead. */
if (show_global_ids || uiout->is_mi_like_p ())
uiout->field_int ("id", tp->global_num);
target_id = target_pid_to_str (tp->ptid);
extra_info = target_extra_thread_info (tp);
name = tp->name ? tp->name : target_thread_name (tp);
/* For the CLI, we stuff everything into the target-id field.
This is a gross hack to make the output come out looking
correct. The underlying problem here is that ui-out has no
way to specify that a field's space allocation should be
shared by several fields. For MI, we do the right thing
instead. */
if (uiout->is_mi_like_p ())
{
uiout->field_string ("target-id", target_id);
if (extra_info)
uiout->field_string ("details", extra_info);
if (name)
uiout->field_string ("name", name);
}
else
{
struct cleanup *str_cleanup;
char *contents;
target_id = target_pid_to_str (tp->ptid);
extra_info = target_extra_thread_info (tp);
name = tp->name ? tp->name : target_thread_name (tp);
if (extra_info && name)
contents = xstrprintf ("%s \"%s\" (%s)", target_id,
name, extra_info);
else if (extra_info)
contents = xstrprintf ("%s (%s)", target_id, extra_info);
else if (name)
contents = xstrprintf ("%s \"%s\"", target_id, name);
else
contents = xstrdup (target_id);
str_cleanup = make_cleanup (xfree, contents);
if (uiout->is_mi_like_p ())
{
uiout->field_string ("target-id", target_id);
if (extra_info)
uiout->field_string ("details", extra_info);
if (name)
uiout->field_string ("name", name);
}
else
{
struct cleanup *str_cleanup;
char *contents;
uiout->field_string ("target-id", contents);
do_cleanups (str_cleanup);
}
if (extra_info && name)
contents = xstrprintf ("%s \"%s\" (%s)", target_id,
name, extra_info);
else if (extra_info)
contents = xstrprintf ("%s (%s)", target_id, extra_info);
else if (name)
contents = xstrprintf ("%s \"%s\"", target_id, name);
else
contents = xstrdup (target_id);
str_cleanup = make_cleanup (xfree, contents);
if (tp->state == THREAD_RUNNING)
uiout->text ("(running)\n");
else
{
/* The switch below puts us at the top of the stack (leaf
frame). */
switch_to_thread (tp->ptid);
print_stack_frame (get_selected_frame (NULL),
/* For MI output, print frame level. */
uiout->is_mi_like_p (),
LOCATION, 0);
}
uiout->field_string ("target-id", contents);
do_cleanups (str_cleanup);
}
if (uiout->is_mi_like_p ())
{
const char *state = "stopped";
if (tp->state == THREAD_RUNNING)
uiout->text ("(running)\n");
else
{
/* The switch below puts us at the top of the stack (leaf
frame). */
switch_to_thread (tp->ptid);
print_stack_frame (get_selected_frame (NULL),
/* For MI output, print frame level. */
uiout->is_mi_like_p (),
LOCATION, 0);
}
if (tp->state == THREAD_RUNNING)
state = "running";
uiout->field_string ("state", state);
}
if (uiout->is_mi_like_p ())
{
const char *state = "stopped";
core = target_core_of_thread (tp->ptid);
if (uiout->is_mi_like_p () && core != -1)
uiout->field_int ("core", core);
if (tp->state == THREAD_RUNNING)
state = "running";
uiout->field_string ("state", state);
}
core = target_core_of_thread (tp->ptid);
if (uiout->is_mi_like_p () && core != -1)
uiout->field_int ("core", core);
}
/* Restores the current thread and the frame selected before
the "info threads" command. */
/* This end scope restores the current thread and the frame
selected before the "info threads" command. */
}
do_cleanups (old_chain);
if (pid == -1 && requested_threads == NULL)
@ -1559,70 +1563,43 @@ restore_selected_frame (struct frame_id a_frame_id, int frame_level)
}
}
/* Data used by the cleanup installed by
'make_cleanup_restore_current_thread'. */
struct current_thread_cleanup
scoped_restore_current_thread::~scoped_restore_current_thread ()
{
thread_info *thread;
struct frame_id selected_frame_id;
int selected_frame_level;
int was_stopped;
inferior *inf;
};
static void
do_restore_current_thread_cleanup (void *arg)
{
struct current_thread_cleanup *old = (struct current_thread_cleanup *) arg;
/* If an entry of thread_info was previously selected, it won't be
deleted because we've increased its refcount. The thread represented
by this thread_info entry may have already exited (due to normal exit,
detach, etc), so the thread_info.state is THREAD_EXITED. */
if (old->thread != NULL
if (m_thread != NULL
/* If the previously selected thread belonged to a process that has
in the mean time exited (or killed, detached, etc.), then don't revert
back to it, but instead simply drop back to no thread selected. */
&& old->inf->pid != 0)
switch_to_thread (old->thread);
&& m_inf->pid != 0)
switch_to_thread (m_thread);
else
{
switch_to_no_thread ();
set_current_inferior (old->inf);
set_current_inferior (m_inf);
}
/* The running state of the originally selected thread may have
changed, so we have to recheck it here. */
if (inferior_ptid != null_ptid
&& old->was_stopped
&& m_was_stopped
&& is_stopped (inferior_ptid)
&& target_has_registers
&& target_has_stack
&& target_has_memory)
restore_selected_frame (old->selected_frame_id,
old->selected_frame_level);
restore_selected_frame (m_selected_frame_id, m_selected_frame_level);
if (m_thread != NULL)
m_thread->decref ();
m_inf->decref ();
}
static void
restore_current_thread_cleanup_dtor (void *arg)
scoped_restore_current_thread::scoped_restore_current_thread ()
{
struct current_thread_cleanup *old = (struct current_thread_cleanup *) arg;
if (old->thread != NULL)
old->thread->decref ();
old->inf->decref ();
xfree (old);
}
struct cleanup *
make_cleanup_restore_current_thread (void)
{
struct current_thread_cleanup *old = XNEW (struct current_thread_cleanup);
old->thread = NULL;
old->inf = current_inferior ();
m_thread = NULL;
m_inf = current_inferior ();
if (inferior_ptid != null_ptid)
{
@ -1631,8 +1608,8 @@ make_cleanup_restore_current_thread (void)
gdb_assert (tp != NULL);
old->was_stopped = tp->state == THREAD_STOPPED;
if (old->was_stopped
m_was_stopped = tp->state == THREAD_STOPPED;
if (m_was_stopped
&& target_has_registers
&& target_has_stack
&& target_has_memory)
@ -1647,17 +1624,14 @@ make_cleanup_restore_current_thread (void)
else
frame = NULL;
old->selected_frame_id = get_frame_id (frame);
old->selected_frame_level = frame_relative_level (frame);
m_selected_frame_id = get_frame_id (frame);
m_selected_frame_level = frame_relative_level (frame);
tp->incref ();
old->thread = tp;
m_thread = tp;
}
old->inf->incref ();
return make_cleanup_dtor (do_restore_current_thread_cleanup, old,
restore_current_thread_cleanup_dtor);
m_inf->incref ();
}
/* See gdbthread.h. */
@ -1727,7 +1701,6 @@ tp_array_compar (const thread_info *a, const thread_info *b)
static void
thread_apply_all_command (char *cmd, int from_tty)
{
struct cleanup *old_chain;
char *saved_cmd;
tp_array_compar_ascending = false;
@ -1743,8 +1716,6 @@ thread_apply_all_command (char *cmd, int from_tty)
update_thread_list ();
old_chain = make_cleanup_restore_current_thread ();
/* Save a copy of the command in case it is clobbered by
execute_command. */
saved_cmd = xstrdup (cmd);
@ -1778,6 +1749,8 @@ thread_apply_all_command (char *cmd, int from_tty)
std::sort (thr_list_cpy.begin (), thr_list_cpy.end (), tp_array_compar);
scoped_restore_current_thread restore_thread;
for (thread_info *thr : thr_list_cpy)
if (thread_alive (thr))
{
@ -1791,8 +1764,6 @@ thread_apply_all_command (char *cmd, int from_tty)
strcpy (cmd, saved_cmd);
}
}
do_cleanups (old_chain);
}
/* Implementation of the "thread apply" command. */
@ -1831,7 +1802,7 @@ thread_apply_command (char *tidlist, int from_tty)
saved_cmd = xstrdup (cmd);
old_chain = make_cleanup (xfree, saved_cmd);
make_cleanup_restore_current_thread ();
scoped_restore_current_thread restore_thread;
parser.init (tidlist, current_inferior ()->num);
while (!parser.finished () && parser.cur_tok () < cmd)

View File

@ -2925,7 +2925,6 @@ tdump_command (char *args, int from_tty)
{
int stepping_frame = 0;
struct bp_location *loc;
struct cleanup *old_chain;
struct command_line *actions;
/* This throws an error is not inspecting a trace frame. */
@ -2936,14 +2935,13 @@ tdump_command (char *args, int from_tty)
/* This command only makes sense for the current frame, not the
selected frame. */
old_chain = make_cleanup_restore_current_thread ();
scoped_restore_current_thread restore_thread;
select_frame (get_current_frame ());
actions = all_tracepoint_actions_and_cleanup (loc->owner);
trace_dump_actions (actions, 0, stepping_frame, from_tty);
do_cleanups (old_chain);
}
/* Encode a piece of a tracepoint's source-level definition in a form

View File

@ -2218,14 +2218,13 @@ value_of_root_1 (struct varobj **var_handle)
struct value *new_val = NULL;
struct varobj *var = *var_handle;
int within_scope = 0;
struct cleanup *back_to;
/* Only root variables can be updated... */
if (!is_root_p (var))
/* Not a root var. */
return NULL;
back_to = make_cleanup_restore_current_thread ();
scoped_restore_current_thread restore_thread;
/* Determine whether the variable is still around. */
if (var->root->valid_block == NULL || var->root->floating)
@ -2264,8 +2263,6 @@ value_of_root_1 (struct varobj **var_handle)
END_CATCH
}
do_cleanups (back_to);
return new_val;
}