Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ruby Ice/objects macOS segfault #1217

Closed
pepone opened this issue Dec 22, 2020 · 3 comments · Fixed by #1220
Closed

ruby Ice/objects macOS segfault #1217

pepone opened this issue Dec 22, 2020 · 3 comments · Fixed by #1220

Comments

@pepone
Copy link
Member

pepone commented Dec 22, 2020

[ running client/server with sliced format test - 12/22/20 14:37:04 ]
- Config: ws,serialize,compress,mx,ipv6
testing stringToProxy... ok
testing checked cast... ok
getting B1... ok
getting B2... ok
getting C... ok
getting D... ok
checking consistency... ok
getting B1, B2, C, and D all at once... ok
checking consistency... ok
testing protected members... ok
getting I, J, H... ok
getting K... ok
testing Value as parameter... ok
getting D1... ok
throw EDerived... ok
setting G... ok
setting I... ok
testing sequences... ok
testing recursive type... ok
testing compact ID... ok
testing marshaled results...ok
testing UnexpectedObjectException... ok
testing getting ObjectFactory... ok
testing getting ObjectFactory as ValueFactory... ok
testing class containing complex dictionary... eval:763: [BUG] Segmentation fault at 0x0000000000000000
-- Ruby level backtrace information ----------------------------------------
/Users/vagrant/workspace/ice-dist/3.7/dist-utils/build/ice/builds/ice-clang-default/ruby/test/TestHelper.rb:107:in `<main>'
/Users/vagrant/workspace/ice-dist/3.7/dist-utils/build/ice/builds/ice-clang-default/ruby/test/TestHelper.rb:91:in `run'
/Users/vagrant/workspace/ice-dist/3.7/dist-utils/build/ice/builds/ice-clang-default/ruby/test/Ice/objects/Client.rb:14:in `run'
/Users/vagrant/workspace/ice-dist/3.7/dist-utils/build/ice/builds/ice-clang-default/ruby/test/TestHelper.rb:69:in `init'
/Users/vagrant/workspace/ice-dist/3.7/dist-utils/build/ice/builds/ice-clang-default/ruby/test/Ice/objects/Client.rb:15:in `block in run'
/Users/vagrant/workspace/ice-dist/3.7/dist-utils/build/ice/builds/ice-clang-default/ruby/test/Ice/objects/AllTests.rb:376:in `allTests'
eval:763:in `opM'
eval:763:in `invoke'

Thread 0 Crashed:: Dispatch queue: com.apple.main-thread
0   libsystem_kernel.dylib              0x00007fff202e9462 __pthread_kill + 10
1   libsystem_pthread.dylib             0x00007fff20317610 pthread_kill + 263
2   libsystem_c.dylib                   0x00007fff2026a720 abort + 120
3   libruby.2.6.dylib                   0x00007fff6f9f800e 0x7fff6f99f000 + 364558
4   libruby.2.6.dylib                   0x00007fff6f9f80e9 rb_bug_context + 219
5   libruby.2.6.dylib                   0x00007fff6fab6b05 0x7fff6f99f000 + 1145605
6   libsystem_platform.dylib            0x00007fff2035bd7d _sigtramp + 29
7   ???                                 0x000000000016910c 0 + 1478924
8   libruby.2.6.dylib                   0x00007fff6faddcc8 rb_id_table_lookup + 37
9   libruby.2.6.dylib                   0x00007fff6fb07a47 0x7fff6f99f000 + 1477191
10  libruby.2.6.dylib                   0x00007fff6fb08378 rb_funcallv + 126
11  libruby.2.6.dylib                   0x00007fff6fb0d4c6 0x7fff6f99f000 + 1500358
12  libruby.2.6.dylib                   0x00007fff6fae293e 0x7fff6f99f000 + 1325374
13  libruby.2.6.dylib                   0x00007fff6fa141b6 rb_hash + 23
14  libruby.2.6.dylib                   0x00007fff6fa1a5d4 0x7fff6f99f000 + 505300
15  libruby.2.6.dylib                   0x00007fff6fa14b21 0x7fff6f99f000 + 482081
16  libruby.2.6.dylib                   0x00007fff6fa14abf rb_hash_stlike_update + 46
17  libruby.2.6.dylib                   0x00007fff6fa15e7f 0x7fff6f99f000 + 487039
18  libruby.2.6.dylib                   0x00007fff6fa15e22 rb_hash_aset + 146
19  libruby.2.6.dylib                   0x00007fff6f9fea11 rb_protect + 345
20  IceRuby.bundle                      0x00000001094297da IceRuby::callProtected(unsigned long (*)(unsigned long), unsigned long) + 29 (Util.cpp:576)
21  IceRuby.bundle                      0x000000010941b7f9 unsigned long IceRuby::callRuby<unsigned long (*)(unsigned long, unsigned long, unsigned long), unsigned long, unsigned long, unsigned long>(unsigned long (*)(unsigned long, unsigned long, unsigned long), unsigned long, unsigned long, unsigned long) + 41 (Util.h:288) [inlined]
22  IceRuby.bundle                      0x000000010941b7f9 IceRuby::DictionaryInfo::unmarshaled(unsigned long, unsigned long, void*) + 57 (Types.cpp:1872)
23  IceRuby.bundle                      0x000000010941f147 IceRuby::ReadObjectCallback::invoke(IceInternal::Handle<Ice::Object> const&) + 149 (Types.cpp:2748)
24  IceRuby.bundle                      0x000000010955bec8 Ice::InputStream::EncapsDecoder11::endSlice() + 212 (InputStream.cpp:2495)
25  IceRuby.bundle                      0x000000010941ec04 IceRuby::ObjectReader::_iceRead(Ice::InputStream*) + 798 (Types.cpp:2652)
26  IceRuby.bundle                      0x0000000109559f4a Ice::InputStream::EncapsDecoder::unmarshal(int, IceInternal::Handle<Ice::Object> const&) + 442 (InputStream.cpp:1878)
27  IceRuby.bundle                      0x000000010955b4da Ice::InputStream::EncapsDecoder11::readInstance(int, void (*)(void*, IceInternal::Handle<Ice::Object> const&), void*) + 604 (InputStream.cpp:2686)
28  IceRuby.bundle                      0x000000010941c697 Ice::InputStream::read(void (*)(void*, IceInternal::Handle<Ice::Object> const&), void*) + 32 (InputStream.h:1115) [inlined]
29  IceRuby.bundle                      0x000000010941c697 IceRuby::ClassInfo::unmarshal(Ice::InputStream*, IceUtil::Handle<IceRuby::UnmarshalCallback> const&, unsigned long, void*, bool) + 181 (Types.cpp:2136)
30  IceRuby.bundle                      0x00000001094135a3 IceRuby::OperationI::unmarshalResults(std::__1::vector<unsigned char, std::__1::allocator<unsigned char> > const&, IceInternal::Handle<Ice::Communicator> const&) + 325 (Operation.cpp:514)
31  IceRuby.bundle                      0x000000010941265a IceRuby::OperationI::invoke(IceInternal::ProxyHandle<IceProxy::Ice::Object> const&, unsigned long, unsigned long) + 506 (Operation.cpp:340)
32  IceRuby.bundle                      0x0000000109410e0e IceRuby_Operation_invoke + 179 (Operation.cpp:125)
33  libruby.2.6.dylib                   0x00007fff6fb1390a 0x7fff6f99f000 + 1526026
34  libruby.2.6.dylib                   0x00007fff6fb02433 0x7fff6f99f000 + 1455155
35  libruby.2.6.dylib                   0x00007fff6fb1024a rb_vm_exec + 1886
36  libruby.2.6.dylib                   0x00007fff6f9fe1a9 0x7fff6f99f000 + 389545
37  libruby.2.6.dylib                   0x00007fff6f9fe0aa ruby_run_node + 57
38  ruby                                0x00000001093b40f8 main + 98
39  libdyld.dylib                       0x00007fff20332621 start + 1
@pepone
Copy link
Member Author

pepone commented Dec 23, 2020

#1200 fixes the original problem, but if I add a call to rb_gc() in

if(_returnsClasses)

I see a similar crash in

v2, v3 = initial.opValueMap(v1)

The crash happens when accessing the string key in DictionaryInfo::unmarshaled, I don't quite understand it as they key was added to the hash, and the hash is still alive


void
IceRuby::DictionaryInfo::unmarshaled(VALUE val, VALUE target, void* closure)
{
    volatile VALUE key = reinterpret_cast<VALUE>(closure);
    cerr << "hash: " << target << endl;
    if (isHash(target))
    {
        cerr << "target is a valid hash" << endl;
    }
    cerr << "adding key: " << key << endl;
    if (isString(key))
    {
        cerr << "string key: " << endl;
    }
    callRuby(rb_hash_aset, target, key, val);
}
target is a valid hash
adding key: 93824992302120

Thread 1 "ruby" received signal SIGSEGV, Segmentation fault.
0x00007ffff7e6b1d3 in rb_id_table_lookup (tbl=0x0, id=id@entry=152, valp=valp@entry=0x7fffffffce10) at symbol.h:64
64      symbol.h: No such file or directory.
(gdb) bt
#0  0x00007ffff7e6b1d3 in rb_id_table_lookup (tbl=0x0, id=id@entry=152, valp=valp@entry=0x7fffffffce10) at symbol.h:64
#1  0x00007ffff7e9f8a7 in lookup_method_table (id=152, klass=<optimized out>) at vm_method.c:736
#2  search_method (defined_class_ptr=<optimized out>, id=<optimized out>, klass=<optimized out>) at vm_method.c:736
#3  method_entry_get_without_cache (defined_class_ptr=<optimized out>, id=<optimized out>, klass=<optimized out>) at vm_method.c:761
#4  method_entry_get (klass=klass@entry=93824992304200, id=id@entry=152, defined_class_ptr=defined_class_ptr@entry=0x7fffffffce78) at vm_method.c:825
#5  0x00007ffff7eac4ff in vm_respond_to (ec=0x55555555bae8, klass=93824992304200, obj=93824992302120, id=3121, priv=0) at vm_method.c:1990
#6  0x00007ffff7eba53f in rb_obj_respond_to (obj=93824992302120, id=3121, priv=0) at vm_method.c:2041
#7  0x00007ffff5411851 in IceRuby::RF_2<int (*)(unsigned long, unsigned long), unsigned long, unsigned long>::operator() (this=this@entry=0x0) at src/IceRuby/Util.h:243
#8  IceRuby::RF_2<int (*)(unsigned long, unsigned long), unsigned long, unsigned long>::call (f=f@entry=140737488343504) at src/IceRuby/Util.h:245
#9  0x00007ffff7d2f624 in rb_protect (proc=0x7ffff5411840 <IceRuby::RF_2<int (*)(unsigned long, unsigned long), unsigned long, unsigned long>::call(unsigned long)>, data=140737488343504, pstate=0x7fffffffd18c) at eval.c:1034
#10 0x00007ffff5426c5c in IceRuby::callProtected (func=0x7ffff5411840 <IceRuby::RF_2<int (*)(unsigned long, unsigned long), unsigned long, unsigned long>::call(unsigned long)>, arg=140737488343504) at src/IceRuby/Util.cpp:576
#11 0x00007ffff5429954 in IceRuby::callRuby<int (*)(unsigned long, unsigned long), unsigned long, unsigned long> (fun=0x7ffff7eba650 <rb_respond_to>, t1=93824992302120, t2=3121) at src/IceRuby/Util.h:260
#12 0x00007ffff54259be in IceRuby::isString (val=93824992302120) at src/IceRuby/Util.cpp:261
#13 0x00007ffff5403b9a in IceRuby::DictionaryInfo::unmarshaled (this=<optimized out>, val=93824992278960, target=93824992302280, closure=0x555555565428) at src/IceRuby/Types.cpp:1885
#14 0x00007ffff540f4fc in IceRuby::ReadObjectCallback::invoke (this=0x555555648920, p=...) at ../cpp/include/IceUtil/Handle.h:30
#15 0x00007ffff50e8e3a in Ice::InputStream::EncapsDecoder::unmarshal (this=0x555555855020, index=1, v=...) at src/Ice/InputStream.cpp:1893
#16 0x00007ffff50ea127 in Ice::InputStream::EncapsDecoder10::readInstance (this=0x555555855020) at src/Ice/InputStream.cpp:2245
#17 0x00007ffff50ea390 in Ice::InputStream::EncapsDecoder10::readPendingValues (this=0x555555855020) at src/Ice/InputStream.cpp:2146
#18 0x00007ffff54216a8 in IceRuby::OperationI::unmarshalResults (this=0x555555a49630, bytes=..., communicator=...) at src/IceRuby/Operation.cpp:548
#19 0x00007ffff542372c in IceRuby::OperationI::invoke (this=this@entry=0x555555a49630, proxy=..., args=args@entry=93824992302960, hctx=hctx@entry=8) at src/IceRuby/Operation.cpp:340
#20 0x00007ffff5421aca in IceRuby_Operation_invoke (self=<optimized out>, proxy=93824996424480, opArgs=93824992302960, ctx=8) at ../cpp/include/IceUtil/Handle.h:30
#21 0x00007ffff7ea7470 in vm_call_cfunc_with_frame (ci=0x555555b07cb0, cc=<optimized out>, calling=<optimized out>, reg_cfp=0x7ffff759de50, ec=0x55555555bae8) at vm_insnhelper.c:1908
#22 vm_call_cfunc (ec=0x55555555bae8, reg_cfp=0x7ffff759de50, calling=<optimized out>, ci=0x555555b07cb0, cc=<optimized out>) at vm_insnhelper.c:1924
#23 0x00007ffff7eb39dc in vm_call_method_each_type (ec=0x55555555bae8, cfp=0x7ffff759de50, calling=0x7fffffffdaf0, ci=0x555555b07cb0, cc=<optimized out>) at vm_insnhelper.c:2245
#24 0x00007ffff7eb40d5 in vm_call_method_each_type (cc=<optimized out>, ci=<optimized out>, calling=<optimized out>, cfp=<optimized out>, ec=<optimized out>) at vm_insnhelper.c:2372
#25 vm_call_method (cc=<optimized out>, ci=<optimized out>, calling=<optimized out>, cfp=<optimized out>, ec=<optimized out>) at vm_insnhelper.c:2400
#26 vm_call_method (ec=0x55555555bae8, cfp=0x7ffff759de50, calling=<optimized out>, ci=<optimized out>, cc=<optimized out>) at vm_insnhelper.c:2367
#27 0x00007ffff7eac9f0 in vm_exec_core (ec=0x55555555bae8, initial=<optimized out>) at insns.def:765
#28 0x00007ffff7eb2eed in rb_vm_exec (ec=0x55555555bae8, mjit_enable_p=1) at vm.c:1894
#29 0x00007ffff7d2c4f6 in ruby_exec_internal (n=0x555555958a80) at eval.c:262
#30 0x00007ffff7d2e58d in ruby_exec_node (n=<optimized out>, n@entry=0x555555958a80) at eval.c:326
#31 0x00007ffff7d3144e in ruby_run_node (n=0x555555958a80) at eval.c:318
#32 0x000055555555510b in main (argc=<optimized out>, argv=<optimized out>) at ./main.c:42

@pepone
Copy link
Member Author

pepone commented Dec 23, 2020

so far this second issue seems to be specific of "string" keys, the other test case that uses a struct as key works fine, also tried with an int key without problems.

@pepone
Copy link
Member Author

pepone commented Dec 24, 2020

I added some code to debug the contents of the hash, and for strings keys, the VALUE we keep in the closure doesn't match the one that is still in the hash

The mismatch comes from https://github.com/ruby/ruby/blob/05a756b3323d23b8f6ec899eaa83f7172ada0999/hash.c#L2870

hash implementation is creating a new frozen string, and that one is kept alive, but the one we have in the closure is not.

+            if (RB_TYPE_P(keyCB->key, T_STRING))
+            {
+                keyCB->key = rb_str_new_frozen(keyCB->key);
+            }
             callRuby(rb_hash_aset, hash, keyCB->key, Qnil);

Creating the frozen string before adding the key to hash solves the problem.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging a pull request may close this issue.

1 participant