This is the mail archive of the
gdb-patches@sourceware.org
mailing list for the GDB project.
[patch 4/8] Types GC [varobj_list to all_root_varobjs]
- From: Jan Kratochvil <jan dot kratochvil at redhat dot com>
- To: gdb-patches at sourceware dot org
- Date: Mon, 25 May 2009 10:02:33 +0200
- Subject: [patch 4/8] Types GC [varobj_list to all_root_varobjs]
Hi,
this patch is completely optional and it can be dropped, just technically the
other patches depend on it. I find the callback based iterator easier to use,
in fact there were bugs due to the current calling semantics (`floating'
lockup, memory leaks).
The new function all_root_varobjs really fully replaces varobj_list just
varobj_list gets finally dropped only in the patch 8/8.
Thanks,
Jan
gdb/
2009-05-25 Jan Kratochvil <jan.kratochvil@redhat.com>
* mi/mi-cmd-var.c (mi_cmd_var_update): Remove variables var, rootlist,
cr, nv. Initialize CLEANUP and "changelist" uncoditionally. Move the
all variables handling code to ...
(mi_cmd_var_update_iter): ... a new function.
(struct mi_cmd_var_update): New.
* varobj.c (varobj_list): Define the function now as static.
(all_root_varobjs): New function.
* varobj.h (varobj_list): Remove the declaration.
(all_root_varobjs): New declaration.
---
gdb/mi/mi-cmd-var.c | 96 ++++++++++++++++++++++++++++-----------------------
gdb/varobj.c | 20 ++++++++++-
gdb/varobj.h | 3 +-
3 files changed, 74 insertions(+), 45 deletions(-)
diff --git a/gdb/mi/mi-cmd-var.c b/gdb/mi/mi-cmd-var.c
index 9de8d3d..688999c 100644
--- a/gdb/mi/mi-cmd-var.c
+++ b/gdb/mi/mi-cmd-var.c
@@ -542,15 +542,46 @@ mi_cmd_var_assign (char *command, char **argv, int argc)
ui_out_field_string (uiout, "value", varobj_get_value (var));
}
+/* Type used for parameters passing to mi_cmd_var_update_iter. */
+
+struct mi_cmd_var_update
+ {
+ int only_floating;
+ enum print_values print_values;
+ };
+
+/* Helper for mi_cmd_var_update - update each VAR. */
+
+static void
+mi_cmd_var_update_iter (struct varobj *var, void *data_pointer)
+{
+ struct mi_cmd_var_update *data = data_pointer;
+ int thread_id, thread_stopped;
+
+ thread_id = varobj_get_thread_id (var);
+
+ if (thread_id == -1 && is_stopped (inferior_ptid))
+ thread_stopped = 1;
+ else
+ {
+ struct thread_info *tp = find_thread_id (thread_id);
+
+ if (tp)
+ thread_stopped = is_stopped (tp->ptid);
+ else
+ thread_stopped = 1;
+ }
+
+ if (thread_stopped)
+ if (!data->only_floating || varobj_floating_p (var))
+ varobj_update_one (var, data->print_values, 0 /* implicit */);
+}
+
void
mi_cmd_var_update (char *command, char **argv, int argc)
{
- struct varobj *var;
- struct varobj **rootlist;
- struct varobj **cr;
struct cleanup *cleanup;
char *name;
- int nv;
enum print_values print_values;
if (argc != 1 && argc != 2)
@@ -566,56 +597,35 @@ mi_cmd_var_update (char *command, char **argv, int argc)
else
print_values = PRINT_NO_VALUES;
+ if (mi_version (uiout) <= 1)
+ cleanup = make_cleanup_ui_out_tuple_begin_end (uiout, "changelist");
+ else
+ cleanup = make_cleanup_ui_out_list_begin_end (uiout, "changelist");
+
/* Check if the parameter is a "*" which means that we want
to update all variables */
if ((*name == '*' || *name == '@') && (*(name + 1) == '\0'))
{
- nv = varobj_list (&rootlist);
- cleanup = make_cleanup (xfree, rootlist);
- if (mi_version (uiout) <= 1)
- make_cleanup_ui_out_tuple_begin_end (uiout, "changelist");
- else
- make_cleanup_ui_out_list_begin_end (uiout, "changelist");
- if (nv <= 0)
- {
- do_cleanups (cleanup);
- return;
- }
- cr = rootlist;
- while (*cr != NULL)
- {
- int thread_id = varobj_get_thread_id (*cr);
- int thread_stopped = 0;
- if (thread_id == -1 && is_stopped (inferior_ptid))
- thread_stopped = 1;
- else
- {
- struct thread_info *tp = find_thread_id (thread_id);
- if (tp)
- thread_stopped = is_stopped (tp->ptid);
- else
- thread_stopped = 1;
- }
- if (thread_stopped)
- if (*name == '*' || varobj_floating_p (*cr))
- varobj_update_one (*cr, print_values, 0 /* implicit */);
- cr++;
- }
- do_cleanups (cleanup);
+ struct mi_cmd_var_update data;
+
+ data.only_floating = *name == '@';
+ data.print_values = print_values;
+
+ /* varobj_update_one automatically updates all the children of VAROBJ.
+ Therefore update each VAROBJ only once by iterating only the root
+ VAROBJs. */
+
+ all_root_varobjs (mi_cmd_var_update_iter, &data);
}
else
{
- /* Get varobj handle, if a valid var obj name was specified */
- var = varobj_get_handle (name);
+ struct varobj *var = varobj_get_handle (name);
- if (mi_version (uiout) <= 1)
- cleanup = make_cleanup_ui_out_tuple_begin_end (uiout, "changelist");
- else
- cleanup = make_cleanup_ui_out_list_begin_end (uiout, "changelist");
varobj_update_one (var, print_values, 1 /* explicit */);
- do_cleanups (cleanup);
}
+
+ do_cleanups (cleanup);
}
/* Helper for mi_cmd_var_update(). */
diff --git a/gdb/varobj.c b/gdb/varobj.c
index e8556d7..718c690 100644
--- a/gdb/varobj.c
+++ b/gdb/varobj.c
@@ -946,7 +946,7 @@ varobj_set_value (struct varobj *var, char *expression)
}
/* Returns a malloc'ed list with all root variable objects */
-int
+static int
varobj_list (struct varobj ***varlist)
{
struct varobj **cv;
@@ -2734,6 +2734,24 @@ java_value_of_variable (struct varobj *var, enum varobj_display_formats format)
{
return cplus_value_of_variable (var, format);
}
+
+/* Iterate all the existing _root_ VAROBJs and call the FUNC callback for them
+ with an arbitrary caller supplied DATA pointer. */
+
+void
+all_root_varobjs (void (*func) (struct varobj *var, void *data), void *data)
+{
+ struct varobj_root *var_root, *var_root_next;
+
+ /* Iterate "safely" - handle if the callee deletes its passed VAROBJ. */
+
+ for (var_root = rootlist; var_root != NULL; var_root = var_root_next)
+ {
+ var_root_next = var_root->next;
+
+ (*func) (var_root->rootvar, data);
+ }
+}
extern void _initialize_varobj (void);
void
diff --git a/gdb/varobj.h b/gdb/varobj.h
index f2cdcf8..c1471d4 100644
--- a/gdb/varobj.h
+++ b/gdb/varobj.h
@@ -130,7 +130,8 @@ extern char *varobj_get_value (struct varobj *var);
extern int varobj_set_value (struct varobj *var, char *expression);
-extern int varobj_list (struct varobj ***rootlist);
+extern void all_root_varobjs (void (*func) (struct varobj *var, void *data),
+ void *data);
extern VEC(varobj_update_result) *varobj_update (struct varobj **varp,
int explicit);
--
1.6.2.2