From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 1239 invoked by alias); 23 Mar 2008 04:41:07 -0000 Received: (qmail 1226 invoked by uid 22791); 23 Mar 2008 04:41:05 -0000 X-Spam-Check-By: sourceware.org Received: from viper.snap.net.nz (HELO viper.snap.net.nz) (202.37.101.8) by sourceware.org (qpsmtpd/0.31) with ESMTP; Sun, 23 Mar 2008 04:40:28 +0000 Received: from kahikatea.snap.net.nz (165.60.255.123.dynamic.snap.net.nz [123.255.60.165]) by viper.snap.net.nz (Postfix) with ESMTP id A8ADB3DA63A; Sun, 23 Mar 2008 17:40:19 +1300 (NZDT) Received: by kahikatea.snap.net.nz (Postfix, from userid 1000) id 3D5C08FC6D; Sun, 23 Mar 2008 16:40:18 +1200 (NZST) From: Nick Roberts MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Transfer-Encoding: 7bit Message-ID: <18405.57137.166048.407495@kahikatea.snap.net.nz> Date: Sun, 23 Mar 2008 09:25:00 -0000 To: Vladimir Prus Cc: gdb@sources.redhat.com Subject: Re: MI non-stop mode spec In-Reply-To: <200803222033.11760.vladimir@codesourcery.com> References: <200803190016.02072.vladimir@codesourcery.com> <200803211307.50963.vladimir@codesourcery.com> <18404.21429.467420.339546@kahikatea.snap.net.nz> <200803222033.11760.vladimir@codesourcery.com> X-Mailer: VM 7.19 under Emacs 22.1.92.2 X-IsSubscribed: yes Mailing-List: contact gdb-help@sourceware.org; run by ezmlm Precedence: bulk List-Id: List-Subscribe: List-Archive: List-Post: List-Help: , Sender: gdb-owner@sourceware.org X-SW-Source: 2008-03/txt/msg00195.txt.bz2 > > > > > Didn't you check in a patch to make *-varobjs be found to a > > > > > thread? > > > > > > > > I submitted a patch earlier this year that stopped thinking that > > > > a variable object had gone out of scope if the thread changed > > > > but nothing happened. > > > > > > Can you resend the current version of that patch, and I'll take a > > > look. > > > > I used pid_to_thread_id (inferior_ptid) for the thread_id, just as > > infrun.c does for *stopped. I think that the thread_id problem for > > single/multi-threaded programs should be fixed first (perhaps along > > the lines Daniel suggested). > > Dan's patch is in, however, it only affects Linux. I suspect in might > be a long time till the problem is solved on all system. Until then, > we probably should assume that if thread list is empty, then the > program is ST and never will become MT. > > I happen to be working on variable objects for non-stop now, so I'll > play with the last version of your patch that you have posted. I've made some changes since then so here's my latest patch updated to current sources. I found that after all I did need thread_id == -2 for global variables (used in mi-cmd-var which doesn't print the thread_id field for them since their value is the same in all threads). -- Nick http://www.inet.net.nz/~nickrob 2008-03-23 Nick Roberts * thread.c (make_cleanup_restore_current_thread) (do_restore_current_thread_cleanup): Don't make static (struct current_thread_cleanup): Move to gdbthread.h * gdbthread.h: Declare above functions as externs here. * varobj.c (struct varobj_root): New component thread_id. (varobj_get_thread_id, check_scope): New functions. (c_value_of_root): Use it to iterate over threads. * varobj.h (varobj_get_thread_id): New extern. * Makefile.in (varobj_h): Update dependencies. * mi/mi-cmd-var.c (print_varobj): Add thread-id field. Index: thread.c =================================================================== RCS file: /cvs/src/src/gdb/thread.c,v retrieving revision 1.64 diff -p -r1.64 thread.c *** thread.c 21 Mar 2008 15:44:53 -0000 1.64 --- thread.c 23 Mar 2008 04:36:10 -0000 *************** static void info_threads_command (char * *** 61,68 **** static void thread_apply_command (char *, int); static void restore_current_thread (ptid_t); static void prune_threads (void); - static struct cleanup *make_cleanup_restore_current_thread (ptid_t, - struct frame_id); void delete_step_resume_breakpoint (void *arg) --- 61,66 ---- *************** restore_selected_frame (struct frame_id *** 555,567 **** } } ! struct current_thread_cleanup ! { ! ptid_t inferior_ptid; ! struct frame_id selected_frame_id; ! }; ! ! static void do_restore_current_thread_cleanup (void *arg) { struct current_thread_cleanup *old = arg; --- 553,559 ---- } } ! void do_restore_current_thread_cleanup (void *arg) { struct current_thread_cleanup *old = arg; *************** do_restore_current_thread_cleanup (void *** 570,576 **** xfree (old); } ! static struct cleanup * make_cleanup_restore_current_thread (ptid_t inferior_ptid, struct frame_id a_frame_id) { --- 562,568 ---- xfree (old); } ! struct cleanup * make_cleanup_restore_current_thread (ptid_t inferior_ptid, struct frame_id a_frame_id) { Index: gdbthread.h =================================================================== RCS file: /cvs/src/src/gdb/gdbthread.h,v retrieving revision 1.21 diff -p -r1.21 gdbthread.h *** gdbthread.h 21 Mar 2008 15:44:53 -0000 1.21 --- gdbthread.h 23 Mar 2008 04:36:10 -0000 *************** extern void load_infrun_state (ptid_t pt *** 149,154 **** --- 149,165 ---- /* Switch from one thread to another. */ extern void switch_to_thread (ptid_t ptid); + struct current_thread_cleanup + { + ptid_t inferior_ptid; + struct frame_id selected_frame_id; + }; + + extern void do_restore_current_thread_cleanup (void *arg); + + extern struct cleanup * make_cleanup_restore_current_thread + (ptid_t inferior_ptid, struct frame_id a_frame_id); + /* Commands with a prefix of `thread'. */ extern struct cmd_list_element *thread_cmd_list; Index: varobj.c =================================================================== RCS file: /cvs/src/src/gdb/varobj.c,v retrieving revision 1.103 diff -p -r1.103 varobj.c *** varobj.c 4 Feb 2008 07:49:04 -0000 1.103 --- varobj.c 23 Mar 2008 04:36:12 -0000 *************** *** 24,30 **** --- 24,32 ---- #include "language.h" #include "wrapper.h" #include "gdbcmd.h" + #include "gdbthread.h" #include "block.h" + #include "inferior.h" #include "gdb_assert.h" #include "gdb_string.h" *************** struct varobj_root *** 65,70 **** --- 67,78 ---- /* The frame for this expression */ struct frame_id frame; + /* GDB thread id. + 0 means that the application is single-threaded. + -1 means that the thread is dead. + -2 means that this expression is a global variable. */ + int thread_id; + /* If 1, "update" always recomputes the frame & valid block using the currently selected frame. */ int use_selected_frame; *************** varobj_create (char *objname, *** 488,493 **** --- 496,506 ---- var->format = variable_default_display (var); var->root->valid_block = innermost_block; + if (innermost_block) + var->root->thread_id = pid_to_thread_id (inferior_ptid); + else + /* Give global variables a thread_id of -2. */ + var->root->thread_id = -2; expr_len = strlen (expression); var->name = savestring (expression, expr_len); /* For a root var, the name and the expr are the same. */ *************** varobj_get_display_format (struct varobj *** 689,694 **** --- 702,713 ---- return var->format; } + int + varobj_get_thread_id (struct varobj *var) + { + return var->root->thread_id; + } + void varobj_set_frozen (struct varobj *var, int frozen) { *************** c_path_expr_of_child (struct varobj *chi *** 2145,2181 **** return child->path_expr; } static struct value * c_value_of_root (struct varobj **var_handle) { struct value *new_val = NULL; struct varobj *var = *var_handle; ! struct frame_info *fi; ! int within_scope; /* Only root variables can be updated... */ if (!is_root_p (var)) /* Not a root var */ return NULL; - /* Determine whether the variable is still around. */ if (var->root->valid_block == NULL || var->root->use_selected_frame) within_scope = 1; else { ! fi = frame_find_by_id (var->root->frame); ! within_scope = fi != NULL; ! /* FIXME: select_frame could fail */ ! if (fi) { ! CORE_ADDR pc = get_frame_pc (fi); ! if (pc < BLOCK_START (var->root->valid_block) || ! pc >= BLOCK_END (var->root->valid_block)) ! within_scope = 0; ! else ! select_frame (fi); ! } } if (within_scope) --- 2164,2228 ---- return child->path_expr; } + static int + check_scope (struct varobj *var) + { + struct frame_info *fi; + int scope; + + fi = frame_find_by_id (var->root->frame); + scope = fi != NULL; + + /* FIXME: select_frame could fail */ + 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 * c_value_of_root (struct varobj **var_handle) { struct value *new_val = NULL; struct varobj *var = *var_handle; ! struct frame_id saved_frame_id; ! struct cleanup *old_cleanups = NULL; ! int within_scope, thread_id; ! ptid_t ptid; /* Only root variables can be updated... */ if (!is_root_p (var)) /* Not a root var */ return NULL; /* Determine whether the variable is still around. */ if (var->root->valid_block == NULL || var->root->use_selected_frame) within_scope = 1; else { ! thread_id = var->root->thread_id; ! ptid = thread_id_to_pid (thread_id); ! if (thread_id == 0) ! /* Single-threaded application. */ ! within_scope = check_scope (var); ! else if (thread_id != -1 && target_thread_alive (ptid)) { ! ! saved_frame_id = get_frame_id (get_selected_frame (NULL)); ! old_cleanups = make_cleanup_restore_current_thread (inferior_ptid, ! saved_frame_id); ! switch_to_thread (ptid); ! within_scope = check_scope (var); ! } ! else ! /* Mark it as dead. */ ! var->root->thread_id = -1; } if (within_scope) *************** c_value_of_root (struct varobj **var_han *** 2186,2191 **** --- 2233,2240 ---- return new_val; } + do_cleanups (old_cleanups); + return NULL; } Index: varobj.h =================================================================== RCS file: /cvs/src/src/gdb/varobj.h,v retrieving revision 1.15 diff -p -r1.15 varobj.h *** varobj.h 30 Jan 2008 07:17:31 -0000 1.15 --- varobj.h 23 Mar 2008 04:36:12 -0000 *************** extern enum varobj_display_formats varob *** 89,94 **** --- 89,96 ---- extern enum varobj_display_formats varobj_get_display_format ( struct varobj *var); + extern int varobj_get_thread_id (struct varobj *var); + extern void varobj_set_frozen (struct varobj *var, int frozen); extern int varobj_get_frozen (struct varobj *var); Index: mi/mi-cmd-var.c =================================================================== RCS file: /cvs/src/src/gdb/mi/mi-cmd-var.c,v retrieving revision 1.45 diff -p -r1.45 mi-cmd-var.c *** mi/mi-cmd-var.c 30 Jan 2008 07:17:31 -0000 1.45 --- mi/mi-cmd-var.c 23 Mar 2008 04:36:15 -0000 *************** print_varobj (struct varobj *var, enum p *** 50,55 **** --- 50,56 ---- { struct type *gdb_type; char *type; + int thread_id; ui_out_field_string (uiout, "name", varobj_get_objname (var)); if (print_expression) *************** print_varobj (struct varobj *var, enum p *** 66,71 **** --- 67,76 ---- 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)) ui_out_field_int (uiout, "frozen", 1); } Index: Makefile.in =================================================================== RCS file: /cvs/src/src/gdb/Makefile.in,v retrieving revision 1.994 diff -p -r1.994 Makefile.in *** Makefile.in 21 Mar 2008 17:09:35 -0000 1.994 --- Makefile.in 23 Mar 2008 04:36:15 -0000 *************** user_regs_h = user-regs.h *** 901,907 **** valprint_h = valprint.h value_h = value.h $(doublest_h) $(frame_h) $(symtab_h) $(gdbtypes_h) \ $(expression_h) ! varobj_h = varobj.h $(symtab_h) $(gdbtypes_h) $(vec_h) vax_tdep_h = vax-tdep.h vec_h = vec.h $(gdb_assert_h) $(gdb_string_h) version_h = version.h --- 901,908 ---- valprint_h = valprint.h value_h = value.h $(doublest_h) $(frame_h) $(symtab_h) $(gdbtypes_h) \ $(expression_h) ! varobj_h = varobj.h $(symtab_h) $(gdbtypes_h) $(vec_h) $(inferior_h) \ ! $(gdbthread_h) vax_tdep_h = vax-tdep.h vec_h = vec.h $(gdb_assert_h) $(gdb_string_h) version_h = version.h