Skip to content

Commit

Permalink
Fix ary_make_partial_step for compaction
Browse files Browse the repository at this point in the history
ary could change embeddedness due to compaction, so we should only get
the pointer after allocations.

The included test was crashing with:

    TestArray#test_slice_gc_compact_stress
    ruby/lib/pp.rb:192: [BUG] Segmentation fault at 0x0000000000000038
  • Loading branch information
peterzhu2118 committed Dec 21, 2023
1 parent fd47351 commit e191bf4
Show file tree
Hide file tree
Showing 2 changed files with 10 additions and 1 deletion.
7 changes: 6 additions & 1 deletion array.c
Expand Up @@ -1231,12 +1231,13 @@ ary_make_partial_step(VALUE ary, VALUE klass, long offset, long len, long step)
assert(offset+len <= RARRAY_LEN(ary));
assert(step != 0);

const VALUE *values = RARRAY_CONST_PTR(ary);
const long orig_len = len;

if (step > 0 && step >= len) {
VALUE result = ary_new(klass, 1);
VALUE *ptr = (VALUE *)ARY_EMBED_PTR(result);
const VALUE *values = RARRAY_CONST_PTR(ary);

RB_OBJ_WRITE(result, ptr, values[offset]);
ARY_SET_EMBED_LEN(result, 1);
return result;
Expand All @@ -1254,13 +1255,17 @@ ary_make_partial_step(VALUE ary, VALUE klass, long offset, long len, long step)
VALUE result = ary_new(klass, len);
if (ARY_EMBED_P(result)) {
VALUE *ptr = (VALUE *)ARY_EMBED_PTR(result);
const VALUE *values = RARRAY_CONST_PTR(ary);

for (i = 0; i < len; ++i) {
RB_OBJ_WRITE(result, ptr+i, values[j]);
j += step;
}
ARY_SET_EMBED_LEN(result, len);
}
else {
const VALUE *values = RARRAY_CONST_PTR(ary);

RARRAY_PTR_USE(result, ptr, {
for (i = 0; i < len; ++i) {
RB_OBJ_WRITE(result, ptr+i, values[j]);
Expand Down
4 changes: 4 additions & 0 deletions test/ruby/test_array.rb
Expand Up @@ -1704,6 +1704,10 @@ def test_slice_out_of_range

def test_slice_gc_compact_stress
EnvUtil.under_gc_compact_stress { assert_equal([1, 2, 3, 4, 5], (0..10).to_a[1, 5]) }
EnvUtil.under_gc_compact_stress do
a = [0, 1, 2, 3, 4, 5]
assert_equal([2, 1, 0], a.slice((2..).step(-1)))
end
end

def test_slice!
Expand Down

0 comments on commit e191bf4

Please sign in to comment.