Skip to content

emmalloc failing to allocate memory whereas dlmalloc can successfully allocate #21277

@emelalkim

Description

@emelalkim

Version of emscripten/emsdk:
emcc (Emscripten gcc/clang-like replacement + linker emulating GNU ld) 3.1.46 (1960782)
clang version 18.0.0 (https://github.com/llvm/llvm-project 75501f53624de92aafce2f1da698b249a7293dc7)
Target: wasm32-unknown-emscripten
Thread model: posix
InstalledDir: /emsdk/upstream/bin

Full link command and output with -v appended:
We are using emscripten to compile openjpeg library to create codecs for DICOM files.
configure: cmake .. -DCMAKE_TOOLCHAIN_FILE=/emsdk/upstream/emscripten/cmake/Modules/Platform/Emscripten.cmake -DCMAKE_CROSSCOMPILING_EMULATOR=/emsdk/node/16.20.0_64bit/bin/node

Two different js files are created:
openjpegjs.js
/emsdk/upstream/emscripten/em++ -O3 --bind -s MODULARIZE=1 -s EXPORT_NAME=OpenJPEGJS -s WASM=0 -s DISABLE_EXCEPTION_CATCHING=1 -s ASSERTIONS=2 -s NO_EXIT_RUNTIME=1 -s MALLOC=emmalloc -s ALLOW_MEMORY_GROWTH=1 -s INITIAL_MEMORY=50mb -s FILESYSTEM=0 -s EXPORTED_FUNCTIONS=[] -s EXPORTED_RUNTIME_METHODS=[ccall] @CMakeFiles/openjpegjs.dir/objects1.rsp -o ../extern/openjpeg/bin/openjpegjs.js @CMakeFiles/openjpegjs.dir/linklibs.rsp
openjpegjs_decode.js
/emsdk/upstream/emscripten/em++ -O3 --bind -s MODULARIZE=1 -s EXPORT_NAME=OpenJPEGJS -s WASM=0 -s DISABLE_EXCEPTION_CATCHING=1 -s ASSERTIONS=2 -s NO_EXIT_RUNTIME=1 -s MALLOC=emmalloc -s ALLOW_MEMORY_GROWTH=1 -s INITIAL_MEMORY=50mb -s FILESYSTEM=0 -s EXPORTED_FUNCTIONS=[] -s EXPORTED_RUNTIME_METHODS=[ccall] @CMakeFiles/openjpegjs_decode.dir/objects1.rsp -o ../extern/openjpeg/bin/openjpegjs_decode.js @CMakeFiles/openjpegjs_decode.dir/linklibs.rsp

When we try to decode some files using openjpegjs.js, memory allocation crashes while trying to allocate 595*4 bytes of memory in this line. It increases the heap size till it exceeds 2GB and cannot allocate memory which results in not being able to decompress the data.
Here are the assertion logs.

encodedBitStream.length= 1960356
[INFO] Header of tile 1 / 1 has been read.
Heap resize call from 52428800 to 62914560 took 2.5182799994945526 msecs. Success: true
Heap resize call from 62914560 to 75497472 took 4.030688002705574 msecs. Success: true
Heap resize call from 75497472 to 90636288 took 0.11062300205230713 msecs. Success: true
Heap resize call from 90636288 to 108789760 took 4.0902139991521835 msecs. Success: true
Heap resize call from 108789760 to 130547712 took 0.43175700306892395 msecs. Success: true
Heap resize call from 130547712 to 156696576 took 0.20280899107456207 msecs. Success: true
Heap resize call from 156696576 to 188088320 took 2.495059996843338 msecs. Success: true
Heap resize call from 188088320 to 225705984 took 0.8876210004091263 msecs. Success: true
Heap resize call from 225705984 to 270860288 took 0.14028400182724 msecs. Success: true
Heap resize call from 270860288 to 325058560 took 1.9511590003967285 msecs. Success: true
Heap resize call from 325058560 to 390070272 took 0.7931340038776398 msecs. Success: true
Heap resize call from 390070272 to 468123648 took 0.15468500554561615 msecs. Success: true
Heap resize call from 468123648 to 561774592 took 1.5468769967556 msecs. Success: true
Heap resize call from 561774592 to 662503424 took 0.49696899950504303 msecs. Success: true
Heap resize call from 662503424 to 763232256 took 0.1452219933271408 msecs. Success: true
Heap resize call from 763232256 to 863961088 took 1.945467010140419 msecs. Success: true
Heap resize call from 863961088 to 964689920 took 0.6675080060958862 msecs. Success: true
Heap resize call from 964689920 to 1065418752 took 1.5788139998912811 msecs. Success: true
Heap resize call from 1065418752 to 1166147584 took 3.2779290080070496 msecs. Success: true
Heap resize call from 1166147584 to 1266876416 took 2.6842510104179382 msecs. Success: true
Heap resize call from 1266876416 to 1367605248 took 3.610280990600586 msecs. Success: true
Heap resize call from 1367605248 to 1468334080 took 3.7163310050964355 msecs. Success: true
Heap resize call from 1468334080 to 1569062912 took 2.760885000228882 msecs. Success: true
Heap resize call from 1569062912 to 1669791744 took 3.910877004265785 msecs. Success: true
Heap resize call from 1669791744 to 1770520576 took 3.2484830021858215 msecs. Success: true
Heap resize call from 1770520576 to 1871249408 took 3.4929400086402893 msecs. Success: true
Heap resize call from 1871249408 to 1971978240 took 4.082751989364624 msecs. Success: true
Heap resize call from 1971978240 to 2072707072 took 3.2575770020484924 msecs. Success: true
Heap resize call from 2072707072 to 2147483648 took 3.5487619936466217 msecs. Success: true
Cannot enlarge memory, requested 2147484432 bytes, but the limit is 2147483648 bytes!
[ERROR] Failed to decode.
[ERROR] Failed to decode tile 1/1
[ERROR] opj_decompress: failed to decode tile!

If we use openjpegjs_decode.js instead, it can successfully decompress

encodedBitStream.length= 1960356
[INFO] Start to read j2k main header (0).
[INFO] Main header has been correctly decoded.
[INFO] Header of tile 1 / 1 has been read.
Decode of ./../fixtures/j2k/EE60E32E_dat.j2k took 392.496375 ms
  frameInfo =  {
  width: 1030,
  height: 1870,
  bitsPerSample: 14,
  componentCount: 1,
  isSigned: false
}
 imageOffset =  { x: 0, y: 0 }
  decoded length =  3852200

If we use dlmalloc instead of emmalloc, it can decompress without any issues with both js files.
For further information about the issue and solution see the issue and PR
We wanted to report this as we couldn't understand the root cause of why emmalloc had this problem and it is not documented as a shortcoming.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions