emscripten-core / emscripten-core/emscripten

memory alignment issue that only occurs with specific buffer sizes (image dimensions) and results in leaks

Open
#14,459 42 comments 1 reaction 0 assignees View on GitHub
Dominant language
C++
Stars
27.6k
Forks
3.6k
Avg merge
1d 1h
Merged PRs (30d)
105

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
```

**repeat**edly 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 dimension**s** both work and **deallocate just fine**; calling the function with such *good* dimensions do **NOT** keep triggering the above `memalign` `⋯` **repeat**edly.

The behavior persists across

- multiple browsers: Chrome `91.0.4472.77`, Firefox `89.0`
- multiple versions of the compiled project: `4505`, `4542`, `4543`
- multiple versions of emscripten: `2.0.20`, `2.0.24`
https://github.com/paulo-coutinho/pdfium-lib/commit/d4a08e866b4fe6573447548c863d4dae4050cb18#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 🕵🏻‍♂️

https://github.com/paulo-coutinho/pdfium-lib/issues/33#issuecomment-861669272
[paulo-coutinho/pdfium-lib/blob/master/modules/wasm.py](https://github.com/paulo-coutinho/pdfium-lib/blob/master/modules/wasm.py) (how the project uses `emscripten`)

## Single-line Reproduction 🔬

1. Go to https://pdfviewer.github.io/
2. Open developer console F12
3. Evaluate the following in the console:

```js
_PDFium_Init();
```

4. Evaluate the following line several times and watch the memory grow:

```js
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 × 4memalign 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
```

![image](https://user-images.githubusercontent.com/27027/122157523-f0cfad80-cea5-11eb-9e58-eb07a8ad41ee.png)

5. Note that this one is totally fine and does not leak:

```js
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 🕵🏻‍♂️

https://github.com/paulo-coutinho/pdfium-lib/issues/33#issuecomment-861669272
[paulo-coutinho/pdfium-lib/blob/master/modules/wasm.py](https://github.com/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#799
- `pdfium::MakeRetain` – https://pdfium.googlesource.com/pdfium/+/refs/heads/chromium/4542/core/fxcrt/retain_ptr.h#174
- `CFX_DIBitmap::Create` – https://pdfium.googlesource.com/pdfium/+/refs/heads/chromium/4542/core/fxge/dib/cfx_dibitmap.cpp#27
- `FX_TryAlloc` – https://pdfium.googlesource.com/pdfium/+/refs/heads/chromium/4542/core/fxcrt/fx_memory.h#48
- `Calloc` – https://pdfium.googlesource.com/pdfium/+/refs/heads/chromium/4542/core/fxcrt/fx_memory.cpp#109
- `PartitionAllocGenericFlags` – https://pdfium.googlesource.com/pdfium/+/refs/heads/chromium/4542/third_party/base/allocator/partition_allocator/partition_alloc.h#394
- `PartitionAllocatorGeneric` – https://pdfium.googlesource.com/pdfium/+/refs/heads/chromium/4542/third_party/base/allocator/partition_allocator/partition_alloc.h#517

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.