This is the mail archive of the gdb-patches@sourceware.org mailing list for the GDB project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

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

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]