This is the mail archive of the
mailing list for the Archer project.
Crash when casting a gdb.Value
- From: Richard Ward <richard dot j dot ward1 at googlemail dot com>
- To: archer at sourceware dot org
- Date: Tue, 26 May 2009 13:48:07 +0100
- Subject: Crash when casting a gdb.Value
Found a reproducible crash in the project archer python branch.
The problem occurs when you cast a gdb.Value to it's own type.
Reproduction (works with any executable):
python v=gdb.Value("string");v=v.cast(v.type);print v
Sometimes have to run the last command a few times to make sure python's
Garbage Collection kicks in. When it does it will segfault, or one of a
couple of other (probably fatal) things will happen.
This occurs because when you cast a value to its own type valpy_cast will
call value_to_value_object with a value that is already tracked by a
value_object, and at some point down the line it will be double-freed.
If its of any use I've attached a patch that fixes valpy_cast, and adds a
warning to the comment above value_to_value_object. I also checked all
the other callers to value_to_value_object, but they all seem ok.
It would seem nicer if value_to_value_object could track whether a value
its being passed is already tracked, and increment the refcount if it was,
but that would require either extra space or extra time.
This was found on an up to date git checkout of origin/archer-tromey-python.
2009-05-25 Richard Ward <firstname.lastname@example.org>
Fixed bad call in valpy_cast to value_to_value_object which was
causing a crash when the value was collected.
Added a warning about this problem in comment.
diff --git a/gdb/python/python-value.c b/gdb/python/python-value.c
index 743e6a6..25ae901 100644
@@ -235,6 +235,7 @@ valpy_cast (PyObject *self, PyObject *args)
struct type *type;
struct value *res_val = NULL; /* Initialize to appease gcc warning. */
volatile struct gdb_exception except;
+ struct value *val=((value_object *) self)->value;
if (! PyArg_ParseTuple (args, "O", &type_obj))
@@ -248,11 +249,17 @@ valpy_cast (PyObject *self, PyObject *args)
TRY_CATCH (except, RETURN_MASK_ALL)
- res_val = value_cast (type, ((value_object *) self)->value);
+ res_val = value_cast (type, val);
- return value_to_value_object (res_val);
+ if(res_val == val)
+ return self;
+ return value_to_value_object (res_val);
@@ -793,7 +800,12 @@ valpy_float (PyObject *self)
/* Returns an object for a value which is released from the all_values chain,
- so its lifetime is not bound to the execution of a command. */
+ so its lifetime is not bound to the execution of a command.
+ DO NOT call with a value that is already stored in a value_object, as
+ this will eventually crash gdb. If necessary value_copy can be used
+ first. It may be better if values_in_python could track the PyObjects to
+ which they are assigned and this function could manipulate their
+ refcounts. */
value_to_value_object (struct value *val)