Bug #9252

"RuntimeError: can't add a new key into hash during iteration" error on test-all of objspace

Added by Koichi Sasada over 1 year ago. Updated over 1 year ago.

[ruby-core:59125]
Status:Closed
Priority:Normal
Assignee:Koichi Sasada
ruby -v:ruby -v: ruby 2.1.0dev (2013-12-15 trunk 44222) [x64-mswin64_110] Backport:1.9.3: UNKNOWN, 2.0.0: UNKNOWN

Description

Now, some platforms have the following errors on "test-all TESTS=objspace".

1) Error:
TestObjSpace#test_reachable_objects_from_root:
RuntimeError: can't add a new key into hash during iteration
C:/ko1/src/ruby/trunk/test/objspace/test_objspace.rb:109:in hash'
C:/ko1/src/ruby/trunk/test/objspace/test_objspace.rb:109:in
hash'
C:/ko1/src/ruby/trunk/test/objspace/test_objspace.rb:109:in reachable_objects_from_root'
C:/ko1/src/ruby/trunk/test/objspace/test_objspace.rb:109:in
test_reachable_objects_from_root'

ruby -v: ruby 2.1.0dev (2013-12-15 trunk 44222) [x64-mswin64_110]

This problem is because of an issue of "ObjectSpace.reachable_objects_from_root".

This method traverse all objects and insert it into a hash object to use as Set.
To set hash object, a hash value is solved by the hash' method and it uses
rb_exec_recursive' for some classes. `rb_exec_recursive' generates a hash object
internally and this value is modified accidentally. This is current my assumption.

For example, we track new objects after `ObjectSpace.reachable_objects_from_root'
and avoid collection of such newer objects can solve this issue, but it will introduce
performance impact (but this method is not performance critical, so it can be accepted).

Associated revisions

Revision 44241
Added by Koichi Sasada over 1 year ago

  • ext/objspace/objspace.c (reachable_object_from_root_i): use compare_by_identity hash to avoid hash modify problem during iteration. [Bug #9252]
  • ext/objspace/objspace.c (reachable_objects_from_root): ditto.

Revision 44241
Added by Koichi Sasada over 1 year ago

  • ext/objspace/objspace.c (reachable_object_from_root_i): use compare_by_identity hash to avoid hash modify problem during iteration. [Bug #9252]
  • ext/objspace/objspace.c (reachable_objects_from_root): ditto.

History

#1 Updated by Koichi Sasada over 1 year ago

  • % Done changed from 0 to 100
  • Status changed from Open to Closed

This issue was solved with changeset r44241.
Koichi, thank you for reporting this issue.
Your contribution to Ruby is greatly appreciated.
May Ruby be with you.


  • ext/objspace/objspace.c (reachable_object_from_root_i): use compare_by_identity hash to avoid hash modify problem during iteration. [Bug #9252]
  • ext/objspace/objspace.c (reachable_objects_from_root): ditto.

#2 Updated by Heesob Park over 1 year ago

This issue is not solved with changeset r44241.
Besides, r44241 caused segmentation fault.
http://ruby-mswin.cloudapp.net/vc10-x64/ruby-trunk/log/20131216T101556Z.log.html.gz

I found that this issue is related with the over optimization on Windows.
Here is a workaround patch:

diff --git a/thread.c b/thread.c.new
index 39bb510..6985ee5 100644
--- a/thread.c
+++ b/thread.c.new
@@ -4754,6 +4754,12 @@ ident_hash_new(void)
* the current callee.
*/

+#if defined(MSC_VER) && defined(_M_AMD64) && _MSC_VER >= 1400
+# pragma optimize("", off)
+#elif defined(
MINGW64_VERSION_MAJOR)
+# pragma GCC push_options
+# pragma GCC optimize ("O0")
+#endif
static VALUE
recursive_list_access(void)
{
@@ -4774,6 +4780,11 @@ recursive_list_access(void)
}
return list;
}
+#if defined(
MSC_VER) && defined(M_AMD64) && _MSC_VER >= 1400
+# pragma optimize("", on)
+#elif defined(
MINGW64_VERSION_MAJOR)
+# pragma GCC pop
options
+#endif

/*
* Returns Qtrue iff obj_id (or the pair ) is already

Also available in: Atom PDF