Bug 445545
| Summary: | ocamlc fails trying to allocate 34 GB of RAM | ||||||
|---|---|---|---|---|---|---|---|
| Product: | [Fedora] Fedora | Reporter: | Radzevich Belevich <serp> | ||||
| Component: | ocaml | Assignee: | Richard W.M. Jones <rjones> | ||||
| Status: | CLOSED CURRENTRELEASE | QA Contact: | Fedora Extras Quality Assurance <extras-qa> | ||||
| Severity: | high | Docs Contact: | |||||
| Priority: | low | ||||||
| Version: | 8 | CC: | rjones | ||||
| Target Milestone: | --- | Keywords: | Reopened | ||||
| Target Release: | --- | ||||||
| Hardware: | athlon | ||||||
| OS: | Linux | ||||||
| Whiteboard: | |||||||
| Fixed In Version: | ocaml-3.10.1-3.fc9 | Doc Type: | Bug Fix | ||||
| Doc Text: | Story Points: | --- | |||||
| Clone Of: | |||||||
| : | 877128 (view as bug list) | Environment: | |||||
| Last Closed: | 2008-07-13 20:32:13 UTC | Type: | --- | ||||
| Regression: | --- | Mount Type: | --- | ||||
| Documentation: | --- | CRM: | |||||
| Verified Versions: | Category: | --- | |||||
| oVirt Team: | --- | RHEL 7.3 requirements from Atomic Host: | |||||
| Cloudforms Team: | --- | Target Upstream Version: | |||||
| Embargoed: | |||||||
| Bug Depends On: | |||||||
| Bug Blocks: | 438486, 441685, 454384 | ||||||
| Attachments: |
|
||||||
|
Description
Radzevich Belevich
2008-05-07 14:50:16 UTC
I've not seen this and I routinely compile OCaml modules & OCaml itself on x86-64. Can you give the precise versions of the Fedora ocaml packages you're using please. [serp@serp pp]$ cat /etc/redhat-release
Fedora release 9 (Sulphur)
[serp@serp pp]$ uname -a
Linux serp.office.stork.ru 2.6.25-14.fc9.x86_64 #1 SMP Thu May 1 06:06:21 EDT
2008 x86_64 x86_64 x86_64 GNU/Linux
[serp@serp pp]$ rpm -qa ocaml*
ocaml-pcre-5.13.0-2.fc9.x86_64
ocaml-findlib-devel-1.2.1-2.fc9.i386
ocaml-camlp4-3.10.1-2.fc9.x86_64
ocaml-findlib-1.2.1-2.fc9.x86_64
ocaml-3.10.1-2.fc9.x86_64
ocaml-camlp4-devel-3.10.1-2.fc9.x86_64
ocaml-runtime-3.10.1-2.fc9.x86_64
ocaml-extlib-1.5.1-2.fc9.x86_64
[serp@serp pp]$ cat log.ml
open Camlp4.PreCast;
open Syntax;
value insert_mname_mline _loc f = <:expr<Log.$lid:f$ $str:Loc.file_name _loc$
$`int:Loc.start_line _loc$>>;
EXTEND Gram
GLOBAL: expr;
expr:
[
[ "Log"; "."; f = [ `LIDENT ("e"|"d"|"w" as f) -> f] ->
insert_mname_mline _loc f ]
];
END;
[serp@serp pp]$ /usr/bin/ocamlc.opt -c -I +camlp4 -pp camlp4rf log.ml -o log.cmo
Fatal error: out of memory.
[serp@serp pp]$ /usr/bin/ocamlc.opt -c -I +camlp4 -pp camlp4rf log.ml -o log.cmo
Fatal error: exception Out_of_memory
Raised at file "", line 0, characters 0-0
Called from file "arg.ml", line 211, characters 4-32
[serp@serp pp]$ /usr/bin/ocamlc.opt -c -I +camlp4 -pp camlp4rf log.ml -o log.cmo
[serp@serp pp]$
First of all I can't reproduce this on either my i386 & x86-64 machines with our ocaml-3.10.1-2 package. They all compile log.ml with the command shown without any error. Also I don't quite understand the commands you show above. Do you mean that when you run the ocamlc.opt command three times, you get three different outputs? Or are you running this on different machines or modifying the input in some manner? Also, can you do: ulimit -a free -m Just need to check there are no artificial limits in your setup. Yes, I run this command three time in a row, and get three different outputs. Last it's compiled successfully :-) But three it's not a regularity. Sometime it's success immediately, but sometimes three or more. [serp@serp pp]$ ulimit -a
core file size (blocks, -c) 0
data seg size (kbytes, -d) unlimited
scheduling priority (-e) 0
file size (blocks, -f) unlimited
pending signals (-i) 8191
max locked memory (kbytes, -l) 32
max memory size (kbytes, -m) unlimited
open files (-n) 1024
pipe size (512 bytes, -p) 8
POSIX message queues (bytes, -q) 819200
real-time priority (-r) 0
stack size (kbytes, -s) 10240
cpu time (seconds, -t) unlimited
max user processes (-u) 1024
virtual memory (kbytes, -v) unlimited
file locks (-x) unlimited
[serp@serp pp]$ free -m
total used free shared buffers cached
Mem: 1004 929 74 0 47 407
-/+ buffers/cache: 474 529
Swap: 1919 0 1919
==============================================
On i386 mashine, all ok.
On ocaml 3.11+dev12 on this mashine (compiled from source), all ok.
But ocaml 3.10.2 compilation has this problem.
Yes, you're right - I can reproduce this if I run the ocamlc.opt command often enough, and in fact I've seen this bug before. Bug 438486 ocaml-camomile doesn't build on ppc64 (even in Rawhide) It's almost exactly the same symtoms too: ocamlc.opt tries to allocate 34 GB [sic] of RAM and obviously fails. It does this non-deterministically. Example from the strace: mmap(NULL, 34289692672, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = -1 ENOMEM (Cannot allocate memory) A bit of informal testing seems to indicate this is a Fedora-specific problem, in that it doesn't appear to occur on Debian. I've posted about this issue on caml-list. Thanks for the small reproducer. Hopefully someone on caml-list will have some more insight, if not I'll take a closer look over the next few days. Reassigning the BZ to me, I'm sure gemi won't mind :-) I've tracked down the problem and come up with two possible solutions. My reasoning is contained in this thread in more detail: http://caml.inria.fr/pub/ml-archives/caml-list/2008/05/f03aa82c55e7dfcfb409536a28fcdedd.en.html The problem is essentially that Fedora mmap returns high memory addresses and the way the OCaml runtime is constructed, this is unexpected. OCaml runtime tries to construct a linear page table, an array tracking which pages are contained in the OCaml heap and which are regular pages (eg. external mallocs). This method doesn't work when pages can be present at very high memory addresses (or at least, it would work if the page table could be extended to 34 GB, but it can't be!) There are two possible solutions: (1) Easy hack but x86-64 only: Pass the MAP_32BIT flag to mmap. This causes mmap to return memory addresses below 2 GB, and fixes the problem. However (a) this is only available on x86-64 (not, eg, ppc64 where we also have the problem). (b) This limits the OCaml runtime to quite a small maximum heap, probably 1 or 2 GB max. (2) Difficult: In OCaml 3.11, the linear page table stuff has been completely rewritten to use a hash table, to get around this problem. We could in theory backport this to OCaml 3.10, but honestly the patch is huge and changes large amounts of the runtime, and I have little confidence I could do this backport correctly. I guess there is a third possibility which is to find out why mmap in Fedora behaves so differently from mmap in, say, Debian. I'll post a patch for (1) in a moment once I've done a bit more testing. Created attachment 304848 [details]
ocaml-3.10.1-map32bit.patch
Patch to pass MAP_32BIT to mmap.
Confirmed that this fixes the original reported problem
on x86-64 / F-9.
See also 454384; a request for a backport of this fix to F8. Reopening, assigning to F-8. Ooops - didn't see that we also have bug 454384. Closing again - I'm going to fix that one now. |