From: "Eregon (Benoit Daloze) via ruby-core" Date: 2023-01-07T12:00:53+00:00 Subject: [ruby-core:111722] [Ruby master Bug#18518] NoMemoryError + [FATAL] failed to allocate memory for twice 1 << large Issue #18518 has been updated by Eregon (Benoit Daloze). nobu (Nobuyoshi Nakada) wrote in #note-8: > It is a test for the development branch and unrelated to users using released versions. It might not be clear given the original bug report, but the behavior of NoMemoryError vs RangeError on CRuby for `1 << (2**40)` is independent of dev/released version. So in this issue I suggest https://bugs.ruby-lang.org/issues/18518#note-4: > I think CRuby should check if RHS is bigger than 2**31 and if so raise an exception (e.g. RangeError) immediately instead of taking a lot of time and run into OOM Current behavior on `ruby 3.2.0 (2022-12-25 revision a528908271) [x86_64-linux]`: ``` $ ruby -e '1 << 2**40' -e: failed to allocate memory (NoMemoryError) $ ruby -e '1 << 2**64' -e: failed to allocate memory (NoMemoryError) $ ruby -e '1 << 2**128' -e:1:in `<<': shift width too big (RangeError) $ ruby -e '1 << 2**66' -e: failed to allocate memory (NoMemoryError) $ ruby -e '1 << 2**67' -e:1:in `<<': shift width too big (RangeError) ``` So the limit for RangeError on CRuby seems between 2^66 and 2^67, at least locally on my computer. Which makes sense given that's in bits, divided by 8 is the same as -3, so 67-3 = 64, CRuby can't allocate something that doesn't fit in size_t/64-bit. Interestingly `1 << 2**32` does work on CRuby: ``` $ ruby -e 'p (1 << 2**32).bit_length' 4294967297 # works locally for me, which I did not expect $ ruby -robjspace -e 'p ObjectSpace.memsize_of(1 << 2**32)' 536870956 ``` So OK let's keep this rejected and accept this limit is implementation-defined (2**67 on 64-bit CRuby, 2**35 I guess on 32-bit CRuby, 2**31 on JRuby+TruffleRuby) and I'll adapt the spec. ---------------------------------------- Bug #18518: NoMemoryError + [FATAL] failed to allocate memory for twice 1 << large https://bugs.ruby-lang.org/issues/18518#change-101122 * Author: Eregon (Benoit Daloze) * Status: Rejected * Priority: Normal * ruby -v: ruby 3.0.2p107 (2021-07-07 revision 0db68f0233) [x86_64-linux] * Backport: 2.6: UNKNOWN, 2.7: UNKNOWN, 3.0: UNKNOWN, 3.1: UNKNOWN ---------------------------------------- Repro: ```ruby exp = 2**40 # also fails with bignum e.g. 2**64 def exc begin yield rescue NoMemoryError => e p :NoMemoryError end end p exp exc { (1 << exp) } exc { (-1 << exp) } exc { (bignum_value << exp) } exc { (-bignum_value << exp) } ``` Output: ``` $ ruby -v mri_oom.rb ruby 3.0.2p107 (2021-07-07 revision 0db68f0233) [x86_64-linux] mri_oom.rb:7: warning: assigned but unused variable - e 1099511627776 :NoMemoryError [FATAL] failed to allocate memory ``` 3.1.0 seems fine: ``` $ ruby -v mri_oom.rb ruby 3.1.0p0 (2021-12-25 revision fb4df44d16) [x86_64-linux] mri_oom.rb:7: warning: assigned but unused variable - e 1099511627776 :NoMemoryError :NoMemoryError :NoMemoryError :NoMemoryError ``` -- https://bugs.ruby-lang.org/ ______________________________________________ ruby-core mailing list -- ruby-core@ml.ruby-lang.org To unsubscribe send an email to ruby-core-leave@ml.ruby-lang.org ruby-core info -- https://ml.ruby-lang.org/mailman3/postorius/lists/ruby-core.ml.ruby-lang.org/