Description
In a project compiled with emscripten
(em++
) to WASM, calls to a function with some image dimensions keep triggering
memalign memset free
memalign memset free
memalign memset
repeatedly on every function call. When the function eventually returns a memory reference, this works as expected when probed with image-related functions for height, width, etc. BUT it cannot be deallocated and leak completely.
Other image dimensions both work and deallocate just fine; calling the function with such good dimensions do NOT keep triggering the above memalign
⋯
repeatedly.
The behavior persists across
- multiple browsers: Chrome
91.0.4472.77
, Firefox89.0
- multiple versions of the compiled project:
4505
,4542
,4543
- multiple versions of emscripten:
2.0.20
,2.0.24
paulocoutinhox/pdfium-lib@d4a08e8#diff-120a286a77ddf1bc450cb5703c08c05422275bc73616e5a359eb245ec9a923bdL68
Please
- see the attached screenshot first, under the Single-line Reproduction section right below
- and toggle open the collapsed sections marked with 👉🏻👈🏻 for details.
Investigation Details 🕵🏻♂️
paulocoutinhox/pdfium-lib#33 (comment)
paulo-coutinho/pdfium-lib/blob/master/modules/wasm.py (how the project uses emscripten
)
Single-line Reproduction 🔬
- Go to https://pdfviewer.github.io/
- Open developer console F12
- Evaluate the following in the console:
_PDFium_Init();
- Evaluate the following line several times and watch the memory grow:
var w = 496, h = 496; for (let i = 0; i < 5; i++) _FPDFBitmap_Destroy(FPDF.Bitmap_CreateEx(w, h, 4)); [ wasmMemory, wasmMemory.buffer.byteLength ] // ❌
👉🏻 496
× 496
× 4
❌ memalign
⋯
trigger on each iteration 👈🏻 (CLICK/TAP HERE TO REVIEW EXECUTION)
CreateEx
memalign memset free
memalign memset free
memalign memset
Destroy
CreateEx
memalign memset free
memalign memset free
memalign memset
Destroy
CreateEx
memalign memset free
memalign memset free
memalign memset
Destroy
CreateEx
memalign memset free
memalign memset free
memalign memset
Destroy
CreateEx
memalign memset free
memalign memset free
memalign memset
Destroy
- Note that this one is totally fine and does not leak:
var w = 495, h = 495; for (let i = 0; i < 5; i++) _FPDFBitmap_Destroy(FPDF.Bitmap_CreateEx(w, h, 4)); [ wasmMemory, wasmMemory.buffer.byteLength ] // ✔️
👉🏻 496
× 496
× 4
✔️ memalign
⋯
trigger only once 👈🏻 (CLICK/TAP HERE TO REVIEW EXECUTION)
CreateEx
memalign memset free
memalign memset free
memalign memset
Destroy
CreateEx
Destroy
CreateEx
Destroy
CreateEx
Destroy
CreateEx
Destroy
I kindly ask emscripten
experts for their help in finding how to compile the said project in a way that resolves this issue.
Investigation Details 🕵🏻♂️
paulocoutinhox/pdfium-lib#33 (comment)
paulo-coutinho/pdfium-lib/blob/master/modules/wasm.py (how the project uses emscripten
)
FPDFBitmap_CreateEx
call tree
FPDFBitmap_CreateEx
– https://pdfium.googlesource.com/pdfium/+/refs/heads/chromium/4542/fpdfsdk/fpdf_view.cpp#799pdfium::MakeRetain
– https://pdfium.googlesource.com/pdfium/+/refs/heads/chromium/4542/core/fxcrt/retain_ptr.h#174CFX_DIBitmap::Create
– https://pdfium.googlesource.com/pdfium/+/refs/heads/chromium/4542/core/fxge/dib/cfx_dibitmap.cpp#27FX_TryAlloc
– https://pdfium.googlesource.com/pdfium/+/refs/heads/chromium/4542/core/fxcrt/fx_memory.h#48Calloc
– https://pdfium.googlesource.com/pdfium/+/refs/heads/chromium/4542/core/fxcrt/fx_memory.cpp#109PartitionAllocGenericFlags
– https://pdfium.googlesource.com/pdfium/+/refs/heads/chromium/4542/third_party/base/allocator/partition_allocator/partition_alloc.h#394PartitionAllocatorGeneric
– https://pdfium.googlesource.com/pdfium/+/refs/heads/chromium/4542/third_party/base/allocator/partition_allocator/partition_alloc.h#517