gdb: Remove cleanup from linux-fork.c:inferior_call_waitpid
Replace cleanup in linux-fork.c:inferior_call_waitpid with a RAII object. gdb/ChangeLog: * linux-fork.c (class scoped_switch_fork_info): New class. (inferior_call_waitpid): Update to use scoped_switch_fork_info.
This commit is contained in:
parent
26089c494f
commit
a07c88800e
2 changed files with 66 additions and 42 deletions
|
@ -1,3 +1,8 @@
|
||||||
|
2019-01-03 Andrew Burgess <andrew.burgess@embecosm.com>
|
||||||
|
|
||||||
|
* linux-fork.c (class scoped_switch_fork_info): New class.
|
||||||
|
(inferior_call_waitpid): Update to use scoped_switch_fork_info.
|
||||||
|
|
||||||
2019-01-03 Andrew Burgess <andrew.burgess@embecosm.com>
|
2019-01-03 Andrew Burgess <andrew.burgess@embecosm.com>
|
||||||
|
|
||||||
* valops.c (find_overload_match): Remove use of null_cleanup, and
|
* valops.c (find_overload_match): Remove use of null_cleanup, and
|
||||||
|
|
|
@ -437,45 +437,64 @@ linux_fork_detach (int from_tty)
|
||||||
delete_fork (inferior_ptid);
|
delete_fork (inferior_ptid);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
/* Temporarily switch to the infrun state stored on the fork_info
|
||||||
inferior_call_waitpid_cleanup (void *fp)
|
identified by a given ptid_t. When this object goes out of scope,
|
||||||
{
|
restore the currently selected infrun state. */
|
||||||
struct fork_info *oldfp = (struct fork_info *) fp;
|
|
||||||
|
|
||||||
if (oldfp)
|
class scoped_switch_fork_info
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
/* Switch to the infrun state held on the fork_info identified by
|
||||||
|
PPTID. If PPTID is the current inferior then no switch is done. */
|
||||||
|
scoped_switch_fork_info (ptid_t pptid)
|
||||||
|
: m_oldfp (nullptr)
|
||||||
|
{
|
||||||
|
if (pptid != inferior_ptid)
|
||||||
|
{
|
||||||
|
struct fork_info *newfp = nullptr;
|
||||||
|
|
||||||
|
/* Switch to pptid. */
|
||||||
|
m_oldfp = find_fork_ptid (inferior_ptid);
|
||||||
|
gdb_assert (m_oldfp != nullptr);
|
||||||
|
newfp = find_fork_ptid (pptid);
|
||||||
|
gdb_assert (newfp != nullptr);
|
||||||
|
fork_save_infrun_state (m_oldfp, 1);
|
||||||
|
remove_breakpoints ();
|
||||||
|
fork_load_infrun_state (newfp);
|
||||||
|
insert_breakpoints ();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Restore the previously selected infrun state. If the constructor
|
||||||
|
didn't need to switch states, then nothing is done here either. */
|
||||||
|
~scoped_switch_fork_info ()
|
||||||
|
{
|
||||||
|
if (m_oldfp != nullptr)
|
||||||
{
|
{
|
||||||
/* Switch back to inferior_ptid. */
|
/* Switch back to inferior_ptid. */
|
||||||
remove_breakpoints ();
|
remove_breakpoints ();
|
||||||
fork_load_infrun_state (oldfp);
|
fork_load_infrun_state (m_oldfp);
|
||||||
insert_breakpoints ();
|
insert_breakpoints ();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
DISABLE_COPY_AND_ASSIGN (scoped_switch_fork_info);
|
||||||
|
|
||||||
|
private:
|
||||||
|
/* The fork_info for the previously selected infrun state, or nullptr if
|
||||||
|
we were already in the desired state, and nothing needs to be
|
||||||
|
restored. */
|
||||||
|
struct fork_info *m_oldfp;
|
||||||
|
};
|
||||||
|
|
||||||
static int
|
static int
|
||||||
inferior_call_waitpid (ptid_t pptid, int pid)
|
inferior_call_waitpid (ptid_t pptid, int pid)
|
||||||
{
|
{
|
||||||
struct objfile *waitpid_objf;
|
struct objfile *waitpid_objf;
|
||||||
struct value *waitpid_fn = NULL;
|
struct value *waitpid_fn = NULL;
|
||||||
struct value *argv[3], *retv;
|
|
||||||
struct gdbarch *gdbarch = get_current_arch ();
|
|
||||||
struct fork_info *oldfp = NULL, *newfp = NULL;
|
|
||||||
struct cleanup *old_cleanup;
|
|
||||||
int ret = -1;
|
int ret = -1;
|
||||||
|
|
||||||
if (pptid != inferior_ptid)
|
scoped_switch_fork_info switch_fork_info (pptid);
|
||||||
{
|
|
||||||
/* Switch to pptid. */
|
|
||||||
oldfp = find_fork_ptid (inferior_ptid);
|
|
||||||
gdb_assert (oldfp != NULL);
|
|
||||||
newfp = find_fork_ptid (pptid);
|
|
||||||
gdb_assert (newfp != NULL);
|
|
||||||
fork_save_infrun_state (oldfp, 1);
|
|
||||||
remove_breakpoints ();
|
|
||||||
fork_load_infrun_state (newfp);
|
|
||||||
insert_breakpoints ();
|
|
||||||
}
|
|
||||||
|
|
||||||
old_cleanup = make_cleanup (inferior_call_waitpid_cleanup, oldfp);
|
|
||||||
|
|
||||||
/* Get the waitpid_fn. */
|
/* Get the waitpid_fn. */
|
||||||
if (lookup_minimal_symbol ("waitpid", NULL, NULL).minsym != NULL)
|
if (lookup_minimal_symbol ("waitpid", NULL, NULL).minsym != NULL)
|
||||||
|
@ -483,8 +502,10 @@ inferior_call_waitpid (ptid_t pptid, int pid)
|
||||||
if (!waitpid_fn
|
if (!waitpid_fn
|
||||||
&& lookup_minimal_symbol ("_waitpid", NULL, NULL).minsym != NULL)
|
&& lookup_minimal_symbol ("_waitpid", NULL, NULL).minsym != NULL)
|
||||||
waitpid_fn = find_function_in_inferior ("_waitpid", &waitpid_objf);
|
waitpid_fn = find_function_in_inferior ("_waitpid", &waitpid_objf);
|
||||||
if (!waitpid_fn)
|
if (waitpid_fn != nullptr)
|
||||||
goto out;
|
{
|
||||||
|
struct gdbarch *gdbarch = get_current_arch ();
|
||||||
|
struct value *argv[3], *retv;
|
||||||
|
|
||||||
/* Get the argv. */
|
/* Get the argv. */
|
||||||
argv[0] = value_from_longest (builtin_type (gdbarch)->builtin_int, pid);
|
argv[0] = value_from_longest (builtin_type (gdbarch)->builtin_int, pid);
|
||||||
|
@ -492,13 +513,11 @@ inferior_call_waitpid (ptid_t pptid, int pid)
|
||||||
argv[2] = value_from_longest (builtin_type (gdbarch)->builtin_int, 0);
|
argv[2] = value_from_longest (builtin_type (gdbarch)->builtin_int, 0);
|
||||||
|
|
||||||
retv = call_function_by_hand (waitpid_fn, NULL, argv);
|
retv = call_function_by_hand (waitpid_fn, NULL, argv);
|
||||||
if (value_as_long (retv) < 0)
|
|
||||||
goto out;
|
|
||||||
|
|
||||||
|
if (value_as_long (retv) >= 0)
|
||||||
ret = 0;
|
ret = 0;
|
||||||
|
}
|
||||||
|
|
||||||
out:
|
|
||||||
do_cleanups (old_cleanup);
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue