Thread safety issue with PubSub and hiredis
rianmcguire opened this issue · 2 comments
I've been digging into some Ruby crashes we've been seeing with ActionCable in our test suite, and I think I've uncovered a thread safety issue when HiredisConnection
is used with #pubsub
.
Minimal reproduction:
require 'redis-client'
require 'hiredis-client'
redis_config = RedisClient.config
redis = redis_config.new_client
pubsub = redis.pubsub
reader = Thread.new do
while event = pubsub.next_event
end
end
loop do
pubsub.call_v(["subscribe", "channel"])
pubsub.call_v(["unsubscribe", "channel"])
end
I understand using multiple threads here is supposed to be safe, as PubSub #call_v
only writes to the socket, and #next_event
only reads from the socket (see also redis/redis-rb#1131).
Without hiredis-client, this runs indefinitely without errors.
With hiredis-client, it either fails with a weird connection error:
/var/lib/gems/3.1.0/gems/hiredis-client-0.22.2/lib/redis_client/hiredis_connection.rb:113:in `rescue in write': Connection reset by peer (redis://localhost:6379) (RedisClient::ConnectionError)
from /var/lib/gems/3.1.0/gems/hiredis-client-0.22.2/lib/redis_client/hiredis_connection.rb:109:in `write'
from /var/lib/gems/3.1.0/gems/redis-client-0.22.2/lib/redis_client.rb:498:in `call_v'
from repro.rb:17:in `block in <main>'
from repro.rb:15:in `loop'
from repro.rb:15:in `<main>'
/var/lib/gems/3.1.0/gems/hiredis-client-0.22.2/lib/redis_client/hiredis_connection.rb:111:in `flush': Connection reset by peer (Errno::ECONNRESET)
from /var/lib/gems/3.1.0/gems/hiredis-client-0.22.2/lib/redis_client/hiredis_connection.rb:111:in `write'
from /var/lib/gems/3.1.0/gems/redis-client-0.22.2/lib/redis_client.rb:498:in `call_v'
from repro.rb:17:in `block in <main>'
from repro.rb:15:in `loop'
from repro.rb:15:in `<main>'
Or crashes Ruby with a seg fault:
Ruby crash dump
/var/lib/gems/3.1.0/gems/hiredis-client-0.22.2/lib/redis_client/hiredis_connection.rb:111: [BUG] Segmentation fault at 0x0000000000000008
ruby 3.1.2p20 (2022-04-12 revision 4491bb740a) [aarch64-linux-gnu]
-- Control frame information -----------------------------------------------
c:0007 p:---- s:0032 e:000031 CFUNC :flush
c:0006 p:0009 s:0028 e:000027 METHOD /var/lib/gems/3.1.0/gems/hiredis-client-0.22.2/lib/redis_client/hiredis_connection.rb:111
c:0005 p:0012 s:0022 e:000021 METHOD /var/lib/gems/3.1.0/gems/redis-client-0.22.2/lib/redis_client.rb:498
c:0004 p:0010 s:0017 e:000016 BLOCK repro.rb:16 [FINISH]
c:0003 p:---- s:0014 e:000013 CFUNC :loop
c:0002 p:0055 s:0010 E:001610 EVAL repro.rb:15 [FINISH]
c:0001 p:0000 s:0003 E:000030 (none) [FINISH]
-- Ruby level backtrace information ----------------------------------------
repro.rb:15:in `<main>'
repro.rb:15:in `loop'
repro.rb:16:in `block in <main>'
/var/lib/gems/3.1.0/gems/redis-client-0.22.2/lib/redis_client.rb:498:in `call_v'
/var/lib/gems/3.1.0/gems/hiredis-client-0.22.2/lib/redis_client/hiredis_connection.rb:111:in `write'
/var/lib/gems/3.1.0/gems/hiredis-client-0.22.2/lib/redis_client/hiredis_connection.rb:111:in `flush'
-- Machine register context ------------------------------------------------
x0: 0x0000000000000000 x1: 0x0000fffff9875bcc x2: 0x0000000000000000
x3: 0x0000000000000001 x4: 0x0000000000000000 x5: 0x0000aaaaffac0170
x6: 0x0000000000000000 x7: 0x000000000040b79e x18: 0x0000ffffb2b55670
x19: 0x0000fffff9875bd0 x20: 0x0000000000000000 x21: 0x0000000000000001
x22: 0x0000ffffaec13054 x23: 0x0000fffff9875bd0 x24: 0x0000aaaaffabfd80
x25: 0x0000aaaaffabc0f0 x26: 0x0000aaaaffabd310 x27: 0x0000000000000000
x28: 0x0000000000000000 x29: 0x0000fffff9875ab0 sp: 0x0000fffff9875ab0
fau: 0x0000000000000008
-- C level backtrace information -------------------------------------------
/lib/aarch64-linux-gnu/libruby-3.1.so.3.1(0xffffb3011ecc) [0xffffb3011ecc]
/lib/aarch64-linux-gnu/libruby-3.1.so.3.1(0xffffb2e6c854) [0xffffb2e6c854]
/lib/aarch64-linux-gnu/libruby-3.1.so.3.1(0xffffb2f88eb8) [0xffffb2f88eb8]
linux-vdso.so.1(__kernel_rt_sigreturn+0x0) [0xffffb319e7bc]
[0xffffaec1924c]
[0xffffaec1306c]
/lib/aarch64-linux-gnu/libruby-3.1.so.3.1(rb_nogvl+0xc0) [0xffffb2fc2a74]
[0xffffaec152cc]
[0xffffb2ff67a4]
[0xffffb2ff8bc0]
[0xffffb2ffb74c]
/lib/aarch64-linux-gnu/libruby-3.1.so.3.1(rb_vm_exec+0xd4) [0xffffb2ffffd4]
[0xffffb300314c]
/lib/aarch64-linux-gnu/libruby-3.1.so.3.1(rb_vrescue2+0xec) [0xffffb2e73a3c]
/lib/aarch64-linux-gnu/libruby-3.1.so.3.1(rb_rescue2+0x78) [0xffffb2e73c6c]
[0xffffb2ff67a4]
[0xffffb2ff8bc0]
[0xffffb2ffb7ac]
/lib/aarch64-linux-gnu/libruby-3.1.so.3.1(rb_vm_exec+0xd4) [0xffffb2ffffd4]
[0xffffb2e72694]
/lib/aarch64-linux-gnu/libruby-3.1.so.3.1(ruby_run_node+0x68) [0xffffb2e75fc8]
[0xaaaae4410b1c]
[0xffffb2a67780]
[0xffffb2a67858]
/usr/bin/ruby3.1(_start+0x30) [0xaaaae4410bb0]
-- Other runtime information -----------------------------------------------
* Loaded script: repro.rb
* Loaded features:
0 enumerator.so
1 thread.rb
2 fiber.so
3 rational.so
4 complex.so
5 ruby2_keywords.rb
6 /usr/lib/aarch64-linux-gnu/ruby/3.1.0/enc/encdb.so
7 /usr/lib/aarch64-linux-gnu/ruby/3.1.0/enc/trans/transdb.so
8 /usr/lib/aarch64-linux-gnu/ruby/3.1.0/rbconfig.rb
9 /usr/lib/ruby/vendor_ruby/rubygems/compatibility.rb
10 /usr/lib/ruby/vendor_ruby/rubygems/defaults.rb
11 /usr/lib/ruby/vendor_ruby/rubygems/deprecate.rb
12 /usr/lib/ruby/vendor_ruby/rubygems/errors.rb
13 /usr/lib/ruby/vendor_ruby/rubygems/unknown_command_spell_checker.rb
14 /usr/lib/ruby/vendor_ruby/rubygems/exceptions.rb
15 /usr/lib/ruby/vendor_ruby/rubygems/basic_specification.rb
16 /usr/lib/ruby/vendor_ruby/rubygems/stub_specification.rb
17 /usr/lib/ruby/vendor_ruby/rubygems/platform.rb
18 /usr/lib/ruby/vendor_ruby/rubygems/version.rb
19 /usr/lib/ruby/vendor_ruby/rubygems/requirement.rb
20 /usr/lib/ruby/vendor_ruby/rubygems/util/list.rb
21 /usr/lib/ruby/vendor_ruby/rubygems/specification.rb
22 /usr/lib/ruby/vendor_ruby/rubygems/defaults/operating_system.rb
23 /usr/lib/ruby/vendor_ruby/rubygems/util.rb
24 /usr/lib/ruby/vendor_ruby/rubygems/dependency.rb
25 /usr/lib/ruby/vendor_ruby/rubygems/core_ext/kernel_gem.rb
26 /usr/lib/aarch64-linux-gnu/ruby/3.1.0/monitor.so
27 /usr/lib/ruby/3.1.0/monitor.rb
28 /usr/lib/ruby/vendor_ruby/rubygems/core_ext/kernel_require.rb
29 /usr/lib/ruby/vendor_ruby/rubygems/core_ext/kernel_warn.rb
30 /usr/lib/ruby/vendor_ruby/rubygems.rb
31 /usr/lib/ruby/vendor_ruby/rubygems/path_support.rb
32 /usr/lib/ruby/3.1.0/error_highlight/version.rb
33 /usr/lib/ruby/3.1.0/error_highlight/base.rb
34 /usr/lib/ruby/3.1.0/error_highlight/formatter.rb
35 /usr/lib/ruby/3.1.0/error_highlight/core_ext.rb
36 /usr/lib/ruby/3.1.0/error_highlight.rb
37 /usr/lib/ruby/3.1.0/did_you_mean/version.rb
38 /usr/lib/ruby/3.1.0/did_you_mean/core_ext/name_error.rb
39 /usr/lib/ruby/3.1.0/did_you_mean/levenshtein.rb
40 /usr/lib/ruby/3.1.0/did_you_mean/jaro_winkler.rb
41 /usr/lib/ruby/3.1.0/did_you_mean/spell_checker.rb
42 /usr/lib/ruby/3.1.0/did_you_mean/spell_checkers/name_error_checkers/class_name_checker.rb
43 /usr/lib/ruby/3.1.0/did_you_mean/spell_checkers/name_error_checkers/variable_name_checker.rb
44 /usr/lib/ruby/3.1.0/did_you_mean/spell_checkers/name_error_checkers.rb
45 /usr/lib/ruby/3.1.0/did_you_mean/spell_checkers/method_name_checker.rb
46 /usr/lib/ruby/3.1.0/did_you_mean/spell_checkers/key_error_checker.rb
47 /usr/lib/ruby/3.1.0/did_you_mean/spell_checkers/null_checker.rb
48 /usr/lib/ruby/3.1.0/did_you_mean/tree_spell_checker.rb
49 /usr/lib/ruby/3.1.0/did_you_mean/spell_checkers/require_path_checker.rb
50 /usr/lib/ruby/3.1.0/did_you_mean/spell_checkers/pattern_key_name_checker.rb
51 /usr/lib/ruby/3.1.0/did_you_mean/formatter.rb
52 /usr/lib/ruby/3.1.0/did_you_mean.rb
53 /var/lib/gems/3.1.0/gems/redis-client-0.22.2/lib/redis_client/version.rb
54 /var/lib/gems/3.1.0/gems/redis-client-0.22.2/lib/redis_client/command_builder.rb
55 /usr/lib/ruby/3.1.0/uri/version.rb
56 /usr/lib/ruby/3.1.0/uri/rfc2396_parser.rb
57 /usr/lib/ruby/3.1.0/uri/rfc3986_parser.rb
58 /usr/lib/ruby/3.1.0/uri/common.rb
59 /usr/lib/ruby/3.1.0/uri/generic.rb
60 /usr/lib/ruby/3.1.0/uri/file.rb
61 /usr/lib/ruby/3.1.0/uri/ftp.rb
62 /usr/lib/ruby/3.1.0/uri/http.rb
63 /usr/lib/ruby/3.1.0/uri/https.rb
64 /usr/lib/ruby/3.1.0/uri/ldap.rb
65 /usr/lib/ruby/3.1.0/uri/ldaps.rb
66 /usr/lib/ruby/3.1.0/uri/mailto.rb
67 /usr/lib/ruby/3.1.0/uri/ws.rb
68 /usr/lib/ruby/3.1.0/uri.rb
69 /var/lib/gems/3.1.0/gems/redis-client-0.22.2/lib/redis_client/url_config.rb
70 /usr/lib/ruby/3.1.0/digest/version.rb
71 /usr/lib/aarch64-linux-gnu/ruby/3.1.0/digest.so
72 /usr/lib/ruby/3.1.0/digest/loader.rb
73 /usr/lib/ruby/3.1.0/digest.rb
74 /usr/lib/aarch64-linux-gnu/ruby/3.1.0/openssl.so
75 /usr/lib/ruby/3.1.0/openssl/bn.rb
76 /usr/lib/ruby/3.1.0/openssl/marshal.rb
77 /usr/lib/ruby/3.1.0/openssl/pkey.rb
78 /usr/lib/ruby/3.1.0/openssl/cipher.rb
79 /usr/lib/ruby/3.1.0/openssl/digest.rb
80 /usr/lib/ruby/3.1.0/openssl/hmac.rb
81 /usr/lib/ruby/3.1.0/openssl/x509.rb
82 /usr/lib/ruby/3.1.0/openssl/buffering.rb
83 /usr/lib/aarch64-linux-gnu/ruby/3.1.0/io/nonblock.so
84 /usr/lib/aarch64-linux-gnu/ruby/3.1.0/socket.so
85 /usr/lib/aarch64-linux-gnu/ruby/3.1.0/io/wait.so
86 /usr/lib/ruby/3.1.0/socket.rb
87 /usr/lib/ruby/3.1.0/ipaddr.rb
88 /usr/lib/ruby/3.1.0/openssl/ssl.rb
89 /usr/lib/ruby/3.1.0/openssl/pkcs5.rb
90 /usr/lib/ruby/3.1.0/openssl/version.rb
91 /usr/lib/ruby/3.1.0/openssl.rb
92 /var/lib/gems/3.1.0/gems/redis-client-0.22.2/lib/redis_client/config.rb
93 /var/lib/gems/3.1.0/gems/redis-client-0.22.2/lib/redis_client/pid_cache.rb
94 /var/lib/gems/3.1.0/gems/redis-client-0.22.2/lib/redis_client/sentinel_config.rb
95 /var/lib/gems/3.1.0/gems/redis-client-0.22.2/lib/redis_client/middlewares.rb
96 /usr/lib/ruby/3.1.0/timeout.rb
97 /var/lib/gems/3.1.0/gems/connection_pool-2.4.1/lib/connection_pool/version.rb
98 /var/lib/gems/3.1.0/gems/connection_pool-2.4.1/lib/connection_pool/timed_stack.rb
99 /var/lib/gems/3.1.0/gems/connection_pool-2.4.1/lib/connection_pool/wrapper.rb
100 /var/lib/gems/3.1.0/gems/connection_pool-2.4.1/lib/connection_pool.rb
101 /var/lib/gems/3.1.0/gems/redis-client-0.22.2/lib/redis_client/pooled.rb
102 /var/lib/gems/3.1.0/gems/redis-client-0.22.2/lib/redis_client/circuit_breaker.rb
103 /var/lib/gems/3.1.0/gems/redis-client-0.22.2/lib/redis_client/connection_mixin.rb
104 /var/lib/gems/3.1.0/gems/redis-client-0.22.2/lib/redis_client/ruby_connection/buffered_io.rb
105 /var/lib/gems/3.1.0/gems/redis-client-0.22.2/lib/redis_client/ruby_connection/resp3.rb
106 /var/lib/gems/3.1.0/gems/redis-client-0.22.2/lib/redis_client/ruby_connection.rb
107 /var/lib/gems/3.1.0/gems/redis-client-0.22.2/lib/redis_client.rb
108 /var/lib/gems/3.1.0/gems/redis-client-0.22.2/lib/redis-client.rb
109 /var/lib/gems/3.1.0/gems/hiredis-client-0.22.2/lib/redis_client/hiredis_connection.so
110 /var/lib/gems/3.1.0/gems/hiredis-client-0.22.2/lib/redis_client/hiredis_connection.rb
111 /var/lib/gems/3.1.0/gems/hiredis-client-0.22.2/lib/hiredis-client.rb
* Process memory map:
aaaae4410000-aaaae4411000 r-xp 00000000 fe:01 4798 /usr/bin/ruby3.1
aaaae442f000-aaaae4430000 r--p 0000f000 fe:01 4798 /usr/bin/ruby3.1
aaaae4430000-aaaae4431000 rw-p 00010000 fe:01 4798 /usr/bin/ruby3.1
aaaaffabb000-aaab00081000 rw-p 00000000 00:00 0 [heap]
ffffa8000000-ffffa8021000 rw-p 00000000 00:00 0
ffffa8021000-ffffac000000 ---p 00000000 00:00 0
ffffae400000-ffffae782000 r--s 00000000 fe:01 7924 /usr/lib/aarch64-linux-gnu/libruby-3.1.so.3.1.2
ffffae980000-ffffae994000 r-xp 00000000 fe:01 1599 /usr/lib/aarch64-linux-gnu/libgcc_s.so.1
ffffae994000-ffffae9af000 ---p 00014000 fe:01 1599 /usr/lib/aarch64-linux-gnu/libgcc_s.so.1
ffffae9af000-ffffae9b0000 r--p 0001f000 fe:01 1599 /usr/lib/aarch64-linux-gnu/libgcc_s.so.1
ffffae9b0000-ffffae9b1000 rw-p 00020000 fe:01 1599 /usr/lib/aarch64-linux-gnu/libgcc_s.so.1
ffffae9b7000-ffffae9c8000 r--s 00000000 fe:01 4798 /usr/bin/ruby3.1
ffffae9c8000-ffffaea00000 rw-p 00000000 00:00 0
ffffaea00000-ffffaea10000 ---p 00000000 00:00 0
ffffaea10000-ffffaec10000 rw-p 00000000 00:00 0
ffffaec10000-ffffaec27000 r-xp 00000000 fe:01 824845 /var/lib/gems/3.1.0/gems/hiredis-client-0.22.2/lib/redis_client/hiredis_connection.so
ffffaec27000-ffffaec3f000 ---p 00017000 fe:01 824845 /var/lib/gems/3.1.0/gems/hiredis-client-0.22.2/lib/redis_client/hiredis_connection.so
ffffaec3f000-ffffaec40000 r--p 0001f000 fe:01 824845 /var/lib/gems/3.1.0/gems/hiredis-client-0.22.2/lib/redis_client/hiredis_connection.so
ffffaec40000-ffffaec41000 rw-p 00020000 fe:01 824845 /var/lib/gems/3.1.0/gems/hiredis-client-0.22.2/lib/redis_client/hiredis_connection.so
ffffaec48000-ffffaec50000 rw-p 00000000 00:00 0
ffffaec50000-ffffaec52000 r-xp 00000000 fe:01 397265 /usr/lib/aarch64-linux-gnu/ruby/3.1.0/io/wait.so
ffffaec52000-ffffaec6f000 ---p 00002000 fe:01 397265 /usr/lib/aarch64-linux-gnu/ruby/3.1.0/io/wait.so
ffffaec6f000-ffffaec70000 r--p 0000f000 fe:01 397265 /usr/lib/aarch64-linux-gnu/ruby/3.1.0/io/wait.so
ffffaec70000-ffffaec71000 rw-p 00010000 fe:01 397265 /usr/lib/aarch64-linux-gnu/ruby/3.1.0/io/wait.so
ffffaec78000-ffffaec80000 rw-p 00000000 00:00 0
ffffaec80000-ffffaecae000 r-xp 00000000 fe:01 397284 /usr/lib/aarch64-linux-gnu/ruby/3.1.0/socket.so
ffffaecae000-ffffaecbf000 ---p 0002e000 fe:01 397284 /usr/lib/aarch64-linux-gnu/ruby/3.1.0/socket.so
ffffaecbf000-ffffaecc0000 r--p 0002f000 fe:01 397284 /usr/lib/aarch64-linux-gnu/ruby/3.1.0/socket.so
ffffaecc0000-ffffaecc1000 rw-p 00030000 fe:01 397284 /usr/lib/aarch64-linux-gnu/ruby/3.1.0/socket.so
ffffaecc8000-ffffaecd0000 rw-p 00000000 00:00 0
ffffaecd0000-ffffaecd1000 r-xp 00000000 fe:01 397264 /usr/lib/aarch64-linux-gnu/ruby/3.1.0/io/nonblock.so
ffffaecd1000-ffffaecef000 ---p 00001000 fe:01 397264 /usr/lib/aarch64-linux-gnu/ruby/3.1.0/io/nonblock.so
ffffaecef000-ffffaecf0000 r--p 0000f000 fe:01 397264 /usr/lib/aarch64-linux-gnu/ruby/3.1.0/io/nonblock.so
ffffaecf0000-ffffaecf1000 rw-p 00010000 fe:01 397264 /usr/lib/aarch64-linux-gnu/ruby/3.1.0/io/nonblock.so
ffffaecf8000-ffffaed00000 rw-p 00000000 00:00 0
ffffaed00000-ffffaed04000 r-xp 00000000 fe:01 397195 /usr/lib/aarch64-linux-gnu/ruby/3.1.0/digest.so
ffffaed04000-ffffaed1f000 ---p 00004000 fe:01 397195 /usr/lib/aarch64-linux-gnu/ruby/3.1.0/digest.so
ffffaed1f000-ffffaed20000 r--p 0000f000 fe:01 397195 /usr/lib/aarch64-linux-gnu/ruby/3.1.0/digest.so
ffffaed20000-ffffaed21000 rw-p 00010000 fe:01 397195 /usr/lib/aarch64-linux-gnu/ruby/3.1.0/digest.so
ffffaed28000-ffffaed30000 rw-p 00000000 00:00 0
ffffaed30000-ffffaf113000 r-xp 00000000 fe:01 2195 /usr/lib/aarch64-linux-gnu/libcrypto.so.3
ffffaf113000-ffffaf125000 ---p 003e3000 fe:01 2195 /usr/lib/aarch64-linux-gnu/libcrypto.so.3
ffffaf125000-ffffaf180000 r--p 003e5000 fe:01 2195 /usr/lib/aarch64-linux-gnu/libcrypto.so.3
ffffaf180000-ffffaf183000 rw-p 00440000 fe:01 2195 /usr/lib/aarch64-linux-gnu/libcrypto.so.3
ffffaf183000-ffffaf186000 rw-p 00000000 00:00 0
ffffaf18c000-ffffaf190000 rw-p 00000000 00:00 0
ffffaf190000-ffffaf22b000 r-xp 00000000 fe:01 2196 /usr/lib/aarch64-linux-gnu/libssl.so.3
ffffaf22b000-ffffaf236000 ---p 0009b000 fe:01 2196 /usr/lib/aarch64-linux-gnu/libssl.so.3
ffffaf236000-ffffaf240000 r--p 000a6000 fe:01 2196 /usr/lib/aarch64-linux-gnu/libssl.so.3
ffffaf240000-ffffaf244000 rw-p 000b0000 fe:01 2196 /usr/lib/aarch64-linux-gnu/libssl.so.3
ffffaf248000-ffffaf250000 rw-p 00000000 00:00 0
ffffaf250000-ffffaf2aa000 r-xp 00000000 fe:01 397273 /usr/lib/aarch64-linux-gnu/ruby/3.1.0/openssl.so
ffffaf2aa000-ffffaf2bc000 ---p 0005a000 fe:01 397273 /usr/lib/aarch64-linux-gnu/ruby/3.1.0/openssl.so
ffffaf2bc000-ffffaf2c0000 r--p 0005c000 fe:01 397273 /usr/lib/aarch64-linux-gnu/ruby/3.1.0/openssl.so
ffffaf2c0000-ffffaf2c1000 rw-p 00060000 fe:01 397273 /usr/lib/aarch64-linux-gnu/ruby/3.1.0/openssl.so
ffffaf2c8000-ffffaf320000 rw-p 00000000 00:00 0
ffffaf320000-ffffaf322000 r-xp 00000000 fe:01 397270 /usr/lib/aarch64-linux-gnu/ruby/3.1.0/monitor.so
ffffaf322000-ffffaf33f000 ---p 00002000 fe:01 397270 /usr/lib/aarch64-linux-gnu/ruby/3.1.0/monitor.so
ffffaf33f000-ffffaf340000 r--p 0000f000 fe:01 397270 /usr/lib/aarch64-linux-gnu/ruby/3.1.0/monitor.so
ffffaf340000-ffffaf341000 rw-p 00010000 fe:01 397270 /usr/lib/aarch64-linux-gnu/ruby/3.1.0/monitor.so
ffffaf344000-ffffaf3a0000 rw-p 00000000 00:00 0
ffffaf3a0000-ffffaf3a2000 r-xp 00000000 fe:01 397245 /usr/lib/aarch64-linux-gnu/ruby/3.1.0/enc/trans/transdb.so
ffffaf3a2000-ffffaf3bf000 ---p 00002000 fe:01 397245 /usr/lib/aarch64-linux-gnu/ruby/3.1.0/enc/trans/transdb.so
ffffaf3bf000-ffffaf3c0000 r--p 0000f000 fe:01 397245 /usr/lib/aarch64-linux-gnu/ruby/3.1.0/enc/trans/transdb.so
ffffaf3c0000-ffffaf3c1000 rw-p 00010000 fe:01 397245 /usr/lib/aarch64-linux-gnu/ruby/3.1.0/enc/trans/transdb.so
ffffaf3c8000-ffffaf3d0000 rw-p 00000000 00:00 0
ffffaf3d0000-ffffaf3d2000 r-xp 00000000 fe:01 397201 /usr/lib/aarch64-linux-gnu/ruby/3.1.0/enc/encdb.so
ffffaf3d2000-ffffaf3ef000 ---p 00002000 fe:01 397201 /usr/lib/aarch64-linux-gnu/ruby/3.1.0/enc/encdb.so
ffffaf3ef000-ffffaf3f0000 r--p 0000f000 fe:01 397201 /usr/lib/aarch64-linux-gnu/ruby/3.1.0/enc/encdb.so
ffffaf3f0000-ffffaf3f1000 rw-p 00010000 fe:01 397201 /usr/lib/aarch64-linux-gnu/ruby/3.1.0/enc/encdb.so
ffffaf3f8000-ffffaf400000 rw-p 00000000 00:00 0
ffffaf400000-ffffaf401000 ---p 00000000 00:00 0
ffffaf401000-ffffaf4a2000 rw-p 00000000 00:00 0
ffffaf4a2000-ffffaf4a3000 ---p 00000000 00:00 0
ffffaf4a3000-ffffaf544000 rw-p 00000000 00:00 0
ffffaf544000-ffffaf545000 ---p 00000000 00:00 0
ffffaf545000-ffffaf5e6000 rw-p 00000000 00:00 0
ffffaf5e6000-ffffaf5e7000 ---p 00000000 00:00 0
ffffaf5e7000-ffffaf688000 rw-p 00000000 00:00 0
ffffaf688000-ffffaf689000 ---p 00000000 00:00 0
ffffaf689000-ffffaf72a000 rw-p 00000000 00:00 0
ffffaf72a000-ffffaf72b000 ---p 00000000 00:00 0
ffffaf72b000-ffffaf7cc000 rw-p 00000000 00:00 0
ffffaf7cc000-ffffaf7cd000 ---p 00000000 00:00 0
ffffaf7cd000-ffffaf86e000 rw-p 00000000 00:00 0
ffffaf86e000-ffffaf86f000 ---p 00000000 00:00 0
ffffaf86f000-ffffaf910000 rw-p 00000000 00:00 0
ffffaf910000-ffffaf911000 ---p 00000000 00:00 0
ffffaf911000-ffffaf9b2000 rw-p 00000000 00:00 0
ffffaf9b2000-ffffaf9b3000 ---p 00000000 00:00 0
ffffaf9b3000-ffffafa54000 rw-p 00000000 00:00 0
ffffafa54000-ffffafa55000 ---p 00000000 00:00 0
ffffafa55000-ffffafaf6000 rw-p 00000000 00:00 0
ffffafaf6000-ffffafaf7000 ---p 00000000 00:00 0
ffffafaf7000-ffffafb98000 rw-p 00000000 00:00 0
ffffafb98000-ffffafb99000 ---p 00000000 00:00 0
ffffafb99000-ffffafc3a000 rw-p 00000000 00:00 0
ffffafc3a000-ffffafc3b000 ---p 00000000 00:00 0
ffffafc3b000-ffffafcdc000 rw-p 00000000 00:00 0
ffffafcdc000-ffffafcdd000 ---p 00000000 00:00 0
ffffafcdd000-ffffafd7e000 rw-p 00000000 00:00 0
ffffafd7e000-ffffafd7f000 ---p 00000000 00:00 0
ffffafd7f000-ffffafe20000 rw-p 00000000 00:00 0
ffffafe20000-ffffafe21000 ---p 00000000 00:00 0
ffffafe21000-ffffafec2000 rw-p 00000000 00:00 0
ffffafec2000-ffffafec3000 ---p 00000000 00:00 0
ffffafec3000-ffffaff64000 rw-p 00000000 00:00 0
ffffaff64000-ffffaff65000 ---p 00000000 00:00 0
ffffaff65000-ffffb0006000 rw-p 00000000 00:00 0
ffffb0006000-ffffb0007000 ---p 00000000 00:00 0
ffffb0007000-ffffb00a8000 rw-p 00000000 00:00 0
ffffb00a8000-ffffb00a9000 ---p 00000000 00:00 0
ffffb00a9000-ffffb014a000 rw-p 00000000 00:00 0
ffffb014a000-ffffb014b000 ---p 00000000 00:00 0
ffffb014b000-ffffb01ec000 rw-p 00000000 00:00 0
ffffb01ec000-ffffb01ed000 ---p 00000000 00:00 0
ffffb01ed000-ffffb028e000 rw-p 00000000 00:00 0
ffffb028e000-ffffb028f000 ---p 00000000 00:00 0
ffffb028f000-ffffb0330000 rw-p 00000000 00:00 0
ffffb0330000-ffffb0331000 ---p 00000000 00:00 0
ffffb0331000-ffffb03d2000 rw-p 00000000 00:00 0
ffffb03d2000-ffffb03d3000 ---p 00000000 00:00 0
ffffb03d3000-ffffb0474000 rw-p 00000000 00:00 0
ffffb0474000-ffffb0475000 ---p 00000000 00:00 0
ffffb0475000-ffffb0516000 rw-p 00000000 00:00 0
ffffb0516000-ffffb0517000 ---p 00000000 00:00 0
ffffb0517000-ffffb05b8000 rw-p 00000000 00:00 0
ffffb05b8000-ffffb05b9000 ---p 00000000 00:00 0
ffffb05b9000-ffffb065a000 rw-p 00000000 00:00 0
ffffb065a000-ffffb065b000 ---p 00000000 00:00 0
ffffb065b000-ffffb06fc000 rw-p 00000000 00:00 0
ffffb06fc000-ffffb06fd000 ---p 00000000 00:00 0
ffffb06fd000-ffffb079e000 rw-p 00000000 00:00 0
ffffb079e000-ffffb079f000 ---p 00000000 00:00 0
ffffb079f000-ffffb2840000 rw-p 00000000 00:00 0
ffffb2847000-ffffb29e9000 rw-p 00000000 00:00 0
ffffb29e9000-ffffb2a40000 r--p 00000000 fe:01 4298 /usr/lib/locale/C.utf8/LC_CTYPE
ffffb2a40000-ffffb2bc7000 r-xp 00000000 fe:01 25337 /usr/lib/aarch64-linux-gnu/libc.so.6
ffffb2bc7000-ffffb2bdc000 ---p 00187000 fe:01 25337 /usr/lib/aarch64-linux-gnu/libc.so.6
ffffb2bdc000-ffffb2be0000 r--p 0018c000 fe:01 25337 /usr/lib/aarch64-linux-gnu/libc.so.6
ffffb2be0000-ffffb2be2000 rw-p 00190000 fe:01 25337 /usr/lib/aarch64-linux-gnu/libc.so.6
ffffb2be2000-ffffb2bef000 rw-p 00000000 00:00 0
ffffb2bf0000-ffffb2c70000 r-xp 00000000 fe:01 25340 /usr/lib/aarch64-linux-gnu/libm.so.6
ffffb2c70000-ffffb2c7f000 ---p 00080000 fe:01 25340 /usr/lib/aarch64-linux-gnu/libm.so.6
ffffb2c7f000-ffffb2c80000 r--p 0008f000 fe:01 25340 /usr/lib/aarch64-linux-gnu/libm.so.6
ffffb2c80000-ffffb2c81000 rw-p 00090000 fe:01 25340 /usr/lib/aarch64-linux-gnu/libm.so.6
ffffb2c88000-ffffb2c90000 rw-p 00000000 00:00 0
ffffb2c90000-ffffb2cbe000 r-xp 00000000 fe:01 1530 /usr/lib/aarch64-linux-gnu/libcrypt.so.1.1.0
ffffb2cbe000-ffffb2ccf000 ---p 0002e000 fe:01 1530 /usr/lib/aarch64-linux-gnu/libcrypt.so.1.1.0
ffffb2ccf000-ffffb2cd0000 r--p 0002f000 fe:01 1530 /usr/lib/aarch64-linux-gnu/libcrypt.so.1.1.0
ffffb2cd0000-ffffb2cd1000 rw-p 00030000 fe:01 1530 /usr/lib/aarch64-linux-gnu/libcrypt.so.1.1.0
ffffb2cd1000-ffffb2cd9000 rw-p 00000000 00:00 0
ffffb2ce0000-ffffb2d55000 r-xp 00000000 fe:01 1629 /usr/lib/aarch64-linux-gnu/libgmp.so.10.4.1
ffffb2d55000-ffffb2d6f000 ---p 00075000 fe:01 1629 /usr/lib/aarch64-linux-gnu/libgmp.so.10.4.1
ffffb2d6f000-ffffb2d70000 r--p 0007f000 fe:01 1629 /usr/lib/aarch64-linux-gnu/libgmp.so.10.4.1
ffffb2d70000-ffffb2d71000 rw-p 00080000 fe:01 1629 /usr/lib/aarch64-linux-gnu/libgmp.so.10.4.1
ffffb2d78000-ffffb2d80000 rw-p 00000000 00:00 0
ffffb2d80000-ffffb2d9a000 r-xp 00000000 fe:01 4913 /usr/lib/aarch64-linux-gnu/libz.so.1.2.13
ffffb2d9a000-ffffb2daf000 ---p 0001a000 fe:01 4913 /usr/lib/aarch64-linux-gnu/libz.so.1.2.13
ffffb2daf000-ffffb2db0000 r--p 0001f000 fe:01 4913 /usr/lib/aarch64-linux-gnu/libz.so.1.2.13
ffffb2db0000-ffffb2db1000 rw-p 00020000 fe:01 4913 /usr/lib/aarch64-linux-gnu/libz.so.1.2.13
ffffb2db8000-ffffb2dc0000 rw-p 00000000 00:00 0
ffffb2dc0000-ffffb312a000 r-xp 00000000 fe:01 7924 /usr/lib/aarch64-linux-gnu/libruby-3.1.so.3.1.2
ffffb312a000-ffffb3136000 ---p 0036a000 fe:01 7924 /usr/lib/aarch64-linux-gnu/libruby-3.1.so.3.1.2
ffffb3136000-ffffb3140000 r--p 00376000 fe:01 7924 /usr/lib/aarch64-linux-gnu/libruby-3.1.so.3.1.2
ffffb3140000-ffffb3141000 rw-p 00380000 fe:01 7924 /usr/lib/aarch64-linux-gnu/libruby-3.1.so.3.1.2
ffffb3141000-ffffb3152000 rw-p 00000000 00:00 0
ffffb3158000-ffffb3160000 rw-p 00000000 00:00 0
ffffb3161000-ffffb3187000 r-xp 00000000 fe:01 25329 /usr/lib/aarch64-linux-gnu/ld-linux-aarch64.so.1
ffffb318c000-ffffb3190000 rw-p 00000000 00:00 0
ffffb3193000-ffffb319a000 r--s 00000000 fe:01 25601 /usr/lib/aarch64-linux-gnu/gconv/gconv-modules.cache
ffffb319a000-ffffb319c000 rw-p 00000000 00:00 0
ffffb319c000-ffffb319e000 r--p 00000000 00:00 0 [vvar]
ffffb319e000-ffffb319f000 r-xp 00000000 00:00 0 [vdso]
ffffb319f000-ffffb31a1000 r--p 0002e000 fe:01 25329 /usr/lib/aarch64-linux-gnu/ld-linux-aarch64.so.1
ffffb31a1000-ffffb31a3000 rw-p 00030000 fe:01 25329 /usr/lib/aarch64-linux-gnu/ld-linux-aarch64.so.1
fffff9079000-fffff9878000 rw-p 00000000 00:00 0 [stack]
Aborted (core dumped)
With Ruby 3.4.0-preview1 compiled with ASAN, ASAN detects a heap-use-after-free.
Full ASAN report
=================================================================
==99==ERROR: AddressSanitizer: heap-use-after-free on address 0x5070000da3d3 at pc 0xaaaacf167d90 bp 0xffff70e2b5c0 sp 0xffff70e2adb0
READ of size 32 at 0x5070000da3d3 thread T2
#0 0xaaaacf167d8c in send (/usr/local/bin/ruby+0x97d8c) (BuildId: 432048382036ad8473f2cd7178b25f9bda061835)
#1 0xffff70f52024 in redisNetWrite /usr/local/bundle/gems/hiredis-client-0.22.2/ext/redis_client/hiredis/vendor/net.c:83:24
#2 0xffff70f58c88 in redisBufferWrite /usr/local/bundle/gems/hiredis-client-0.22.2/ext/redis_client/hiredis/vendor/hiredis.c:971:28
#3 0xffff70f517b8 in hiredis_buffer_write_safe /usr/local/bundle/gems/hiredis-client-0.22.2/ext/redis_client/hiredis/hiredis_connection.c:272:26
#4 0xffff95930b84 in rb_nogvl /usr/src/ruby/thread.c:1543:5
#5 0xffff70f4f264 in hiredis_buffer_write_nogvl /usr/local/bundle/gems/hiredis-client-0.22.2/ext/redis_client/hiredis/hiredis_connection.c:280:5
#6 0xffff70f4f264 in hiredis_read_internal /usr/local/bundle/gems/hiredis-client-0.22.2/ext/redis_client/hiredis/hiredis_connection.c:745:17
#7 0xffff70f4f264 in hiredis_read /usr/local/bundle/gems/hiredis-client-0.22.2/ext/redis_client/hiredis/hiredis_connection.c:808:13
#8 0xffff959e9b34 in vm_call_cfunc_with_frame_ /usr/src/ruby/./vm_insnhelper.c:3594:11
#9 0xffff959ab1fc in vm_sendish /usr/src/ruby/./vm_insnhelper.c:5723:15
#10 0xffff959ab1fc in vm_exec_core /usr/src/ruby/insns.def:891:11
#11 0xffff9599f660 in rb_vm_exec /usr/src/ruby/vm.c:2559:22
#12 0xffff959cd4b8 in invoke_block /usr/src/ruby/vm.c:1517:12
#13 0xffff959cd4b8 in invoke_iseq_block_from_c /usr/src/ruby/vm.c:1587:16
#14 0xffff959cd4b8 in invoke_block_from_c_proc /usr/src/ruby/vm.c:1685:16
#15 0xffff959cd4b8 in vm_invoke_proc /usr/src/ruby/vm.c:1715:12
#16 0xffff9594685c in thread_do_start_proc /usr/src/ruby/thread.c:594:16
#17 0xffff959451b8 in thread_do_start /usr/src/ruby/thread.c:611:18
#18 0xffff959451b8 in thread_start_func_2 /usr/src/ruby/thread.c:666:18
#19 0xffff959445f4 in call_thread_start_func_2 /usr/src/ruby/./thread_pthread.c:2235:5
#20 0xffff959445f4 in nt_start /usr/src/ruby/./thread_pthread.c:2280:13
#21 0xaaaacf19e124 in asan_thread_start(void*) asan_interceptors.cpp.o
#22 0xffff94fdee54 in start_thread nptl/pthread_create.c:442:8
#23 0xffff95047f98 in thread_start misc/../sysdeps/unix/sysv/linux/aarch64/clone.S:79
0x5070000da3d3 is located 3 bytes inside of 68-byte region [0x5070000da3d0,0x5070000da414)
freed by thread T0 here:
#0 0xaaaacf1a057c in free (/usr/local/bin/ruby+0xd057c) (BuildId: 432048382036ad8473f2cd7178b25f9bda061835)
#1 0xffff70f58d9c in redisBufferWrite /usr/local/bundle/gems/hiredis-client-0.22.2/ext/redis_client/hiredis/vendor/hiredis.c:976:17
#2 0xffff70f517b8 in hiredis_buffer_write_safe /usr/local/bundle/gems/hiredis-client-0.22.2/ext/redis_client/hiredis/hiredis_connection.c:272:26
#3 0xffff95930b84 in rb_nogvl /usr/src/ruby/thread.c:1543:5
#4 0x36ffff70f4f6f8 (<unknown module>)
#5 0xffff959e9b34 in vm_call_cfunc_with_frame_ /usr/src/ruby/./vm_insnhelper.c:3594:11
#6 0x30ffff959ab1fc (<unknown module>)
#7 0x71ffff9599f900 (<unknown module>)
#8 0x3ffff95651d5c (<unknown module>)
#9 0x79ffff95651b94 (<unknown module>)
#10 0x39aaaacf1dbf1c (<unknown module>)
#11 0x10ffff94f8777c (<unknown module>)
#12 0xffff94f87854 in __libc_start_main csu/../csu/libc-start.c:360:3
#13 0xaaaacf10436c in _start (/usr/local/bin/ruby+0x3436c) (BuildId: 432048382036ad8473f2cd7178b25f9bda061835)
previously allocated by thread T0 here:
#0 0xaaaacf1a0bbc in realloc (/usr/local/bin/ruby+0xd0bbc) (BuildId: 432048382036ad8473f2cd7178b25f9bda061835)
#1 0xffff70f5c7e4 in hi_realloc /usr/local/bundle/gems/hiredis-client-0.22.2/ext/redis_client/hiredis/vendor/./alloc.h:66:12
#2 0xffff70f5c7e4 in sdsMakeRoomFor /usr/local/bundle/gems/hiredis-client-0.22.2/ext/redis_client/hiredis/vendor/sds.c:223:17
#3 0xffff70f5e338 in sdscatlen /usr/local/bundle/gems/hiredis-client-0.22.2/ext/redis_client/hiredis/vendor/sds.c:381:9
#4 0xffff70f5a27c in __redisAppendCommand /usr/local/bundle/gems/hiredis-client-0.22.2/ext/redis_client/hiredis/vendor/hiredis.c:1065:14
#5 0xffff70f5a27c in redisAppendCommandArgv /usr/local/bundle/gems/hiredis-client-0.22.2/ext/redis_client/hiredis/vendor/hiredis.c:1126:9
#6 0xffff70f4ece8 in hiredis_write /usr/local/bundle/gems/hiredis-client-0.22.2/ext/redis_client/hiredis/hiredis_connection.c:684:5
#7 0xffff959e9b34 in vm_call_cfunc_with_frame_ /usr/src/ruby/./vm_insnhelper.c:3594:11
#8 0x30ffff959ab1fc (<unknown module>)
#9 0x71ffff9599f900 (<unknown module>)
#10 0x3ffff95651d5c (<unknown module>)
#11 0x79ffff95651b94 (<unknown module>)
#12 0x39aaaacf1dbf1c (<unknown module>)
#13 0x10ffff94f8777c (<unknown module>)
#14 0xffff94f87854 in __libc_start_main csu/../csu/libc-start.c:360:3
#15 0xaaaacf10436c in _start (/usr/local/bin/ruby+0x3436c) (BuildId: 432048382036ad8473f2cd7178b25f9bda061835)
Thread T2 created by T0 here:
#0 0xaaaacf186538 in pthread_create (/usr/local/bin/ruby+0xb6538) (BuildId: 432048382036ad8473f2cd7178b25f9bda061835)
#1 0xffff9592e504 in native_thread_create0 /usr/src/ruby/./thread_pthread.c:2152:11
#2 0xffff9592e504 in native_thread_create_dedicated /usr/src/ruby/./thread_pthread.c:2219:12
#3 0xffff9592e504 in native_thread_create /usr/src/ruby/./thread_pthread.c:2398:16
#4 0xffff9592e504 in thread_create_core /usr/src/ruby/thread.c:859:11
#5 0x31ffff9593d77c (<unknown module>)
#6 0x4cffff959f8e70 (<unknown module>)
#7 0x21ffff959fc1b0 (<unknown module>)
#8 0xaffff9593c28c (<unknown module>)
#9 0x42ffff959e9b34 (<unknown module>)
#10 0x6effff959d8510 (<unknown module>)
#11 0x3fffff959d7f54 (<unknown module>)
#12 0x28ffff959a3a80 (<unknown module>)
#13 0x71ffff9599f900 (<unknown module>)
#14 0x3ffff95651d5c (<unknown module>)
#15 0x79ffff95651b94 (<unknown module>)
#16 0x39aaaacf1dbf1c (<unknown module>)
#17 0x10ffff94f8777c (<unknown module>)
#18 0xffff94f87854 in __libc_start_main csu/../csu/libc-start.c:360:3
#19 0xaaaacf10436c in _start (/usr/local/bin/ruby+0x3436c) (BuildId: 432048382036ad8473f2cd7178b25f9bda061835)
SUMMARY: AddressSanitizer: heap-use-after-free (/usr/local/bin/ruby+0x97d8c) (BuildId: 432048382036ad8473f2cd7178b25f9bda061835) in send
Shadow bytes around the buggy address:
0x5070000da100: fd fd fa fa fa fa fd fd fd fd fd fd fd fd fd fd
0x5070000da180: fa fa fa fa fd fd fd fd fd fd fd fd fd fa fa fa
0x5070000da200: fa fa fd fd fd fd fd fd fd fd fd fa fa fa fa fa
0x5070000da280: fd fd fd fd fd fd fd fd fd fd fa fa fa fa fd fd
0x5070000da300: fd fd fd fd fd fd fd fd fa fa fa fa fd fd fd fd
=>0x5070000da380: fd fd fd fd fd fa fa fa fa fa[fd]fd fd fd fd fd
0x5070000da400: fd fd fd fa fa fa fa fa fd fd fd fd fd fd fd fd
0x5070000da480: fd fd fa fa fa fa fd fd fd fd fd fd fd fd fd fd
0x5070000da500: fa fa fa fa fd fd fd fd fd fd fd fd fd fa fa fa
0x5070000da580: fa fa fd fd fd fd fd fd fd fd fd fa fa fa fa fa
0x5070000da600: fd fd fd fd fd fd fd fd fd fd fa fa fa fa fd fd
Shadow byte legend (one shadow byte represents 8 application bytes):
Addressable: 00
Partially addressable: 01 02 03 04 05 06 07
Heap left redzone: fa
Freed heap region: fd
Stack left redzone: f1
Stack mid redzone: f2
Stack right redzone: f3
Stack after return: f5
Stack use after scope: f8
Global redzone: f9
Global init order: f6
Poisoned by user: f7
Container overflow: fc
Array cookie: ac
Intra object redzone: bb
ASan internal: fe
Left alloca redzone: ca
Right alloca redzone: cb
==99==ABORTING
==99==ERROR: AddressSanitizer: heap-use-after-free on address 0x5070000da3d3 at pc 0xaaaacf167d90 bp 0xffff70e2b5c0 sp 0xffff70e2adb0
T2 in the ASAN report is the reader
Ruby thread that's calling #next_event
:
READ of size 32 at 0x5070000da3d3 thread T2
#0 0xaaaacf167d8c in send (/usr/local/bin/ruby+0x97d8c) (BuildId: 432048382036ad8473f2cd7178b25f9bda061835)
#1 0xffff70f52024 in redisNetWrite /usr/local/bundle/gems/hiredis-client-0.22.2/ext/redis_client/hiredis/vendor/net.c:83:24
#2 0xffff70f58c88 in redisBufferWrite /usr/local/bundle/gems/hiredis-client-0.22.2/ext/redis_client/hiredis/vendor/hiredis.c:971:28
#3 0xffff70f517b8 in hiredis_buffer_write_safe /usr/local/bundle/gems/hiredis-client-0.22.2/ext/redis_client/hiredis/hiredis_connection.c:272:26
#4 0xffff95930b84 in rb_nogvl /usr/src/ruby/thread.c:1543:5
#5 0xffff70f4f264 in hiredis_buffer_write_nogvl /usr/local/bundle/gems/hiredis-client-0.22.2/ext/redis_client/hiredis/hiredis_connection.c:280:5
#6 0xffff70f4f264 in hiredis_read_internal /usr/local/bundle/gems/hiredis-client-0.22.2/ext/redis_client/hiredis/hiredis_connection.c:745:17
#7 0xffff70f4f264 in hiredis_read /usr/local/bundle/gems/hiredis-client-0.22.2/ext/redis_client/hiredis/hiredis_connection.c:808:13
This thread should just be reading, but it ends up accessing the write buffer, as hiredis_read_internal also drains the write buffer.
The write buffer had already been freed by the main Ruby thread that's writing subscribe
and unsubscribe
commands:
0x5070000da3d3 is located 3 bytes inside of 68-byte region [0x5070000da3d0,0x5070000da414)
freed by thread T0 here:
#0 0xaaaacf1a057c in free (/usr/local/bin/ruby+0xd057c) (BuildId: 432048382036ad8473f2cd7178b25f9bda061835)
#1 0xffff70f58d9c in redisBufferWrite /usr/local/bundle/gems/hiredis-client-0.22.2/ext/redis_client/hiredis/vendor/hiredis.c:976:17
#2 0xffff70f517b8 in hiredis_buffer_write_safe /usr/local/bundle/gems/hiredis-client-0.22.2/ext/redis_client/hiredis/hiredis_connection.c:272:26
#3 0xffff95930b84 in rb_nogvl /usr/src/ruby/thread.c:1543:5
From my naive understanding, it seems flushing the write buffer inside hiredis_read_internal
is unnecessary, as HiredisConnection already calls flush
after writes?
redis-client/hiredis-client/lib/redis_client/hiredis_connection.rb
Lines 109 to 129 in e8aff08
Removing the write buffer flush from hiredis_read_internal
fixes the crashes/ASAN errors in my reproduction above. I've made a PR with the change.
Nice catch.