Skip to content

Commit

Permalink
Merge pull request #10217 from damiendoligez/fix-9853
Browse files Browse the repository at this point in the history
fix for #9853
  • Loading branch information
Octachron committed Apr 16, 2021
2 parents 2c85ab7 + 505d4ec commit 791f819
Show file tree
Hide file tree
Showing 3 changed files with 20 additions and 8 deletions.
3 changes: 3 additions & 0 deletions Changes
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,9 @@ Working version
to the debugger via a socket.
(Antonin Décimo, review by Xavier Leroy)

- #10217: Fix a segfault in a corner case of compaction (reported in #9853)
(Damien Doligez, report by Sadiq Jaffer, review by Stephen Dolan)

- #10250, #10266: Dynamically allocate alternate signal stacks to
accommodate changes in Glibc 2.34.
(Xavier Leroy, reports by Tomasz Kłoczko and R.W.M. Jones, review by Anil
Expand Down
15 changes: 7 additions & 8 deletions runtime/compact.c
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,8 @@ extern void caml_shrink_heap (char *); /* memory.c */
We use the GC's color bits in the following way:
- White words are headers of live blocks.
- White words are headers of live blocks except for 0, which is a
fragment.
- Blue words are headers of free blocks.
- Black words are headers of out-of-heap "blocks".
- Gray words are the encoding of pointers in inverted lists.
Expand Down Expand Up @@ -122,11 +123,9 @@ static char *compact_allocate (mlsize_t size)
{
char *chunk, *adr;

while (Chunk_size (compact_fl) - Chunk_alloc (compact_fl) <= Bhsize_wosize (3)
&& Chunk_size (Chunk_next (compact_fl))
- Chunk_alloc (Chunk_next (compact_fl))
<= Bhsize_wosize (3)){
while (Chunk_size(compact_fl) - Chunk_alloc(compact_fl) < Bhsize_wosize(1)){
compact_fl = Chunk_next (compact_fl);
CAMLassert (compact_fl != NULL);
}
chunk = compact_fl;
while (Chunk_size (chunk) - Chunk_alloc (chunk) < size){
Expand Down Expand Up @@ -242,7 +241,7 @@ static void do_compaction (intnat new_allocation_policy)

CAMLassert (!Is_black_hd (h));
CAMLassert (!Is_gray_hd (h));
if (Is_white_hd (h)){
if (h != 0 && Is_white_hd (h)){
word q;
tag_t t;
char *newadr;
Expand Down Expand Up @@ -304,13 +303,13 @@ static void do_compaction (intnat new_allocation_policy)
chend = ch + Chunk_size (ch);
while ((char *) p < chend){
word q = *p;
if (Color_hd (q) == Caml_white){
if (q != 0 && Is_white_hd (q)){
size_t sz = Bhsize_hd (q);
char *newadr = compact_allocate (sz);
memmove (newadr, p, sz);
p += Wsize_bsize (sz);
}else{
CAMLassert (Color_hd (q) == Caml_blue);
CAMLassert (q == 0 || Is_blue_hd (q));
p += Whsize_hd (q);
}
}
Expand Down
10 changes: 10 additions & 0 deletions testsuite/tests/regression/pr9853/compaction_corner_case.ml
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
(* TEST *)

(* Compaction crash when there is only one heap chunk and it is fully used. *)
let c = ref []

let () =
for i = 0 to 25000 do
c := 0 :: !c;
Gc.compact ()
done

0 comments on commit 791f819

Please sign in to comment.