Fix segv when referencing a value added to history after a Guile garbage collect.
authorDoug Evans <xdje42@gmail.com>
Thu, 13 Mar 2014 16:24:19 +0000 (09:24 -0700)
committerDoug Evans <xdje42@gmail.com>
Thu, 13 Mar 2014 16:24:19 +0000 (09:24 -0700)
* value.c (record_latest_value): Call release_value_or_incref
instead of release_value.

testsuite/
* gdb.guile/scm-value.exp (test_value_in_inferior): Verify value added
to history survives a gc.

gdb/ChangeLog
gdb/testsuite/ChangeLog
gdb/testsuite/gdb.guile/scm-value.exp
gdb/value.c

index b3e129631aa85c27d53ecad401a704116bc3e09b..f997cd649e0dce6bd4cc350010780860a28ad3a5 100644 (file)
@@ -1,3 +1,8 @@
+2014-03-13  Doug Evans  <xdje42@gmail.com>
+
+       * value.c (record_latest_value): Call release_value_or_incref
+       instead of release_value.
+
 2014-03-13  Pedro Alves  <palves@redhat.com>
 
        * procfs.c (procfs_target): Don't override to_shortname,
index 0f16ab0942aea12d8f35a14f98876caece48caa7..78be1f75333503f7413337ecec17da100cf49efe 100644 (file)
@@ -1,3 +1,9 @@
+2014-03-13  Ludovic Courtès  <ludo@gnu.org>
+           Doug Evans  <xdje42@gmail.com>
+
+       * gdb.guile/scm-value.exp (test_value_in_inferior): Verify value added
+       to history survives a gc.
+
 2014-03-13  Pedro Alves  <palves@redhat.com>
 
        * gdb.base/default.exp: Don't test "target procfs".
index 89f0ff1d610e3e3cf04e08abf8d7759af7c8c31e..a85d5bda9e48e358da37edfe7432b12b1255d4a4 100644 (file)
@@ -67,6 +67,10 @@ proc test_value_in_inferior {} {
     gdb_test "gu (history-ref i)" "#<gdb:value 42>"
     gdb_test "p \$" "= 42"
 
+    # Verify the recorded history value survives a gc.
+    gdb_test_no_output "guile (gc)"
+    gdb_test "p \$\$" "= 42"
+
     # Test dereferencing the argv pointer.
 
     # Just get inferior variable argv the value history, available to guile.
index 4e8d1fe815e5619a29222c791c60941f36065862..27043ee8cf6912459f2e134eb63d80a04b26fa45 100644 (file)
@@ -1659,7 +1659,11 @@ record_latest_value (struct value *val)
      from.  This is a bit dubious, because then *&$1 does not just return $1
      but the current contents of that location.  c'est la vie...  */
   val->modifiable = 0;
-  release_value (val);
+
+  /* The value may have already been released, in which case we're adding a
+     new reference for its entry in the history.  That is why we call
+     release_value_or_incref here instead of release_value.  */
+  release_value_or_incref (val);
 
   /* Here we treat value_history_count as origin-zero
      and applying to the value being stored now.  */