This is the mail archive of the
gdb-patches@sourceware.org
mailing list for the GDB project.
Fix crash in -var-delete
- From: Vladimir Prus <ghost at cs dot msu dot su>
- To: gdb-patches at sources dot redhat dot com
- Date: Wed, 7 Nov 2007 22:57:59 +0300
- Subject: Fix crash in -var-delete
A KDevelop user has reported that gdb 6.7 consistently crashes when
used in KDevelop. Of course, I should have tested gdb 6.7 before it's released,
but it's too late at this point, so here's a patch instead.
Historically, KDevelop deletes variable objects recursively -- first most
nested ones, then their parents and so on. Note that while it's not necessary
in most cases, there's nothing inherently wrong about it. Say, if
GUI for some reason does not care about particular child anymore, it's free to
delete it (even though with frozen varobj, it can just freeze it).
Unfortunately gdb 6.7, when deleting varobj where some children of it
are already deleted, tries to mess with NULL pointers, and crashes.
The patch and a testcase are attached. OK?
- Volodya
Index: varobj.c
===================================================================
RCS file: /cvs/src/src/gdb/varobj.c,v
retrieving revision 1.96
diff -u -p -r1.96 varobj.c
--- varobj.c 27 Sep 2007 18:04:12 -0000 1.96
+++ varobj.c 7 Nov 2007 19:51:19 -0000
@@ -1292,6 +1292,8 @@ delete_variable_1 (struct cpstack **resu
for (i = 0; i < VEC_length (varobj_p, var->children); ++i)
{
varobj_p child = VEC_index (varobj_p, var->children, i);
+ if (!child)
+ continue;
if (!remove_from_parent_p)
child->parent = NULL;
delete_variable_1 (resultp, delcountp, child, 0, only_children_p);
Index: testsuite/gdb.mi/mi-var-child.c
===================================================================
RCS file: /cvs/src/src/gdb/testsuite/gdb.mi/mi-var-child.c,v
retrieving revision 1.6
diff -u -p -r1.6 mi-var-child.c
--- testsuite/gdb.mi/mi-var-child.c 23 Aug 2007 18:08:49 -0000 1.6
+++ testsuite/gdb.mi/mi-var-child.c 7 Nov 2007 19:51:20 -0000
@@ -306,6 +306,29 @@ do_special_tests (void)
incr_a(2);
}
+struct very_simple_struct
+{
+ int a;
+ int b;
+};
+
+int
+do_child_deletion (void)
+{
+ /*: BEGIN: child_deletion :*/
+ struct very_simple_struct s = {1, 2};
+ /*:
+ mi_create_varobj S s "create varobj for s"
+ mi_list_varobj_children S {{S.a a 0 int} {S.b b 0 int}} \
+ "list children of S"
+ mi_delete_varobj S.a "delete S.a"
+ mi_delete_varobj S.b "delete S.b"
+ mi_delete_varobj S "delete S"
+ :*/
+ return 99;
+ /*: END: child_deletion :*/
+}
+
int
main (int argc, char *argv [])
{
@@ -313,6 +336,7 @@ main (int argc, char *argv [])
do_block_tests ();
do_children_tests ();
do_special_tests ();
+ do_child_deletion ();
exit (0);
}
Index: testsuite/gdb.mi/mi-var-child.exp
===================================================================
RCS file: /cvs/src/src/gdb/testsuite/gdb.mi/mi-var-child.exp,v
retrieving revision 1.26
diff -u -p -r1.26 mi-var-child.exp
--- testsuite/gdb.mi/mi-var-child.exp 23 Aug 2007 18:14:19 -0000 1.26
+++ testsuite/gdb.mi/mi-var-child.exp 7 Nov 2007 19:51:20 -0000
@@ -1227,7 +1227,9 @@ mi_gdb_test "-var-update *" \
"\\^done,changelist=\\\[\{name=\"psnp->ptrs.0.next.next.long_ptr\",in_scope=\"true\",type_changed=\"false\"\}\\\]" \
"update all vars psnp->next->next->long_ptr (and 2.long_ptr) changed"
+mi_prepare_inline_tests $srcfile
+mi_run_inline_test child_deletion
mi_gdb_exit