zeromq / czmq

High-level C binding for ØMQ
czmq.zeromq.org
Mozilla Public License 2.0
1.16k stars 523 forks source link

zsock_events() segfaults if called too often #2261

Closed paddor closed 4 months ago

paddor commented 1 year ago

I'm using ZMQ v4.3.4 and CZMQ v4.2.1 with the CZTop binding (FFI classes are generated in this project). While testing a ping functionality in my app, I ran the ping in a tight loop and noticed that CZMQ sometimes segfaults in zsock_events() after a few seconds (a few thousand pings).

Relevant stacktraces from Ruby:

-- Control frame information -----------------------------------------------
c:0014 p:---- s:0066 e:000065 CFUNC  :zsock_events
c:0013 p:0020 s:0061 e:000060 METHOD /home/roadster/.gem/ruby/3.2.0/gems/czmq-ffi-gen-1.0.0/lib/czmq-ffi-gen/czmq/ffi/zsock.rb:5597
...

-- C level backtrace information -------------------------------------------
/home/user/.rubies/ruby-3.2.0/lib/libruby.so.3.2(rb_print_backtrace+0xd) [0x7fcb093959df] /home/user/src/ruby-3.2.0/vm_dump.c:785
/home/user/.rubies/ruby-3.2.0/lib/libruby.so.3.2(rb_vm_bugreport) /home/user/src/ruby-3.2.0/vm_dump.c:1080
/home/user/.rubies/ruby-3.2.0/lib/libruby.so.3.2(rb_bug_for_fatal_signal+0xf4) [0x7fcb0918b934] /home/user/src/ruby-3.2.0/error.c:813
/home/user/.rubies/ruby-3.2.0/lib/libruby.so.3.2(sigsegv+0x4d) [0x7fcb092e4c4d] /home/user/src/ruby-3.2.0/signal.c:964
/lib/x86_64-linux-gnu/libc.so.6(0x7fcb08c99520) [0x7fcb08c99520]
/lib/x86_64-linux-gnu/libzmq.so.5(0x7fcb02d27112) [0x7fcb02d27112]
/lib/x86_64-linux-gnu/libzmq.so.5(0x7fcb02d3c5bf) [0x7fcb02d3c5bf]
/lib/x86_64-linux-gnu/libczmq.so(zsock_events+0x7e) [0x7fcb02dc94fe]
/lib/x86_64-linux-gnu/libffi.so.8(0x7fcb035f7e2e) [0x7fcb035f7e2e]
/lib/x86_64-linux-gnu/libffi.so.8(0x7fcb035f4493) [0x7fcb035f4493]
/home/user/.gem/ruby/3.2.0/gems/ffi-1.15.5/lib/ffi_c.so(call_blocking_function+0x46) [0x7fcb03491474] /home/user/.gem/ruby/3.2.0/gems/ffi-1.15.5/ext/ffi_c/Call.c:336
/home/user/.rubies/ruby-3.2.0/lib/libruby.so.3.2(rb_nogvl+0xd5) [0x7fcb09333295] /home/user/src/ruby-3.2.0/thread.c:1548
/home/user/.gem/ruby/3.2.0/gems/ffi-1.15.5/lib/ffi_c.so(rbffi_do_blocking_call+0x32) [0x7fcb034914ad] /home/user/.gem/ruby/3.2.0/gems/ffi-1.15.5/ext/ffi_c/Call.c:344
/home/user/.rubies/ruby-3.2.0/lib/libruby.so.3.2(rb_vrescue2+0x11e) [0x7fcb09194d9e] /home/user/src/ruby-3.2.0/eval.c:917
/home/user/.rubies/ruby-3.2.0/lib/libruby.so.3.2(rb_rescue2+0x8e) [0x7fcb0919502e] /home/user/src/ruby-3.2.0/eval.c:898
/home/user/.gem/ruby/3.2.0/gems/ffi-1.15.5/lib/ffi_c.so(rbffi_CallFunction+0x3c4) [0x7fcb034918a3] /home/user/.gem/ruby/3.2.0/gems/ffi-1.15.5/ext/ffi_c/Call.c:387
/home/user/.gem/ruby/3.2.0/gems/ffi-1.15.5/lib/ffi_c.so(custom_trampoline+0x62) [0x7fcb03497fec] /home/user/.gem/ruby/3.2.0/gems/ffi-1.15.5/ext/ffi_c/MethodHandle.c:220
/home/user/.rubies/ruby-3.2.0/lib/libruby.so.3.2(vm_call_cfunc_with_frame+0x127) [0x7fcb0936a227] /home/user/src/ruby-3.2.0/vm_insnhelper.c:3252
/home/user/.rubies/ruby-3.2.0/lib/libruby.so.3.2(vm_sendish+0x97) [0x7fcb0937a724] /home/user/src/ruby-3.2.0/vm_insnhelper.c:5064
/home/user/.rubies/ruby-3.2.0/lib/libruby.so.3.2(vm_exec_core) /home/user/src/ruby-3.2.0/insns.def:820
/home/user/.rubies/ruby-3.2.0/lib/libruby.so.3.2(rb_vm_exec+0xd3) [0x7fcb09380003] /home/user/src/ruby-3.2.0/vm.c:2374
/home/user/.rubies/ruby-3.2.0/lib/libruby.so.3.2(rb_yield_1+0x2d8) [0x7fcb09382b68] /home/user/src/ruby-3.2.0/vm.c:1398
/home/user/.rubies/ruby-3.2.0/lib/libruby.so.3.2(int_dotimes+0x94) [0x7fcb0922e264] /home/user/src/ruby-3.2.0/numeric.c:5697
/home/user/.rubies/ruby-3.2.0/lib/libruby.so.3.2(vm_call_cfunc_with_frame+0x127) [0x7fcb0936a227] /home/user/src/ruby-3.2.0/vm_insnhelper.c:3252
/home/user/.rubies/ruby-3.2.0/lib/libruby.so.3.2(vm_sendish+0xd2) [0x7fcb0936ff42] /home/user/src/ruby-3.2.0/vm_insnhelper.c:5064
/home/user/.rubies/ruby-3.2.0/lib/libruby.so.3.2(vm_exec_core+0x1e2) [0x7fcb0937a802] /home/user/src/ruby-3.2.0/insns.def:801
/home/user/.rubies/ruby-3.2.0/lib/libruby.so.3.2(rb_vm_exec+0xd3) [0x7fcb09380003] /home/user/src/ruby-3.2.0/vm.c:2374
/home/user/.rubies/ruby-3.2.0/lib/libruby.so.3.2(vm_call0_cc+0x76) [0x7fcb0938a322] /home/user/src/ruby-3.2.0/vm_eval.c:87
/home/user/.rubies/ruby-3.2.0/lib/libruby.so.3.2(rb_funcallv) /home/user/src/ruby-3.2.0/vm_eval.c:1051
/home/user/.rubies/ruby-3.2.0/lib/libruby.so.3.2(rb_funcall+0x41) [0x7fcb0938ea31] /home/user/src/ruby-3.2.0/vm_eval.c:1123
...
sphaero commented 4 months ago

Do you have a code example in C that reproduces this issue?

paddor commented 4 months ago

Sorry, I don't.

sphaero commented 4 months ago

Ok, if you don't mind then I'm closing this. We can't substract relevant info from this info. I'm also not sure why zsock_events is called that often. That's not the way to do it IMHO.

paddor commented 4 months ago

zsock_events is called often because it's in an event loop that checks readability using the FD, which is unreliable. After being notified about readability/writability from the FD, you still have to check the socket's events to be sure.

It's okay, it's not an urgent problem / not affecting me these days. If it returns, I'll try to come up with a code example in C.