From 350e1a768cca6deab7aeca8adcff9561faeb1f35 Mon Sep 17 00:00:00 2001 From: Doug Evans Date: Thu, 13 Mar 2014 09:24:19 -0700 Subject: [PATCH] Fix segv when referencing a value added to history after a Guile garbage collect. * 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 | 5 +++++ gdb/testsuite/ChangeLog | 6 ++++++ gdb/testsuite/gdb.guile/scm-value.exp | 4 ++++ gdb/value.c | 6 +++++- 4 files changed, 20 insertions(+), 1 deletion(-) diff --git a/gdb/ChangeLog b/gdb/ChangeLog index b3e129631aa..f997cd649e0 100644 --- a/gdb/ChangeLog +++ b/gdb/ChangeLog @@ -1,3 +1,8 @@ +2014-03-13 Doug Evans + + * value.c (record_latest_value): Call release_value_or_incref + instead of release_value. + 2014-03-13 Pedro Alves * procfs.c (procfs_target): Don't override to_shortname, diff --git a/gdb/testsuite/ChangeLog b/gdb/testsuite/ChangeLog index 0f16ab0942a..78be1f75333 100644 --- a/gdb/testsuite/ChangeLog +++ b/gdb/testsuite/ChangeLog @@ -1,3 +1,9 @@ +2014-03-13 Ludovic Courtès + Doug Evans + + * gdb.guile/scm-value.exp (test_value_in_inferior): Verify value added + to history survives a gc. + 2014-03-13 Pedro Alves * gdb.base/default.exp: Don't test "target procfs". diff --git a/gdb/testsuite/gdb.guile/scm-value.exp b/gdb/testsuite/gdb.guile/scm-value.exp index 89f0ff1d610..a85d5bda9e4 100644 --- a/gdb/testsuite/gdb.guile/scm-value.exp +++ b/gdb/testsuite/gdb.guile/scm-value.exp @@ -67,6 +67,10 @@ proc test_value_in_inferior {} { gdb_test "gu (history-ref i)" "#" 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. diff --git a/gdb/value.c b/gdb/value.c index 4e8d1fe815e..27043ee8cf6 100644 --- a/gdb/value.c +++ b/gdb/value.c @@ -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. */ -- 2.30.2