Add constructor and destructor to thread_info

This patch adds constructor and destructor to thread_info.

gdb:

2017-03-29  Yao Qi  <yao.qi@linaro.org>

	* gdbthread.h (struct thread_info): Declare constructor and
	destructor.  Add some in-class member initializers.
	* thread.c (free_thread): Remove.
	(init_thread_list): Call delete instead of free_thread.
	(new_thread): Call thread_info constructor.
	(thread_info::thread_info): New function.
	(thread_info::~thread_info): New function.
	(delete_thread_1): Call delete instead of free_thread.
	(make_cleanup_restore_current_thread): Move tp and frame to
	inner block.
This commit is contained in:
Yao Qi 2017-03-29 16:56:31 +01:00
parent 52be03fd13
commit 1231656410
3 changed files with 76 additions and 60 deletions

View File

@ -1,3 +1,16 @@
2017-03-29 Yao Qi <yao.qi@linaro.org>
* gdbthread.h (struct thread_info): Declare constructor and
destructor. Add some in-class member initializers.
* thread.c (free_thread): Remove.
(init_thread_list): Call delete instead of free_thread.
(new_thread): Call thread_info constructor.
(thread_info::thread_info): New function.
(thread_info::~thread_info): New function.
(delete_thread_1): Call delete instead of free_thread.
(make_cleanup_restore_current_thread): Move tp and frame to
inner block.
2017-03-28 Anton Kolesov <anton.kolesov@synopsys.com> 2017-03-28 Anton Kolesov <anton.kolesov@synopsys.com>
* arc-tdep.c (arc_frame_cache): Add support for prologue analysis. * arc-tdep.c (arc_frame_cache): Add support for prologue analysis.

View File

@ -179,7 +179,11 @@ typedef VEC (value_ptr) value_vec;
struct thread_info struct thread_info
{ {
struct thread_info *next; public:
explicit thread_info (inferior *inf, ptid_t ptid);
~thread_info ();
struct thread_info *next = NULL;
ptid_t ptid; /* "Actual process id"; ptid_t ptid; /* "Actual process id";
In fact, this may be overloaded with In fact, this may be overloaded with
kernel thread id, etc. */ kernel thread id, etc. */
@ -226,13 +230,13 @@ struct thread_info
/* The name of the thread, as specified by the user. This is NULL /* The name of the thread, as specified by the user. This is NULL
if the thread does not have a user-given name. */ if the thread does not have a user-given name. */
char *name; char *name = NULL;
/* Non-zero means the thread is executing. Note: this is different /* Non-zero means the thread is executing. Note: this is different
from saying that there is an active target and we are stopped at from saying that there is an active target and we are stopped at
a breakpoint, for instance. This is a real indicator whether the a breakpoint, for instance. This is a real indicator whether the
thread is off and running. */ thread is off and running. */
int executing; int executing = 0;
/* Non-zero if this thread is resumed from infrun's perspective. /* Non-zero if this thread is resumed from infrun's perspective.
Note that a thread can be marked both as not-executing and Note that a thread can be marked both as not-executing and
@ -241,30 +245,30 @@ struct thread_info
thread really run until that wait status has been processed, but thread really run until that wait status has been processed, but
we should not process that wait status if we didn't try to let we should not process that wait status if we didn't try to let
the thread run. */ the thread run. */
int resumed; int resumed = 0;
/* Frontend view of the thread state. Note that the THREAD_RUNNING/ /* Frontend view of the thread state. Note that the THREAD_RUNNING/
THREAD_STOPPED states are different from EXECUTING. When the THREAD_STOPPED states are different from EXECUTING. When the
thread is stopped internally while handling an internal event, thread is stopped internally while handling an internal event,
like a software single-step breakpoint, EXECUTING will be false, like a software single-step breakpoint, EXECUTING will be false,
but STATE will still be THREAD_RUNNING. */ but STATE will still be THREAD_RUNNING. */
enum thread_state state; enum thread_state state = THREAD_STOPPED;
/* If this is > 0, then it means there's code out there that relies /* If this is > 0, then it means there's code out there that relies
on this thread being listed. Don't delete it from the lists even on this thread being listed. Don't delete it from the lists even
if we detect it exiting. */ if we detect it exiting. */
int refcount; int refcount = 0;
/* State of GDB control of inferior thread execution. /* State of GDB control of inferior thread execution.
See `struct thread_control_state'. */ See `struct thread_control_state'. */
struct thread_control_state control; thread_control_state control {};
/* State of inferior thread to restore after GDB is done with an inferior /* State of inferior thread to restore after GDB is done with an inferior
call. See `struct thread_suspend_state'. */ call. See `struct thread_suspend_state'. */
struct thread_suspend_state suspend; thread_suspend_state suspend {};
int current_line; int current_line = 0;
struct symtab *current_symtab; struct symtab *current_symtab = NULL;
/* Internal stepping state. */ /* Internal stepping state. */
@ -274,20 +278,20 @@ struct thread_info
by proceed and keep_going, and among other things, it's used in by proceed and keep_going, and among other things, it's used in
adjust_pc_after_break to distinguish a hardware single-step adjust_pc_after_break to distinguish a hardware single-step
SIGTRAP from a breakpoint SIGTRAP. */ SIGTRAP from a breakpoint SIGTRAP. */
CORE_ADDR prev_pc; CORE_ADDR prev_pc = 0;
/* Did we set the thread stepping a breakpoint instruction? This is /* Did we set the thread stepping a breakpoint instruction? This is
used in conjunction with PREV_PC to decide whether to adjust the used in conjunction with PREV_PC to decide whether to adjust the
PC. */ PC. */
int stepped_breakpoint; int stepped_breakpoint = 0;
/* Should we step over breakpoint next time keep_going is called? */ /* Should we step over breakpoint next time keep_going is called? */
int stepping_over_breakpoint; int stepping_over_breakpoint = 0;
/* Should we step over a watchpoint next time keep_going is called? /* Should we step over a watchpoint next time keep_going is called?
This is needed on targets with non-continuable, non-steppable This is needed on targets with non-continuable, non-steppable
watchpoints. */ watchpoints. */
int stepping_over_watchpoint; int stepping_over_watchpoint = 0;
/* Set to TRUE if we should finish single-stepping over a breakpoint /* Set to TRUE if we should finish single-stepping over a breakpoint
after hitting the current step-resume breakpoint. The context here after hitting the current step-resume breakpoint. The context here
@ -298,12 +302,12 @@ struct thread_info
step_after_step_resume_breakpoint is set to TRUE at this moment in step_after_step_resume_breakpoint is set to TRUE at this moment in
order to keep GDB in mind that there is still a breakpoint to step over order to keep GDB in mind that there is still a breakpoint to step over
when GDB gets back SIGTRAP from step_resume_breakpoint. */ when GDB gets back SIGTRAP from step_resume_breakpoint. */
int step_after_step_resume_breakpoint; int step_after_step_resume_breakpoint = 0;
/* Pointer to the state machine manager object that handles what is /* Pointer to the state machine manager object that handles what is
left to do for the thread's execution command after the target left to do for the thread's execution command after the target
stops. Several execution commands use it. */ stops. Several execution commands use it. */
struct thread_fsm *thread_fsm; struct thread_fsm *thread_fsm = NULL;
/* This is used to remember when a fork or vfork event was caught by /* This is used to remember when a fork or vfork event was caught by
a catchpoint, and thus the event is to be followed at the next a catchpoint, and thus the event is to be followed at the next
@ -311,37 +315,37 @@ struct thread_info
struct target_waitstatus pending_follow; struct target_waitstatus pending_follow;
/* True if this thread has been explicitly requested to stop. */ /* True if this thread has been explicitly requested to stop. */
int stop_requested; int stop_requested = 0;
/* The initiating frame of a nexting operation, used for deciding /* The initiating frame of a nexting operation, used for deciding
which exceptions to intercept. If it is null_frame_id no which exceptions to intercept. If it is null_frame_id no
bp_longjmp or bp_exception but longjmp has been caught just for bp_longjmp or bp_exception but longjmp has been caught just for
bp_longjmp_call_dummy. */ bp_longjmp_call_dummy. */
struct frame_id initiating_frame; struct frame_id initiating_frame = null_frame_id;
/* Private data used by the target vector implementation. */ /* Private data used by the target vector implementation. */
struct private_thread_info *priv; struct private_thread_info *priv = NULL;
/* Function that is called to free PRIVATE. If this is NULL, then /* Function that is called to free PRIVATE. If this is NULL, then
xfree will be called on PRIVATE. */ xfree will be called on PRIVATE. */
void (*private_dtor) (struct private_thread_info *); void (*private_dtor) (struct private_thread_info *) = NULL;
/* Branch trace information for this thread. */ /* Branch trace information for this thread. */
struct btrace_thread_info btrace; struct btrace_thread_info btrace {};
/* Flag which indicates that the stack temporaries should be stored while /* Flag which indicates that the stack temporaries should be stored while
evaluating expressions. */ evaluating expressions. */
int stack_temporaries_enabled; int stack_temporaries_enabled = 0;
/* Values that are stored as temporaries on stack while evaluating /* Values that are stored as temporaries on stack while evaluating
expressions. */ expressions. */
value_vec *stack_temporaries; value_vec *stack_temporaries = NULL;
/* Step-over chain. A thread is in the step-over queue if these are /* Step-over chain. A thread is in the step-over queue if these are
non-NULL. If only a single thread is in the chain, then these non-NULL. If only a single thread is in the chain, then these
fields point to self. */ fields point to self. */
struct thread_info *step_over_prev; struct thread_info *step_over_prev = NULL;
struct thread_info *step_over_next; struct thread_info *step_over_next = NULL;
}; };
/* Create an empty thread list, or empty the existing one. */ /* Create an empty thread list, or empty the existing one. */

View File

@ -192,21 +192,6 @@ clear_thread_inferior_resources (struct thread_info *tp)
thread_cancel_execution_command (tp); thread_cancel_execution_command (tp);
} }
static void
free_thread (struct thread_info *tp)
{
if (tp->priv)
{
if (tp->private_dtor)
tp->private_dtor (tp->priv);
else
xfree (tp->priv);
}
xfree (tp->name);
xfree (tp);
}
void void
init_thread_list (void) init_thread_list (void)
{ {
@ -220,7 +205,7 @@ init_thread_list (void)
for (tp = thread_list; tp; tp = tpnext) for (tp = thread_list; tp; tp = tpnext)
{ {
tpnext = tp->next; tpnext = tp->next;
free_thread (tp); delete tp;
} }
thread_list = NULL; thread_list = NULL;
@ -233,16 +218,7 @@ init_thread_list (void)
static struct thread_info * static struct thread_info *
new_thread (struct inferior *inf, ptid_t ptid) new_thread (struct inferior *inf, ptid_t ptid)
{ {
struct thread_info *tp; thread_info *tp = new thread_info (inf, ptid);
gdb_assert (inf != NULL);
tp = XCNEW (struct thread_info);
tp->ptid = ptid;
tp->global_num = ++highest_thread_num;
tp->inf = inf;
tp->per_inf_num = ++inf->highest_thread_num;
if (thread_list == NULL) if (thread_list == NULL)
thread_list = tp; thread_list = tp;
@ -255,11 +231,6 @@ new_thread (struct inferior *inf, ptid_t ptid)
last->next = tp; last->next = tp;
} }
/* Nothing to follow yet. */
tp->pending_follow.kind = TARGET_WAITKIND_SPURIOUS;
tp->state = THREAD_STOPPED;
tp->suspend.waitstatus.kind = TARGET_WAITKIND_IGNORE;
return tp; return tp;
} }
@ -336,6 +307,33 @@ add_thread (ptid_t ptid)
return add_thread_with_info (ptid, NULL); return add_thread_with_info (ptid, NULL);
} }
thread_info::thread_info (struct inferior *inf_, ptid_t ptid_)
: ptid (ptid_), inf (inf_)
{
gdb_assert (inf_ != NULL);
this->global_num = ++highest_thread_num;
this->per_inf_num = ++inf_->highest_thread_num;
/* Nothing to follow yet. */
memset (&this->pending_follow, 0, sizeof (this->pending_follow));
this->pending_follow.kind = TARGET_WAITKIND_SPURIOUS;
this->suspend.waitstatus.kind = TARGET_WAITKIND_IGNORE;
}
thread_info::~thread_info ()
{
if (this->priv)
{
if (this->private_dtor)
this->private_dtor (this->priv);
else
xfree (this->priv);
}
xfree (this->name);
}
/* Add TP to the end of the step-over chain LIST_P. */ /* Add TP to the end of the step-over chain LIST_P. */
static void static void
@ -470,7 +468,7 @@ delete_thread_1 (ptid_t ptid, int silent)
else else
thread_list = tp->next; thread_list = tp->next;
free_thread (tp); delete tp;
} }
/* Delete thread PTID and notify of thread exit. If this is /* Delete thread PTID and notify of thread exit. If this is
@ -1655,8 +1653,6 @@ set_thread_refcount (void *data)
struct cleanup * struct cleanup *
make_cleanup_restore_current_thread (void) make_cleanup_restore_current_thread (void)
{ {
struct thread_info *tp;
struct frame_info *frame;
struct current_thread_cleanup *old = XNEW (struct current_thread_cleanup); struct current_thread_cleanup *old = XNEW (struct current_thread_cleanup);
old->inferior_ptid = inferior_ptid; old->inferior_ptid = inferior_ptid;
@ -1668,6 +1664,8 @@ make_cleanup_restore_current_thread (void)
if (!ptid_equal (inferior_ptid, null_ptid)) if (!ptid_equal (inferior_ptid, null_ptid))
{ {
struct frame_info *frame;
old->was_stopped = is_stopped (inferior_ptid); old->was_stopped = is_stopped (inferior_ptid);
if (old->was_stopped if (old->was_stopped
&& target_has_registers && target_has_registers
@ -1687,7 +1685,8 @@ make_cleanup_restore_current_thread (void)
old->selected_frame_id = get_frame_id (frame); old->selected_frame_id = get_frame_id (frame);
old->selected_frame_level = frame_relative_level (frame); old->selected_frame_level = frame_relative_level (frame);
tp = find_thread_ptid (inferior_ptid); struct thread_info *tp = find_thread_ptid (inferior_ptid);
if (tp) if (tp)
tp->refcount++; tp->refcount++;
} }