This is the mail archive of the
gdb@sources.redhat.com
mailing list for the GDB project.
Re: -var-create on invalid expression causes seg. fault
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 <dan@codesourcery.com>
* 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) \