Mantis Bug Tracker

View Issue Details Jump to Notes ] Issue History ] Print ]
IDProjectCategoryView StatusDate SubmittedLast Update
0007815OCamlruntime system and C interfacepublic2018-06-27 04:332018-07-19 17:56
Reporterjoris 
Assigned Todoligez 
PrioritynormalSeveritycrashReproducibilityalways
StatusresolvedResolutionfixed 
Platformamd64OSlinuxOS Version
Product Version4.06.1 
Target Version4.07.1+devFixed in Version4.07.1+dev 
Summary0007815: Major GC crashes on fragmented heap with large number of block size and first_fit policy
DescriptionCalling Gc.full_major (or simply major) after allocating thousands of block of different word size and freeing half of them with first_fit policy makes the runtime crash with no meaningful trace
Steps To ReproduceCompile the attached file with
opam install gperftools # install tcmalloc

ocamlfind ocamlopt -g -linkpkg -package gperftools minimal.ml

and run it. On my machine it also crashes with jemalloc with rounds = 3 and nr_blocks = 20000

opam install jemalloc
ocamlfind ocamlopt -g -linkpkg -package jemalloc_ctl minimal.ml
Additional InformationBackground:
This code is an un-natural example and it was obviously hand-crafted.

I came across this issue after trying to reproduce a bug in minor gc and caml_fl_allocate which under certain conditions makes minor gc run forever (or at least quadratically, but for half an hour on small heaps at least).

I was trying to fill the flp to see what would happen in this case. I don't know yet if those two issues are related
TagsNo tags attached.
Attached Files? file icon minimal.ml [^] (644 bytes) 2018-06-27 04:33 [Show Content]

- Relationships

-  Notes
(0019217)
stedolan (developer)
2018-06-27 15:09

That's a nice reproduction case!

This bug is reproducible by running the bytecode interpreter under valgrind, which should make debugging easier. It seems to be independent of the choice of malloc, although it doesn't seem to actually segfault with the default glibc allocator.

In freelist.c, there's this loop:

        value buf [FLP_MAX];
        int j = 0;
        mlsize_t oldsz = sz;

        prev = flp[i];
        while (prev != flp[i+1]){
          cur = Next (prev);
          sz = Wosize_bp (cur);
          if (sz > prevsz){
            buf[j++] = prev;
            prevsz = sz;
            if (sz >= oldsz){
              CAMLassert (sz == oldsz);
              break;
            }
          }
          prev = cur;
        }

This example causes 'buf[j++] = prev' (line 345) to run more than FLP_MAX times, overflowing the buffer.
(0019234)
doligez (administrator)
2018-07-11 16:55

This is embarrassingly easy to fix, see https://github.com/ocaml/ocaml/pull/1896 [^]

@joris: do you want to be credited in the changelog with your real name?
@stedolan: would you like to review the fix?
(0019239)
joris (reporter)
2018-07-12 01:17

Awesome !

As you wish, i don't know what's the usual practice. In anycase my name is Joris Giovannangeli.
(0019258)
xleroy (administrator)
2018-07-19 17:56

Commits 802ebbf (trunk) and 1bea41f (4.07 branch)

- Issue History
Date Modified Username Field Change
2018-06-27 04:33 joris New Issue
2018-06-27 04:33 joris File Added: minimal.ml
2018-06-27 15:09 stedolan Note Added: 0019217
2018-07-11 16:55 doligez Note Added: 0019234
2018-07-11 16:55 doligez Assigned To => doligez
2018-07-11 16:55 doligez Status new => assigned
2018-07-11 16:56 doligez Target Version => 4.07.1+dev
2018-07-12 01:17 joris Note Added: 0019239
2018-07-19 17:56 xleroy Note Added: 0019258
2018-07-19 17:56 xleroy Status assigned => resolved
2018-07-19 17:56 xleroy Resolution open => fixed
2018-07-19 17:56 xleroy Fixed in Version => 4.07.1+dev


Copyright © 2000 - 2011 MantisBT Group
Powered by Mantis Bugtracker