aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorVladimir Prus <vladimir@codesourcery.com>2007-11-07 20:06:29 +0000
committerVladimir Prus <vladimir@codesourcery.com>2007-11-07 20:06:29 +0000
commit214270abf389bb2aa4584423353a7da2a1e6b463 (patch)
tree8e980f439b9001a60df7f261c792c5268fdfca9b
parent91ea499d4ae67d29f4ef3aefc3335224a2837254 (diff)
downloadgdb-214270abf389bb2aa4584423353a7da2a1e6b463.zip
gdb-214270abf389bb2aa4584423353a7da2a1e6b463.tar.gz
gdb-214270abf389bb2aa4584423353a7da2a1e6b463.tar.bz2
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.
-rw-r--r--gdb/ChangeLog8
-rw-r--r--gdb/testsuite/ChangeLog5
-rw-r--r--gdb/testsuite/gdb.mi/mi-var-child.c24
-rw-r--r--gdb/testsuite/gdb.mi/mi-var-child.exp2
-rw-r--r--gdb/varobj.c2
5 files changed, 41 insertions, 0 deletions
diff --git a/gdb/ChangeLog b/gdb/ChangeLog
index af8f602..ab6711e 100644
--- a/gdb/ChangeLog
+++ b/gdb/ChangeLog
@@ -1,3 +1,11 @@
+2007-11-07 Vladimir Prus <vladimir@codesourcery.com>
+
+ 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-11-07 Markus Deuling <deuling@de.ibm.com>
* gdbarch.sh (legacy_virtual_frame_pointer): Add gdbarch parameter.
diff --git a/gdb/testsuite/ChangeLog b/gdb/testsuite/ChangeLog
index 290ec1b..dbc6011 100644
--- a/gdb/testsuite/ChangeLog
+++ b/gdb/testsuite/ChangeLog
@@ -1,3 +1,8 @@
+2007-11-07 Vladimir Prus <vladimir@codesourcery.com>
+
+ * gdb.mi/mi-var-child.c (do_child_deletion): New.
+ * gdb.mi/mi-var-child.exp: Run child_deletion tests.
+
2007-11-05 Luis Machado <luisgpm@br.ibm.com>
* gdb.base/printcmds.exp: New function
diff --git a/gdb/testsuite/gdb.mi/mi-var-child.c b/gdb/testsuite/gdb.mi/mi-var-child.c
index 393efd2..406f0e2 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 aad9727..c26cada 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 d6125c6..fb1fd1d 100644
--- a/gdb/varobj.c
+++ b/gdb/varobj.c
@@ -1292,6 +1292,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);