I realise that Vladimir is also working on this too but this patch doesn't require Python scripting and it's quite simple too, just involving changes to varobj.c and mi-cmd-var.c. It uses a special variable object to keep track of the number of STL members as I described previously. It's for after the release of 6.8 and intended as the basis of a discussion. I don't expect it to be approved as is. Here's a sample transaction. Currently the variable object must be created after initialisation, e.g., (gdb) n &"n\n" ~"16\t vector v1; // create an empty vector of integers\n" ^done (gdb) -var-create - * v ^done,name="var1",numchild="1",value="{...}",type="std::vector >" (gdb) -var-list-children --all-values var1 ^done,numchild="4",children=[child={name="var1.0",exp="0",numchild="0",value="3",type="long"},child={name="var1.1",exp="1",numchild="0",value="0",type="int"},child={name="var1.2",exp="2",numchild="0",value="0",type="int"},child={name="var1.3",exp="3",numchild="0",value="0",type="int"}] (gdb) so that GDB doesn't find a ridiculous (uninitialised) number of children. Note there are four children. var1.0 is the special variable object which is equal to the actual number of STL members. (v._M_impl._M_finish - v._M_impl._M_start) u &"u\n" ~"33\t v[0] = 1;\n" ^done (gdb) u &"u\n" ~"34\t v[1] = 11;\n" ^done (gdb) u &"u\n" ~"35\t v[2] = 22;\n" ^done (gdb) Remember that line 35 hasn't been executed yet. -var-update --all-values * ^done,changelist=[{name="var1.1",value="1",in_scope="true",type_changed="false"},{name="var1.2",value="11",in_scope="true",type_changed="false"}] (gdb) u &"u\n" ~"36\t v.push_back (7);\n" ^done (gdb) Now it has. -var-update --all-values * ^done,changelist=[{name="var1.3",value="22",in_scope="true",type_changed="false"}] (gdb) u &"u\n" ~"38\t cout << endl;\n" ^done (gdb) Now v.push_back (7) has added a new member which changes the value of var1.0. -var-update --all-values * ^done,changelist=[{name="var1.0",value="4",in_scope="true",type_changed="false"}] (gdb) And we can automatically see the new member here. -var-list-children --all-values var1 ^done,numchild="5",children=[child={name="var1.0",exp="0",numchild="0",value="4",type="long"},child={name="var1.1",exp="1",numchild="0",value="1",type="int"},child={name="var1.2",exp="2",numchild="0",value="11",type="int"},child={name="var1.3",exp="3",numchild="0",value="22",type="int"},child={name="var1.4",exp="4",numchild="0",value="7",type="int"}] -- Nick http://www.inet.net.nz/~nickrob 2008-02-13 Nick Roberts * varobj.c (struct varobj): New member. (varobj_list_stl_children, create_stl_child, value_of_stl_child): New functions. (install_new_value): Create/delete STL children if number has changed. (varobj_update): Update STL children. (new_variable): Initialise stl component to 0. * mi/mi-cmd-var.c: Include wrapper.h. (mi_cmd_var_list_children): Compute STL children separately. *** varobj.c 05 Feb 2008 09:38:32 +1300 1.103 --- varobj.c 13 Feb 2008 16:10:13 +1300 *************** struct varobj *** 147,152 **** --- 147,156 ---- not fetched if either the variable is frozen, or any parents is frozen. */ int not_fetched; + + /* 0 means normal varobj, + 1 means special varobj to track number of STL members. */ + int stl; }; struct cpstack *************** static void uninstall_variable (struct v *** 178,183 **** --- 182,189 ---- static struct varobj *create_child (struct varobj *, int, char *); + static struct varobj *create_stl_child (struct varobj *, int, char *); + /* Utility routines */ static struct varobj *new_variable (void); *************** static struct value *value_of_root (stru *** 217,222 **** --- 223,230 ---- static struct value *value_of_child (struct varobj *parent, int index); + static struct value *value_of_stl_child (struct varobj *parent, int index); + static char *my_value_of_variable (struct varobj *var); static char *value_get_print_value (struct value *value, *************** varobj_list_children (struct varobj *var *** 758,763 **** --- 766,815 ---- return var->children; } + VEC (varobj_p)* + varobj_list_stl_children (struct varobj *var) + { + struct varobj *child; + struct value *value; + struct expression *expr; + char *stl_child; + char *name; + int i; + + + stl_child = xstrprintf ("%s.%s - %s.%s", + var->name, "_M_impl._M_finish", + var->name, "_M_impl._M_start"); + expr = parse_expression (stl_child); + gdb_evaluate_expression (expr, &value); + var->num_children = 1 + (int) unpack_long (value_type (value), + value_contents (value)); + xfree (stl_child); + + /* If we're called when the list of children is not yet initialized, + allocate enough elements in it. */ + while (VEC_length (varobj_p, var->children) < var->num_children) + VEC_safe_push (varobj_p, var->children, NULL); + + for (i = 0; i < var->num_children; i++) + { + varobj_p existing = VEC_index (varobj_p, var->children, i); + + if (existing == NULL) + { + /* Either it's the first call to varobj_list_children for + this variable object, and the child was never created, + or it was explicitly deleted by the client. */ + name = xstrprintf ("%d", i); + + existing = create_stl_child (var, i, name); + VEC_replace (varobj_p, var->children, i, existing); + } + } + + return var->children; + } + /* Obtain the type of an object Variable as a string similar to the one gdb prints on the console */ *************** install_new_value (struct varobj *var, s *** 1055,1061 **** gdb_assert (var->print_value != NULL && print_value != NULL); if (strcmp (var->print_value, print_value) != 0) ! changed = 1; } } } --- 1107,1117 ---- gdb_assert (var->print_value != NULL && print_value != NULL); if (strcmp (var->print_value, print_value) != 0) ! { ! changed = 1; ! if (var->stl) ! varobj_list_stl_children (var->parent); ! } } } } *************** varobj_update (struct varobj **varp, str *** 1191,1197 **** updated. */ if (v->root->rootvar != v) { ! new = value_of_child (v->parent, v->index); if (install_new_value (v, new, 0 /* type not changed */)) { /* Note that it's changed */ --- 1247,1266 ---- updated. */ if (v->root->rootvar != v) { ! struct expression *expr; ! struct value *value; ! char* stl_member; ! ! //TODO: Just deal with vectors for the moment. ! stl_member = xstrprintf ("%s._M_impl._M_start", ! varobj_get_expression (v->parent)); ! expr = parse_expression (stl_member); ! if (gdb_evaluate_expression (expr, &value)) ! new = value_of_stl_child (v->parent, v->index); ! else ! new = value_of_child (v->parent, v->index); ! xfree (stl_member); ! if (install_new_value (v, new, 0 /* type not changed */)) { /* Note that it's changed */ *************** create_child (struct varobj *parent, int *** 1448,1453 **** --- 1517,1557 ---- return child; } + + static struct varobj * + create_stl_child (struct varobj *parent, int index, char *name) + { + struct varobj *child; + char *childs_name; + struct value *value; + + child = new_variable (); + + /* name is allocated by name_of_child */ + child->name = name; + child->index = index; + value = value_of_stl_child (parent, index); + child->parent = parent; + child->root = parent->root; + childs_name = xstrprintf ("%s.%s", parent->obj_name, name); + child->obj_name = childs_name; + if (index == 0) child->stl = 1; + install_variable (child); + + /* Compute the type of the child. Must do this before + calling install_new_value. */ + if (value != NULL) + /* If the child had no evaluation errors, var->value + will be non-NULL and contain a valid type. */ + child->type = value_type (value); + else + /* Otherwise, we must compute the type. */ + child->type = (*child->root->lang->type_of_child) (child->parent, + child->index); + install_new_value (child, value, 1); + + return child; + } /* *************** new_variable (void) *** 1476,1481 **** --- 1580,1586 ---- var->print_value = NULL; var->frozen = 0; var->not_fetched = 0; + var->stl = 0; return var; } *************** value_of_child (struct varobj *parent, i *** 1768,1773 **** --- 1873,1901 ---- return value; } + static struct value * + value_of_stl_child (struct varobj *parent, int index) + { + struct expression *expr; + struct value *value; + char *stl_child; + + if (index == 0) + /* With i == 0, create a special varobj to detect creation/deletion + of STL members. */ + stl_child = xstrprintf ("%s.%s - %s.%s", + parent->name, "_M_impl._M_finish", + parent->name, "_M_impl._M_start"); + else + stl_child = xstrprintf ("*(%s.%s + %d)", + parent->name, "_M_impl._M_start", index - 1); + + expr = parse_expression (stl_child); + gdb_evaluate_expression (expr, &value); + xfree (stl_child); + return value; + } + /* GDB already has a command called "value_of_variable". Sigh. */ static char * my_value_of_variable (struct varobj *var) *** mi-cmd-var.c 05 Feb 2008 12:13:22 +1300 1.45 --- mi-cmd-var.c 13 Feb 2008 15:41:50 +1300 *************** *** 28,33 **** --- 28,34 ---- #include "value.h" #include #include "gdb_string.h" + #include "wrapper.h" const char mi_no_values[] = "--no-values"; const char mi_simple_values[] = "--simple-values"; *************** mi_cmd_var_list_children (char *command, *** 361,366 **** --- 362,370 ---- int numchild; enum print_values print_values; int ix; + struct expression *expr; + struct value *value; + char* stl_member; if (argc != 1 && argc != 2) error (_("mi_cmd_var_list_children: Usage: [PRINT_VALUES] NAME")); *************** mi_cmd_var_list_children (char *command, *** 373,379 **** if (var == NULL) error (_("Variable object not found")); ! children = varobj_list_children (var); ui_out_field_int (uiout, "numchild", VEC_length (varobj_p, children)); if (argc == 2) print_values = mi_parse_values_option (argv[0]); --- 377,391 ---- if (var == NULL) error (_("Variable object not found")); ! //TODO: Just deal with vectors for the moment. ! stl_member = xstrprintf ("%s._M_impl._M_start", varobj_get_expression (var)); ! expr = parse_expression (stl_member); ! if (gdb_evaluate_expression (expr, &value)) ! children = varobj_list_stl_children (var); ! else ! children = varobj_list_children (var); ! xfree (stl_member); ! ui_out_field_int (uiout, "numchild", VEC_length (varobj_p, children)); if (argc == 2) print_values = mi_parse_values_option (argv[0]); *************** varobj_update_one (struct varobj *var, e *** 651,657 **** cc++; } xfree (changelist); ! }Write failed flushing stdout buffer. ! write stdout: Broken pipe ! } --- 663,667 ---- cc++; } xfree (changelist); ! } }&j!z޶:X܆[\