From: Vladimir Prus Date: Thu, 8 Nov 2007 08:31:53 +0000 (+0000) Subject: Fix crash when a variable object being deleted X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=6bd1347b308624310e3468a8a63081ea1e42c7bf;p=thirdparty%2Fbinutils-gdb.git Fix crash when a variable object being deleted has any of its children deleted previously. * varobj.c (delete_variable_1): Don't recurse into deleted children. --- diff --git a/gdb/ChangeLog b/gdb/ChangeLog index eac5d71aa81..8cd2d6dac49 100644 --- a/gdb/ChangeLog +++ b/gdb/ChangeLog @@ -1,3 +1,11 @@ +2007-11-08 Vladimir Prus + + Fix crash when a variable object being deleted + has any of its children deleted previously. + + * varobj.c (delete_variable_1): Don't recurse + into deleted children. + 2007-10-29 Joel Brobecker * version.in: Set version to 6.7.1.20071029-cvs. diff --git a/gdb/testsuite/ChangeLog b/gdb/testsuite/ChangeLog index cbaefb2e32f..c2ce65d9220 100644 --- a/gdb/testsuite/ChangeLog +++ b/gdb/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2007-11-08 Vladimir Prus + + * gdb.mi/mi-var-child.c (do_child_deletion): New. + * gdb.mi/mi-var-child.exp: Run child_deletion tests. + 2007-10-09 Daniel Jacobowitz * gdb.server/server-run.exp: Test for dynamic linker symbols. diff --git a/gdb/testsuite/gdb.mi/mi-var-child.c b/gdb/testsuite/gdb.mi/mi-var-child.c index 393efd24d57..406f0e2e2c7 100644 --- a/gdb/testsuite/gdb.mi/mi-var-child.c +++ b/gdb/testsuite/gdb.mi/mi-var-child.c @@ -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); } diff --git a/gdb/testsuite/gdb.mi/mi-var-child.exp b/gdb/testsuite/gdb.mi/mi-var-child.exp index aad9727c393..c26cada8aa6 100644 --- a/gdb/testsuite/gdb.mi/mi-var-child.exp +++ b/gdb/testsuite/gdb.mi/mi-var-child.exp @@ -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 diff --git a/gdb/varobj.c b/gdb/varobj.c index 5ea81fa3ef6..84d308548af 100644 --- a/gdb/varobj.c +++ b/gdb/varobj.c @@ -1295,6 +1295,8 @@ delete_variable_1 (struct cpstack **resultp, int *delcountp, 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);