From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 1755 invoked by alias); 23 Feb 2005 16:00:51 -0000 Mailing-List: contact gdb-help@sources.redhat.com; run by ezmlm Precedence: bulk List-Subscribe: List-Archive: List-Post: List-Help: , Sender: gdb-owner@sources.redhat.com Received: (qmail 1599 invoked from network); 23 Feb 2005 16:00:42 -0000 Received: from unknown (HELO nevyn.them.org) (66.93.172.17) by sourceware.org with SMTP; 23 Feb 2005 16:00:42 -0000 Received: from drow by nevyn.them.org with local (Exim 4.44 #1 (Debian)) id 1D3yw6-0007ru-Ri; Wed, 23 Feb 2005 11:00:26 -0500 Date: Wed, 23 Feb 2005 16:23:00 -0000 From: Daniel Jacobowitz To: Ross Morley Cc: Nick Roberts , gdb@sources.redhat.com Subject: Re: -var-create on invalid expression causes seg. fault Message-ID: <20050223160026.GA27996@nevyn.them.org> Mail-Followup-To: Ross Morley , Nick Roberts , gdb@sources.redhat.com References: <16919.48311.476960.352611@farnswood.snap.net.nz> <42184BBA.6030007@tensilica.com> Mime-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <42184BBA.6030007@tensilica.com> User-Agent: Mutt/1.5.6+20040907i X-SW-Source: 2005-02/txt/msg00148.txt.bz2 On Sun, Feb 20, 2005 at 12:35:06AM -0800, Ross Morley wrote: > Thanks for your input Nick, but I don't think it's what I need. > > I already know exactly where the problem is (I debugged it under gdb). > What I don't know is the right way to fix it. > Also I believe this bug exists in 6.3 because the offending code is > the same, though I haven't tried to reproduce it there. > > I should have mentioned that a seg. fault does not always immediately > result. It just depends how the freed memory is used after it's freed. > If it's allocated again and its new owner alters the location that was > var->value to contain 0 or some other bad address, the seg. fault will > occur. Otherwise the problem may lurk for a long time and show up > later in some obscure way or not at all. So it's a bit hard to reproduce > the seg. fault, but if you read my post and run it under gdb you should > easily be able to verify that a pointer to freed memory is dereferenced. > > I'm hoping someone who knows the internals of MI variables can suggest > a good fix that won't break something else. It's not as simple as > clearing that hanging pointer... that will just cause a seg. fault > for sure when the pointer is dereferenced. If no one knows, I'll > probably just have to dive in and educate myself. Could you give the attached patch a try? I encountered a similar problem in mi-var-block.exp when using ARM RVDS, which emits location lists even at -O0. It frequently reports variables as "unavailable", which is an error condition. The patch sets the variable to an error in the -var-update "unavailable" case; this never passes any error message on to the user, but that seems to be the prior art for varobj. You'll need to use catch_exceptions for your older sources; the patch is for HEAD. [I haven't finished testing any of these patches, that's why I haven't submitted this to gdb-patches yet.] -- Daniel Jacobowitz CodeSourcery, LLC 2005-02-23 Daniel Jacobowitz * Makefile.in (eval.o): Update dependencies. * eval.c: Include "ui-out.h" and "exceptions.h". (evaluate_subexp_standard): Use TRY_CATCH around value_of_variable. Use value_zero if an error occurs when avoiding side effects. * varobj.c (varobj_create): Call release_value after evaluate_type. (c_value_of_root): Initialize new_val. Don't release_value a NULL value. Index: src/gdb/eval.c =================================================================== --- src.orig/gdb/eval.c 2005-02-17 14:29:06.000000000 -0800 +++ src/gdb/eval.c 2005-02-23 07:02:08.000000000 -0800 @@ -37,6 +37,8 @@ #include "block.h" #include "parser-defs.h" #include "cp-support.h" +#include "ui-out.h" +#include "exceptions.h" /* This is defined in valops.c */ extern int overload_resolution; @@ -437,8 +439,26 @@ evaluate_subexp_standard (struct type *e value_rtti_target_type () if we are dealing with a pointer or reference to a base class and print object is on. */ - return value_of_variable (exp->elts[pc + 2].symbol, - exp->elts[pc + 1].block); + { + volatile struct exception except; + struct value *ret = NULL; + + TRY_CATCH (except, RETURN_MASK_ERROR) + { + ret = value_of_variable (exp->elts[pc + 2].symbol, + exp->elts[pc + 1].block); + } + + if (except.reason < 0) + { + if (noside == EVAL_AVOID_SIDE_EFFECTS) + ret = value_zero (SYMBOL_TYPE (exp->elts[pc + 2].symbol), not_lval); + else + throw_exception (except); + } + + return ret; + } case OP_LAST: (*pos) += 2; Index: src/gdb/varobj.c =================================================================== --- src.orig/gdb/varobj.c 2005-02-17 14:29:06.000000000 -0800 +++ src/gdb/varobj.c 2005-02-23 07:12:25.000000000 -0800 @@ -504,7 +504,10 @@ varobj_create (char *objname, gdb_value_fetch_lazy (var->value); } else - var->value = evaluate_type (var->root->exp); + { + var->value = evaluate_type (var->root->exp); + release_value (var->value); + } var->type = value_type (var->value); @@ -1873,7 +1876,7 @@ c_name_of_child (struct varobj *parent, static struct value * c_value_of_root (struct varobj **var_handle) { - struct value *new_val; + struct value *new_val = NULL; struct varobj *var = *var_handle; struct frame_info *fi; int within_scope; @@ -1917,11 +1920,12 @@ c_value_of_root (struct varobj **var_han else var->error = 0; } + + release_value (new_val); } else var->error = 1; - release_value (new_val); return new_val; } Index: src/gdb/Makefile.in =================================================================== --- src.orig/gdb/Makefile.in 2005-02-14 12:09:02.000000000 -0800 +++ src/gdb/Makefile.in 2005-02-23 07:00:39.000000000 -0800 @@ -1891,7 +1891,7 @@ environ.o: environ.c $(defs_h) $(environ eval.o: eval.c $(defs_h) $(gdb_string_h) $(symtab_h) $(gdbtypes_h) \ $(value_h) $(expression_h) $(target_h) $(frame_h) $(language_h) \ $(f_lang_h) $(cp_abi_h) $(infcall_h) $(objc_lang_h) $(block_h) \ - $(parser_defs_h) $(cp_support_h) + $(parser_defs_h) $(cp_support_h) $(exceptions_h) $(uiout_h) event-loop.o: event-loop.c $(defs_h) $(event_loop_h) $(event_top_h) \ $(gdb_string_h) $(exceptions_h) event-top.o: event-top.c $(defs_h) $(top_h) $(inferior_h) $(target_h) \