From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 27670 invoked by alias); 25 May 2009 08:02:48 -0000 Received: (qmail 27268 invoked by uid 22791); 25 May 2009 08:02:43 -0000 X-SWARE-Spam-Status: No, hits=-2.1 required=5.0 tests=AWL,BAYES_00,J_CHICKENPOX_62,SPF_HELO_PASS,SPF_PASS X-Spam-Check-By: sourceware.org Received: from mx2.redhat.com (HELO mx2.redhat.com) (66.187.237.31) by sourceware.org (qpsmtpd/0.43rc1) with ESMTP; Mon, 25 May 2009 08:02:38 +0000 Received: from int-mx2.corp.redhat.com (int-mx2.corp.redhat.com [172.16.27.26]) by mx2.redhat.com (8.13.8/8.13.8) with ESMTP id n4P82bjY013935 for ; Mon, 25 May 2009 04:02:37 -0400 Received: from ns3.rdu.redhat.com (ns3.rdu.redhat.com [10.11.255.199]) by int-mx2.corp.redhat.com (8.13.1/8.13.1) with ESMTP id n4P82Z1V006375 for ; Mon, 25 May 2009 04:02:36 -0400 Received: from host0.dyn.jankratochvil.net (sebastian-int.corp.redhat.com [172.16.52.221]) by ns3.rdu.redhat.com (8.13.8/8.13.8) with ESMTP id n4P82Yl0017063 for ; Mon, 25 May 2009 04:02:35 -0400 Received: from host0.dyn.jankratochvil.net (localhost [127.0.0.1]) by host0.dyn.jankratochvil.net (8.14.3/8.14.3) with ESMTP id n4P82Xk5013864 for ; Mon, 25 May 2009 10:02:34 +0200 Received: (from jkratoch@localhost) by host0.dyn.jankratochvil.net (8.14.3/8.14.3/Submit) id n4P82XIF013862 for gdb-patches@sourceware.org; Mon, 25 May 2009 10:02:33 +0200 Date: Mon, 25 May 2009 08:02:00 -0000 From: Jan Kratochvil To: gdb-patches@sourceware.org Subject: [patch 4/8] Types GC [varobj_list to all_root_varobjs] Message-ID: <20090525080233.GD13323@host0.dyn.jankratochvil.net> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline User-Agent: Mutt/1.5.19 (2009-01-05) X-IsSubscribed: yes Mailing-List: contact gdb-patches-help@sourceware.org; run by ezmlm Precedence: bulk List-Id: List-Subscribe: List-Archive: List-Post: List-Help: , Sender: gdb-patches-owner@sourceware.org X-SW-Source: 2009-05/txt/msg00547.txt.bz2 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 * 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