gdb/continuations: use lambdas instead of function pointers
Use lambdas and std::list to track inferior continuations. This is a refactoring. gdb/ChangeLog: 2021-04-22 Tankut Baris Aktemur <tankut.baris.aktemur@intel.com> * inferior.h (class inferior) <continuations>: Change the type to be an std::list of std::function's. Update the references and uses below. * continuations.c (struct continuation): Delete. (make_continuation): Delete. (do_my_continuations_1): Delete. (do_my_continuations): Delete. (discard_my_continuations_1): Delete. (discard_my_continuations): Delete. (add_inferior_continuation): Update. (do_all_inferior_continuations): Update. (discard_all_inferior_continuations): Update. * continuations.h (add_inferior_continuation): Update to take an std::function as the parameter. * infcmd.c (struct attach_command_continuation_args): Delete. (attach_command_continuation): Delete. (attach_command_continuation_free_args): Delete. (attach_command): Update. (notice_new_inferior): Update.
This commit is contained in:
parent
1194676e0b
commit
c4c493de2b
5 changed files with 48 additions and 143 deletions
|
@ -1,3 +1,25 @@
|
|||
2021-04-22 Tankut Baris Aktemur <tankut.baris.aktemur@intel.com>
|
||||
|
||||
* inferior.h (class inferior) <continuations>: Change the type
|
||||
to be an std::list of std::function's.
|
||||
Update the references and uses below.
|
||||
* continuations.c (struct continuation): Delete.
|
||||
(make_continuation): Delete.
|
||||
(do_my_continuations_1): Delete.
|
||||
(do_my_continuations): Delete.
|
||||
(discard_my_continuations_1): Delete.
|
||||
(discard_my_continuations): Delete.
|
||||
(add_inferior_continuation): Update.
|
||||
(do_all_inferior_continuations): Update.
|
||||
(discard_all_inferior_continuations): Update.
|
||||
* continuations.h (add_inferior_continuation): Update to take
|
||||
an std::function as the parameter.
|
||||
* infcmd.c (struct attach_command_continuation_args): Delete.
|
||||
(attach_command_continuation): Delete.
|
||||
(attach_command_continuation_free_args): Delete.
|
||||
(attach_command): Update.
|
||||
(notice_new_inferior): Update.
|
||||
|
||||
2021-04-22 Tankut Baris Aktemur <tankut.baris.aktemur@intel.com>
|
||||
|
||||
* continuations.h: Update the general comment.
|
||||
|
|
|
@ -22,98 +22,15 @@
|
|||
#include "inferior.h"
|
||||
#include "continuations.h"
|
||||
|
||||
struct continuation
|
||||
{
|
||||
struct continuation *next;
|
||||
continuation_ftype *function;
|
||||
continuation_free_arg_ftype *free_arg;
|
||||
void *arg;
|
||||
};
|
||||
|
||||
/* Add a new continuation to the continuation chain. Args are
|
||||
FUNCTION to run the continuation up with, and ARG to pass to
|
||||
it. */
|
||||
|
||||
static void
|
||||
make_continuation (struct continuation **pmy_chain,
|
||||
continuation_ftype *function,
|
||||
void *arg, void (*free_arg) (void *))
|
||||
{
|
||||
struct continuation *newobj = XNEW (struct continuation);
|
||||
|
||||
newobj->next = *pmy_chain;
|
||||
newobj->function = function;
|
||||
newobj->free_arg = free_arg;
|
||||
newobj->arg = arg;
|
||||
*pmy_chain = newobj;
|
||||
}
|
||||
|
||||
static void
|
||||
do_my_continuations_1 (struct continuation **pmy_chain)
|
||||
{
|
||||
struct continuation *ptr;
|
||||
|
||||
while ((ptr = *pmy_chain) != NULL)
|
||||
{
|
||||
*pmy_chain = ptr->next; /* Do this first in case of recursion. */
|
||||
(*ptr->function) (ptr->arg);
|
||||
if (ptr->free_arg)
|
||||
(*ptr->free_arg) (ptr->arg);
|
||||
xfree (ptr);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
do_my_continuations (struct continuation **list)
|
||||
{
|
||||
struct continuation *continuations;
|
||||
|
||||
if (*list == NULL)
|
||||
return;
|
||||
|
||||
/* Copy the list header into another pointer, and set the global
|
||||
list header to null, so that the global list can change as a side
|
||||
effect of invoking the continuations and the processing of the
|
||||
preexisting continuations will not be affected. */
|
||||
|
||||
continuations = *list;
|
||||
*list = NULL;
|
||||
|
||||
/* Work now on the list we have set aside. */
|
||||
do_my_continuations_1 (&continuations);
|
||||
}
|
||||
|
||||
static void
|
||||
discard_my_continuations_1 (struct continuation **pmy_chain)
|
||||
{
|
||||
struct continuation *ptr;
|
||||
|
||||
while ((ptr = *pmy_chain) != NULL)
|
||||
{
|
||||
*pmy_chain = ptr->next;
|
||||
if (ptr->free_arg)
|
||||
(*ptr->free_arg) (ptr->arg);
|
||||
xfree (ptr);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
discard_my_continuations (struct continuation **list)
|
||||
{
|
||||
discard_my_continuations_1 (list);
|
||||
*list = NULL;
|
||||
}
|
||||
|
||||
/* Add a continuation to the continuation list of INFERIOR. The new
|
||||
continuation will be added at the front. */
|
||||
|
||||
void
|
||||
add_inferior_continuation (continuation_ftype *hook, void *args,
|
||||
continuation_free_arg_ftype *free_arg)
|
||||
add_inferior_continuation (std::function<void ()> &&cont)
|
||||
{
|
||||
struct inferior *inf = current_inferior ();
|
||||
|
||||
make_continuation (&inf->continuations, hook, args, free_arg);
|
||||
inf->continuations.emplace_front (std::move (cont));
|
||||
}
|
||||
|
||||
/* Do all continuations of the current inferior. */
|
||||
|
@ -122,7 +39,12 @@ void
|
|||
do_all_inferior_continuations ()
|
||||
{
|
||||
struct inferior *inf = current_inferior ();
|
||||
do_my_continuations (&inf->continuations);
|
||||
while (!inf->continuations.empty ())
|
||||
{
|
||||
auto iter = inf->continuations.begin ();
|
||||
(*iter) ();
|
||||
inf->continuations.erase (iter);
|
||||
}
|
||||
}
|
||||
|
||||
/* Get rid of all the inferior-wide continuations of INF. */
|
||||
|
@ -130,5 +52,5 @@ do_all_inferior_continuations ()
|
|||
void
|
||||
discard_all_inferior_continuations (struct inferior *inf)
|
||||
{
|
||||
discard_my_continuations (&inf->continuations);
|
||||
inf->continuations.clear ();
|
||||
}
|
||||
|
|
|
@ -20,29 +20,19 @@
|
|||
#ifndef CONTINUATIONS_H
|
||||
#define CONTINUATIONS_H
|
||||
|
||||
#include <functional>
|
||||
|
||||
struct inferior;
|
||||
|
||||
/* To continue the execution commands when running gdb asynchronously.
|
||||
A continuation structure contains a pointer to a function to be called
|
||||
to finish the command, once the target has stopped. Such mechanism is
|
||||
used by the attach command and the remote target when a new inferior
|
||||
is detected. */
|
||||
|
||||
/* Prototype of the continuation callback functions. ARG is the
|
||||
continuation argument registered in the corresponding
|
||||
add_*_continuation call. */
|
||||
typedef void (continuation_ftype) (void *arg);
|
||||
|
||||
/* Prototype of the function responsible for releasing the argument
|
||||
passed to the continuation callback functions, either when the
|
||||
continuation is called, or discarded. */
|
||||
typedef void (continuation_free_arg_ftype) (void *);
|
||||
A continuation is an std::function to be called to finish the
|
||||
command, once the target has stopped. Such mechanism is used by
|
||||
the attach command and the remote target when a new inferior is
|
||||
detected. */
|
||||
|
||||
/* Inferior specific (any thread) continuations. */
|
||||
|
||||
extern void add_inferior_continuation (continuation_ftype *,
|
||||
void *,
|
||||
continuation_free_arg_ftype *);
|
||||
extern void add_inferior_continuation (std::function<void ()> &&cont);
|
||||
extern void do_all_inferior_continuations ();
|
||||
extern void discard_all_inferior_continuations (struct inferior *inf);
|
||||
|
||||
|
|
45
gdb/infcmd.c
45
gdb/infcmd.c
|
@ -2540,30 +2540,6 @@ attach_post_wait (int from_tty, enum attach_post_wait_mode mode)
|
|||
}
|
||||
}
|
||||
|
||||
struct attach_command_continuation_args
|
||||
{
|
||||
int from_tty;
|
||||
enum attach_post_wait_mode mode;
|
||||
};
|
||||
|
||||
static void
|
||||
attach_command_continuation (void *args)
|
||||
{
|
||||
struct attach_command_continuation_args *a
|
||||
= (struct attach_command_continuation_args *) args;
|
||||
|
||||
attach_post_wait (a->from_tty, a->mode);
|
||||
}
|
||||
|
||||
static void
|
||||
attach_command_continuation_free_args (void *args)
|
||||
{
|
||||
struct attach_command_continuation_args *a
|
||||
= (struct attach_command_continuation_args *) args;
|
||||
|
||||
xfree (a);
|
||||
}
|
||||
|
||||
/* "attach" command entry point. Takes a program started up outside
|
||||
of gdb and ``attaches'' to it. This stops it cold in its tracks
|
||||
and allows us to start debugging it. */
|
||||
|
@ -2661,8 +2637,6 @@ attach_command (const char *args, int from_tty)
|
|||
E.g. Mach 3 or GNU hurd. */
|
||||
if (!target_attach_no_wait ())
|
||||
{
|
||||
struct attach_command_continuation_args *a;
|
||||
|
||||
/* Careful here. See comments in inferior.h. Basically some
|
||||
OSes don't ignore SIGSTOPs on continue requests anymore. We
|
||||
need a way for handle_inferior_event to reset the stop_signal
|
||||
|
@ -2671,11 +2645,10 @@ attach_command (const char *args, int from_tty)
|
|||
inferior->control.stop_soon = STOP_QUIETLY_NO_SIGSTOP;
|
||||
|
||||
/* Wait for stop. */
|
||||
a = XNEW (struct attach_command_continuation_args);
|
||||
a->from_tty = from_tty;
|
||||
a->mode = mode;
|
||||
add_inferior_continuation (attach_command_continuation, a,
|
||||
attach_command_continuation_free_args);
|
||||
add_inferior_continuation ([=] ()
|
||||
{
|
||||
attach_post_wait (from_tty, mode);
|
||||
});
|
||||
|
||||
/* Let infrun consider waiting for events out of this
|
||||
target. */
|
||||
|
@ -2719,7 +2692,6 @@ notice_new_inferior (thread_info *thr, int leave_running, int from_tty)
|
|||
|
||||
if (thr->executing)
|
||||
{
|
||||
struct attach_command_continuation_args *a;
|
||||
struct inferior *inferior = current_inferior ();
|
||||
|
||||
/* We're going to install breakpoints, and poke at memory,
|
||||
|
@ -2730,11 +2702,10 @@ notice_new_inferior (thread_info *thr, int leave_running, int from_tty)
|
|||
inferior->control.stop_soon = STOP_QUIETLY_REMOTE;
|
||||
|
||||
/* Wait for stop before proceeding. */
|
||||
a = XNEW (struct attach_command_continuation_args);
|
||||
a->from_tty = from_tty;
|
||||
a->mode = mode;
|
||||
add_inferior_continuation (attach_command_continuation, a,
|
||||
attach_command_continuation_free_args);
|
||||
add_inferior_continuation ([=] ()
|
||||
{
|
||||
attach_post_wait (from_tty, mode);
|
||||
});
|
||||
|
||||
return;
|
||||
}
|
||||
|
|
|
@ -22,6 +22,7 @@
|
|||
#define INFERIOR_H 1
|
||||
|
||||
#include <exception>
|
||||
#include <list>
|
||||
|
||||
struct target_waitstatus;
|
||||
struct frame_info;
|
||||
|
@ -32,7 +33,6 @@ struct regcache;
|
|||
struct ui_out;
|
||||
struct terminal_info;
|
||||
struct target_desc_info;
|
||||
struct continuation;
|
||||
struct inferior;
|
||||
struct thread_info;
|
||||
|
||||
|
@ -510,7 +510,7 @@ public:
|
|||
|
||||
/* What is left to do for an execution command after any thread of
|
||||
this inferior stops. */
|
||||
continuation *continuations = NULL;
|
||||
std::list<std::function<void ()>> continuations;
|
||||
|
||||
/* True if setup_inferior wasn't called for this inferior yet.
|
||||
Until that is done, we must not access inferior memory or
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue