mirror of
https://github.com/espressif/binutils-gdb.git
synced 2025-10-19 05:42:42 +08:00
* varobj.c (struct varobj_root): New component thread_id.
(varobj_get_thread_id, check_scope): New functions. (c_value_of_root): Use check_scope. Switch to the proper thread if necessary. * varobj.h (varobj_get_thread_id): New extern. * mi/mi-cmd-var.c (print_varobj): Add thread-id field.
This commit is contained in:
@ -1,3 +1,15 @@
|
|||||||
|
2008-03-24 Nick Roberts <nickrob@snap.net.nz>
|
||||||
|
Vladimir Prus <vladimir@codesourcery.com>
|
||||||
|
|
||||||
|
* varobj.c (struct varobj_root): New component thread_id.
|
||||||
|
(varobj_get_thread_id, check_scope): New functions.
|
||||||
|
(c_value_of_root): Use check_scope. Switch to the
|
||||||
|
proper thread if necessary.
|
||||||
|
|
||||||
|
* varobj.h (varobj_get_thread_id): New extern.
|
||||||
|
|
||||||
|
* mi/mi-cmd-var.c (print_varobj): Add thread-id field.
|
||||||
|
|
||||||
2008-03-23 Daniel Jacobowitz <dan@codesourcery.com>
|
2008-03-23 Daniel Jacobowitz <dan@codesourcery.com>
|
||||||
|
|
||||||
PR gdb/544
|
PR gdb/544
|
||||||
|
@ -50,6 +50,7 @@ print_varobj (struct varobj *var, enum print_values print_values,
|
|||||||
{
|
{
|
||||||
struct type *gdb_type;
|
struct type *gdb_type;
|
||||||
char *type;
|
char *type;
|
||||||
|
int thread_id;
|
||||||
|
|
||||||
ui_out_field_string (uiout, "name", varobj_get_objname (var));
|
ui_out_field_string (uiout, "name", varobj_get_objname (var));
|
||||||
if (print_expression)
|
if (print_expression)
|
||||||
@ -66,6 +67,10 @@ print_varobj (struct varobj *var, enum print_values print_values,
|
|||||||
xfree (type);
|
xfree (type);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
thread_id = varobj_get_thread_id (var);
|
||||||
|
if (thread_id > 0)
|
||||||
|
ui_out_field_int (uiout, "thread-id", thread_id);
|
||||||
|
|
||||||
if (varobj_get_frozen (var))
|
if (varobj_get_frozen (var))
|
||||||
ui_out_field_int (uiout, "frozen", 1);
|
ui_out_field_int (uiout, "frozen", 1);
|
||||||
}
|
}
|
||||||
|
72
gdb/varobj.c
72
gdb/varobj.c
@ -68,6 +68,13 @@ struct varobj_root
|
|||||||
not NULL. */
|
not NULL. */
|
||||||
struct frame_id frame;
|
struct frame_id frame;
|
||||||
|
|
||||||
|
/* The thread ID that this varobj_root belong to. This field
|
||||||
|
is only valid if valid_block is not NULL.
|
||||||
|
When not 0, indicates which thread 'frame' belongs to.
|
||||||
|
When 0, indicates that the thread list was empty when the varobj_root
|
||||||
|
was created. */
|
||||||
|
int thread_id;
|
||||||
|
|
||||||
/* If 1, "update" always recomputes the frame & valid block
|
/* If 1, "update" always recomputes the frame & valid block
|
||||||
using the currently selected frame. */
|
using the currently selected frame. */
|
||||||
int use_selected_frame;
|
int use_selected_frame;
|
||||||
@ -503,8 +510,9 @@ varobj_create (char *objname,
|
|||||||
if (innermost_block && fi != NULL)
|
if (innermost_block && fi != NULL)
|
||||||
{
|
{
|
||||||
var->root->frame = get_frame_id (fi);
|
var->root->frame = get_frame_id (fi);
|
||||||
|
var->root->thread_id = pid_to_thread_id (inferior_ptid);
|
||||||
old_fi = get_selected_frame (NULL);
|
old_fi = get_selected_frame (NULL);
|
||||||
select_frame (fi);
|
select_frame (fi);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* We definitely need to catch errors here.
|
/* We definitely need to catch errors here.
|
||||||
@ -692,6 +700,19 @@ varobj_get_display_format (struct varobj *var)
|
|||||||
return var->format;
|
return var->format;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* If the variable object is bound to a specific thread, that
|
||||||
|
is its evaluation can always be done in context of a frame
|
||||||
|
inside that thread, returns GDB id of the thread -- which
|
||||||
|
is always positive. Otherwise, returns -1. */
|
||||||
|
int
|
||||||
|
varobj_get_thread_id (struct varobj *var)
|
||||||
|
{
|
||||||
|
if (var->root->valid_block && var->root->thread_id > 0)
|
||||||
|
return var->root->thread_id;
|
||||||
|
else
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
varobj_set_frozen (struct varobj *var, int frozen)
|
varobj_set_frozen (struct varobj *var, int frozen)
|
||||||
{
|
{
|
||||||
@ -2138,13 +2159,36 @@ c_path_expr_of_child (struct varobj *child)
|
|||||||
return child->path_expr;
|
return child->path_expr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* If frame associated with VAR can be found, switch
|
||||||
|
to it and return 1. Otherwise, return 0. */
|
||||||
|
static int
|
||||||
|
check_scope (struct varobj *var)
|
||||||
|
{
|
||||||
|
struct frame_info *fi;
|
||||||
|
int scope;
|
||||||
|
|
||||||
|
fi = frame_find_by_id (var->root->frame);
|
||||||
|
scope = fi != NULL;
|
||||||
|
|
||||||
|
if (fi)
|
||||||
|
{
|
||||||
|
CORE_ADDR pc = get_frame_pc (fi);
|
||||||
|
if (pc < BLOCK_START (var->root->valid_block) ||
|
||||||
|
pc >= BLOCK_END (var->root->valid_block))
|
||||||
|
scope = 0;
|
||||||
|
else
|
||||||
|
select_frame (fi);
|
||||||
|
}
|
||||||
|
return scope;
|
||||||
|
}
|
||||||
|
|
||||||
static struct value *
|
static struct value *
|
||||||
c_value_of_root (struct varobj **var_handle)
|
c_value_of_root (struct varobj **var_handle)
|
||||||
{
|
{
|
||||||
struct value *new_val = NULL;
|
struct value *new_val = NULL;
|
||||||
struct varobj *var = *var_handle;
|
struct varobj *var = *var_handle;
|
||||||
struct frame_info *fi;
|
struct frame_info *fi;
|
||||||
int within_scope;
|
int within_scope = 0;
|
||||||
struct cleanup *back_to;
|
struct cleanup *back_to;
|
||||||
|
|
||||||
/* Only root variables can be updated... */
|
/* Only root variables can be updated... */
|
||||||
@ -2158,20 +2202,22 @@ c_value_of_root (struct varobj **var_handle)
|
|||||||
/* Determine whether the variable is still around. */
|
/* Determine whether the variable is still around. */
|
||||||
if (var->root->valid_block == NULL || var->root->use_selected_frame)
|
if (var->root->valid_block == NULL || var->root->use_selected_frame)
|
||||||
within_scope = 1;
|
within_scope = 1;
|
||||||
|
else if (var->root->thread_id == 0)
|
||||||
|
{
|
||||||
|
/* The program was single-threaded when the variable object was
|
||||||
|
created. Technically, it's possible that the program became
|
||||||
|
multi-threaded since then, but we don't support such
|
||||||
|
scenario yet. */
|
||||||
|
within_scope = check_scope (var);
|
||||||
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
fi = frame_find_by_id (var->root->frame);
|
ptid_t ptid = thread_id_to_pid (var->root->thread_id);
|
||||||
within_scope = fi != NULL;
|
if (in_thread_list (ptid))
|
||||||
/* FIXME: select_frame could fail */
|
|
||||||
if (fi)
|
|
||||||
{
|
{
|
||||||
CORE_ADDR pc = get_frame_pc (fi);
|
switch_to_thread (ptid);
|
||||||
if (pc < BLOCK_START (var->root->valid_block) ||
|
within_scope = check_scope (var);
|
||||||
pc >= BLOCK_END (var->root->valid_block))
|
}
|
||||||
within_scope = 0;
|
|
||||||
else
|
|
||||||
select_frame (fi);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (within_scope)
|
if (within_scope)
|
||||||
|
@ -89,6 +89,8 @@ extern enum varobj_display_formats varobj_set_display_format (
|
|||||||
extern enum varobj_display_formats varobj_get_display_format (
|
extern enum varobj_display_formats varobj_get_display_format (
|
||||||
struct varobj *var);
|
struct varobj *var);
|
||||||
|
|
||||||
|
extern int varobj_get_thread_id (struct varobj *var);
|
||||||
|
|
||||||
extern void varobj_set_frozen (struct varobj *var, int frozen);
|
extern void varobj_set_frozen (struct varobj *var, int frozen);
|
||||||
|
|
||||||
extern int varobj_get_frozen (struct varobj *var);
|
extern int varobj_get_frozen (struct varobj *var);
|
||||||
|
Reference in New Issue
Block a user