Uncaught runtimeerror memory access out of bounds как исправить

I have successfully compiled stb_dxt, a DXT texture compressor written in C++, to emscripten and asm.js. This works wonderfully in Firefox but performance in Chrome is poor. I am therefore attempti...

@gordyr

I have successfully compiled stb_dxt, a DXT texture compressor written in C++, to emscripten and asm.js. This works wonderfully in Firefox but performance in Chrome is poor. I am therefore attempting to compile the same program to WebAssembly using the following flags:

emcc -O3 stb_dxt.cpp -o dxt.js -s DISABLE_EXCEPTION_CATCHING=1 -s NO_FILESYSTEM=1 -s EXPORTED_FUNCTIONS="['_rygCompress']" -s WASM=1 -s ALLOW_MEMORY_GROWTH=1

My Javascript glue code, which works perfectly with asm.js, needs to pass in an image ArrayBuffer like so:

    this.width = input.width;
    this.height = input.height;
    this.srcSize = input.data.length*input.data.BYTES_PER_ELEMENT;
    this.inputPtr = STB.Module._malloc(this.srcSize);
    this.outputPtr = STB.Module._malloc(Math.max(8, this.srcSize/8));

    this.inputHeap = new Uint8Array(STB.Module.HEAPU8.buffer, this.inputPtr, this.srcSize);
    this.outputHeap = new Uint8Array(STB.Module.HEAPU8.buffer, this.outputPtr, Math.max(8, this.srcSize/8));

    //set inputHeap to jpeg decoded RGBA data
    this.inputHeap.set(input.data);

As you can see I am using _malloc to allocate the memory for the passed in ArrayBuffer and also for what will be the resulting output ArrayBuffer once the program has run and compressed the texture to DXT1.

However, as soon as the first call to _malloc fires, I am getting an out of bounds memory error:

Uncaught (in promise) RuntimeError: memory access out of bounds
    at <WASM UNNAMED> (<WASM>[24]+7062)
    at Object.Module._malloc

I assume that I’m doing something wrong, any help would be greatly appreciated.

The code I am trying to compile is available here: https://github.com/nothings/stb/blob/master/stb_dxt.h

@kripken

My first guess is that wasm startup is async, and perhaps you’re calling into compiled code too early? Building with -s ASSERTIONS=1 -s SAFE_HEAP=1 might find something.

(Otherwise, all those options and that code should work identically on asm.js and wasm, nothing seems wrong there.)

@kripken

Also worth checking if -s BINARYEN_ASYNC_COMPILATION=0 changes things.

@gordyr

Thanks for the quick response, it’s nearly 1am here. I’ll give your suggestions a try in the morning and let you know how I get on.

@gordyr

@kripken — I’ve tried compiling with the flags you suggested and I now get a series of memory enlargement related errors:

Module.reallocBuffer: Attempted to grow from 16777216 bytes to 134217728 bytes, but got error: RangeError: WebAssembly.Memory.grow(): maximum memory size exceeded
Failed to grow the heap from 16777216 bytes to 134217728 bytes, not enough memory!
failed to set errno from JS
wasm-00010efe-24:3754 Uncaught (in promise) RuntimeError: memory access out of bounds
    at <WASM UNNAMED> (<WASM>[24]+7062)

I forgot to mentioned previously, but once I have compiled the program and first run it, I get the following error:

WebAssembly Instantiation: memory import 10 has no maximum limit, expected at most 4294967295

It would appear that WebAssembly has recently changed their instantiation method to require the previously optional «maximum» option to be present.

Therefore, I am manually adding this option into the resulting javascript file following compilation:

Module["wasmMemory"]=new WebAssembly.Memory({"initial":TOTAL_MEMORY/WASM_PAGE_SIZE, "maximum" : 256});

Perhaps this has something to do with it? However, my understanding was this that was only for the WebAssembly instantiation, and was not in any way related to the amount of memory that a compiled program can use, which should be grown internally as it runs.

Perhaps there have been some breaking changes recently?

@gordyr

Interestingly, if I divide the amount of memory I am trying to allocate by WebAssembly’s page size, the call to _malloc works:

var WASM_PAGE_SIZE = 65536;
this.srcSize = input.data.length * input.data.BYTES_PER_ELEMENT / WASM_PAGE_SIZE ;
this.inputPtr = STB.Module._malloc(this.srcSize);

But then of course, when I then create the Uint8Array() view and try to set the data, the buffer isn’t large enough.

Why should the _malloc call fail when I pass in the true length of the input data in bytes? (67108864)

@gordyr

I’ve managed to fix my issue by doing the following:

  1. Compiling with -s TOTAL_MEMORY=512MB
  2. Manually editing the javascript as follows:
Module["wasmMemory"]=new WebAssembly.Memory({"initial":TOTAL_MEMORY/WASM_PAGE_SIZE, "maximum" : TOTAL_MEMORY/WASM_PAGE_SIZE});

Everything then works, but sadly performance is far worse than compiling to asm.js.

  • In Firefox nightly running my program goes from 450ms in asm.js, to around 3,500ms.
  • In Chrome Canary, is goes from 1500ms to 3,800ms.

Is there anything I can do to improve this? Or is it simply down to the fact that WebAssembly isn’t optimized to the level of asm.js yet?

@kripken

The BINARYEN_MEM_MAX option might help those build issues. Although things should work without it too, so something’s gone wrong, but I don’t remember all the details here to know what offhand — this went through a few revisions.

About perf, that is very surprising. It’s just the wasm flag changed between those? Can you put up links to asm.js and wasm versions, built with --profiling, so we can reproduce? If it does reproduce, we should file bugs on browsers, although if it makes both of those browsers slower, perhaps it’s our fault in the toolchain somehow.

@GordoRank

@kripken — After a few hours of profiling and tweaking I have been able to improve on performance to the point where the WASM version is now significantly faster then the asm.js one, in Chrome. Firefox is still slightly faster when using asm.js however. Regardless, it seems that setting the input buffer in Chrome was causing a huge bottleneck for me but witching to Uint32Array views over the input ArrayBuffer made the copy far faster and solved it.

So this is great news, but still, I have to manually edit and include a maximum property in the javascript that’s output by Emscripten.

@juj

It would appear that WebAssembly has recently changed their instantiation method to require the previously optional «maximum» option to be present.

Do you have more info about this? I believe maximum should still be optional?

@gordyr

Do you have more info about this? I believe maximum should still be optional?

The only info I can give you is that without the maximum option being explicitly stated, compilation fails for me, giving a memory import 10 has no maximum limit error. The second I provide the option and set it to the same as the already present initial value, the error goes away and everything works.

This is using the latest incoming build of Emscripten… Sorry I can’t be any more help.

@kripken

Very strange. We need a full testcase to diagnose this, I think, I’m not sure where things are going wrong.

@evanw

We’re also experiencing rare errors like this sometimes at Figma, but only in Chrome (not Firefox). I logged a bug with Chrome before I found this issue.

@evanw

I finally got SAFE_HEAP working. I verified that SAFE_HEAP works by making sure *(char*)0x3FFFFFFF triggers the heap checks (in both Firefox and Chrome). I then ran Figma with SAFE_HEAP enabled and no heap checks were triggered (in both Firefox and Chrome) but Firefox loaded fine and Chrome threw «memory access out of bounds». Does this mean the bug is in Chrome and not in emscripten? Is there anything else I should try?

@kripken

I’m pretty sure it’s a Chrome bug at this point, yeah. One last thing I’d try is to build with -s DETERMINISTIC=1 which removes timing and randomness out of the picture. Also can’t hurt to add ASSERTIONS.

@evanw

ASSERTIONS was a good idea. It looks like this is the problem:

Module.reallocBuffer: Attempted to grow from 1073741824 bytes to 1342177280 bytes, but got error: RangeError: WebAssembly.Memory.grow(): maximum memory size exceeded

Firefox allows the memory to grow over 1gb while Chrome doesn’t. Figma sometimes needs more than 1gb of memory for large documents. Is the 1gb limit something that emscripten sets? Or is this a limitation of Chrome’s implementation in particular?

@evanw

I saw your comment above about BINARYEN_MEM_MAX so I tried -s BINARYEN_MEM_MAX=2147418112 but Chrome still fails to grow to 1342177280.

@kripken

Interesting. Looks like a chrome bug, emscripten doesn’t set a 1GB limit (and it wouldn’t be browser-specific in any case). Let’s maybe move the discussion back to the chromium bug tracker to make sure they see it.

@evanw

@kripken

Another thought here (not relevant to the Chrome side, so not posting in the bug there): in Chrome the allocation failed, so your app should have seen malloc/new return NULL. Does that happen properly for you, or is emscripten messing that up somehow?

@kripken

(That’s assuming you have ABORTING_MALLOC turned off, which I think is the case? Otherwise it should have called abort and halted the app.)

@evanw

The crash is actually in malloc, not in our code. The call to malloc is still executing (i.e. at the top of the call stack) when the crash occurs so it never has the chance to return null. Here’s what the stack trace looks like:

Uncaught RuntimeError: memory access out of bounds
    at <WASM UNNAMED> (<WASM>[331 (_malloc)]+4483)
    at <WASM UNNAMED> (<WASM>[703 (_malloca)]+138)
    at <WASM UNNAMED> (<WASM>[714 (operator new(unsigned int))]+9)
    at <WASM UNNAMED> (<WASM>[6072 (Codec::encodePhaseAndPropertyChanges(MultiplayerMessage const&, Fig::Message&))]+772)
    at <WASM UNNAMED> (<WASM>[6070 (Codec::toBuffer(MultiplayerMessage const&, MessageFormat))]+1135)
    at <WASM UNNAMED> (<WASM>[6069 (MultiplayerMessage::toBuffer(ImageMode, MessageFormat) const)]+197)
    ...

For what it’s worth, I did verify that we aren’t get any calls to malloc returning NULL before the crash.

@evanw

I think I’ve figured it out. We #define MALLOC_ALIGNMENT 16 before dlmalloc.cpp. This is supposed to be safe:

MALLOC_ALIGNMENT         default: (size_t)(2 * sizeof(void *))
Controls the minimum alignment for malloc'ed chunks.  It must be a
power of two and at least 8, even on machines for which smaller
alignments would suffice. It may be defined as larger than this
though. Note however that code and data structures are optimized for
the case of 8-byte alignment.

Calling malloc crashes in Chrome if we #define MALLOC_ALIGNMENT 16 but doesn’t crash if we #define MALLOC_ALIGNMENT 8 (the default). Any idea why this might be?

@evanw

Scratch that, never mind. That just lets us load the app in barely under 1gb. We still have the same problem if I make the document slightly bigger.

@kripken

Yeah, that crashing in malloc is definitely a sign of a problem in emscripten. I debugged it and found the issues, fixes and details in #5289.

@kripken

Should be fixed by that merged PR.

@Y0QIN

I’m also experiencing this error when my program runs for a few minutes in Chrome
Uncaught RuntimeError: memory access out of bounds
at wasm-function[79]:46
at wasm-function[401]:379
at wasm-function[992]:1112
at wasm-function[338]:533
at wasm-function[1253]:704
at wasm-function[748]:707
at wasm-function[1378]:245
at wasm-function[1348]:205
at wasm-function[1356]:9

@kripken

@Y0QIN — that might be a different issue, as I think the one here was fixed. To debug it, I’d start with building with -g so that stack trace is readable, and then hopefully what’s going wrong can be figured out. If not, if you can share a testcase we can debug that here.

surikov

added a commit
to surikov/riffshare
that referenced
this issue

Nov 19, 2018

@surikov

Hi, I am trying to get my Unity LEGO microgame uploaded to play.unity.com.

I can build to WebGL and it uploads the game, but when I try to play it in my browser (chrome) it gives the following error:

‘An error occured running the Unity content on this page. See your browser Javascript console for more info. the error was: Uncaught RuntimeError: memory access out of bounds.’

You can try it here for yourself: https://play.unity.com/mg/lego/web-0osz7

I thought maybe the game was too heavy so I tried stripping the whole game down until there was barely anything left, but it still gives the same error when playing the uploaded build.

Edit: stripping down the game seems to work, I think I will have to rebuild and reupload untill I hit the maximum…

The chrome console shows these errors:

Uncaught RuntimeError: memory access out of bounds
    at <anonymous>:wasm-function[39464]:0xe48aa0
    at <anonymous>:wasm-function[39463]:0xe48a33
    at <anonymous>:wasm-function[39462]:0xe489c9
    at <anonymous>:wasm-function[49594]:0x10a110c
    at <anonymous>:wasm-function[49601]:0x10a1f8f
    at <anonymous>:wasm-function[49599]:0x10a1a95
    at <anonymous>:wasm-function[49598]:0x10a181f
    at <anonymous>:wasm-function[25339]:0xb97bac
    at dynCall_iiiii (<anonymous>:wasm-function[52471]:0x111f01b)
    at Object.dynCall_iiiii (blob:https://play.unity3dusercontent.com/08f085a7-7fd5-42f4-a591-d067454a8d6a:8:463265)
    at invoke_iiiii (blob:https://play.unity3dusercontent.com/08f085a7-7fd5-42f4-a591-d067454a8d6a:8:331727)
    at <anonymous>:wasm-function[50596]:0x10c8f11
    at <anonymous>:wasm-function[50050]:0x10b0ed8
    at <anonymous>:wasm-function[4469]:0x1b7b8d
    at <anonymous>:wasm-function[4467]:0x1b7865
    at <anonymous>:wasm-function[8137]:0x2f5ff6
    at <anonymous>:wasm-function[8134]:0x2f4e18
    at <anonymous>:wasm-function[10603]:0x40081f
    at <anonymous>:wasm-function[8402]:0x3162cc
    at <anonymous>:wasm-function[10989]:0x42cea0
    at <anonymous>:wasm-function[10703]:0x40a3f0
    at <anonymous>:wasm-function[10703]:0x40a405
    at <anonymous>:wasm-function[10698]:0x409f0f
    at <anonymous>:wasm-function[10691]:0x408112
    at dynCall_v (<anonymous>:wasm-function[52485]:0x111f24d)
    at Object.dynCall_v (blob:https://play.unity3dusercontent.com/08f085a7-7fd5-42f4-a591-d067454a8d6a:8:471234)
    at browserIterationFunc (blob:https://play.unity3dusercontent.com/08f085a7-7fd5-42f4-a591-d067454a8d6a:8:166325)
    at Object.runIter (blob:https://play.unity3dusercontent.com/08f085a7-7fd5-42f4-a591-d067454a8d6a:8:169386)
    at Browser_mainLoop_runner (blob:https://play.unity3dusercontent.com/08f085a7-7fd5-42f4-a591-d067454a8d6a:8:167848)

Многие пользователи ПК во время работы с какой-либо программой могут столкнуться с «вылетом» указанной программы, и появившимся сообщением «Out of memory». Возникшая проблема может иметь множество причин, начиная от банального недостатка памяти на пользовательском ПК, и заканчивая некорректной работой с памятью какой-либо программы.

  • Причины появления дисфункции
  • Как исправить ошибку «Out of memory»
  • Заключение

Ошибка out of memory

Причины появления дисфункции

Сообщение «Out of memory» (в переводе дословно «вне памяти», или «недостаточно памяти») обычно возникает при недостатке памяти на пользовательском компьютере. В частности же, в появлении данной ошибки «виновен» следующий набор факторов:

  • Недостаток памяти RAM на вашем ПК (рабочей памяти, планки которой установлены на материнской плате вашего компьютера). Если на вашем компьютере установлен всего 1 гигабайт памяти, вы будете встречаться с описываемой ошибкой довольно часто. Нормальным же ныне считается наличие на компьютере 4 гигабайт памяти и выше;
  • Недостаток места на жёстком диске.

Когда вашему компьютеру не хватает физической R.A.M. памяти, он заимствует часть места на жёстком диске, и создаёт так называемую «виртуальную память». Система временно хранит в такой виртуальной памяти ту часть данных, которая не помещается в памяти обычной. Такие данные обычно хранятся в файле «pagefile.sys», размер которого может увеличиваться или уменьшаться в зависимости от специфики работы вашей ОС. Если на диске будет недостаточно места, файл «pagefile.sys» не сможет расти, и пользователь получит рассматриваемую ошибку.

  • При одновременном запуске на ПК большого количества программ, каждая из которых бронирует часть памяти ПК под свои задачи;
  • При запуск большого количества вкладок браузера. Веб-навигаторы уровня «Firefox» или «Google Chrome» способны занимать от 500 мегабайт до 1 гигабайта памяти под свой функционал, при этом число открытых вкладок и соответствующей обслуживающей памяти может быть ограничено системой. Специалисты Майрософт называют такую проблему «the desktop heap limitation» — «ограничение кучи рабочего стола»);
  • Некорректная работа с памятью ряда программ (наиболее часто это игровые программы);
  • Не оптимальный размер файла подкачки, с которым работает система.Планка памяти и датчик

Как исправить ошибку «Out of memory»

Для решения указанной проблемы рекомендую сделать следующее:

  1. Перезагрузите ваш ПК, и запустите требуемую программу вновь. Возможно, что проблема имеет случайный характер, и более повторяться не будет;
  2. Перед запуском нужной программы закройте другие ненужные программы (браузер, музыкальный или видео плеер, текстовый или графический редактор, мессенджер и так далее);
  3. Если проблема возникает во время серфинга в сети, закройте всё множество вкладок вашего браузера (при наличии), оставив лишь одну или две.Много открытых вкладок

Альтернативным вариантом решения проблемы является установка соответствующего фикса от Майкрософт. Или использование расширений или дополнений для браузера уровня «The Great Suspender» для «Google Chrome», хорошо работающего с ненужными вкладками браузера.

  • Добавьте оперативной памяти на ваш ПК. Если у вас на компьютере установлено 1-2 гигабайта памяти, будет оптимальным довести её объём до 4 гигабайт (а для 64-битных Виндовс 7, 8 и 10 версии рекомендую 8 и более гигабайт);Планка памяти
  • Убедитесь, что на вашем жёстком диске (или SSD) достаточно свободного места. При необходимости, освободите диск от ненужных файлов;
  • Используйте инструмент командной строки BCDEdit для изменения параметров загрузки системы. Если у вас на ПК установлена Виндовс 7 и более, запустите командную строку от имени администратора на Виндовс 7 и Виндовс 10, и в ней наберите:

bcdedit/set IncreaseUserVa 3072

И нажмите на ввод, и перезагрузите ваш ПК. Функционал данной команды позволяет выделить пользовательским приложениям 3 гигабайта оперативной памяти для работы. В некоторых системах этого может быть слишком много, потому если после ввода данной команды система начала чаще сбоить, то введите в командной строке от имени администратора:

bcdedit /set IncreaseUserVa 2560 что позволит задействовать 2,5 гигабайта вместо ранее забронированных 3.

Если ситуацию этим исправить не удалось, верните настройки на состояние по умолчанию:

bcdedit /deletevalue IncreaseUserVa

  • Увеличьте объём файла подкачки. Нажмите кнопку «Пуск», в строке поиска введите sysdm.cpl и нажмите ввод. В открывшемся окне настроек системы выберите «Дополнительно» — «Быстродействие» — «Параметры» — «Дополнительно» — «Виртуальная память» — «Изменить». Снимите галочку с опции автоматического размера, поставьте галочку на «Указать размер», и поставьте исходный размер в 8192, и максимальный в 8192. Затем выберите «Задать»;

    Окно виртуальной памяти

    Установите нужный размер файла подкачки

  • Если ошибка возникает при использовании игровой программы, перейдите в её графические настройки, и выберите их минимальные значения;
  • Произведите правильную настройку «Java». Для решения проблем с игровой программой «Майнкрафт» перейдите в Панель управления Виндовс, найдите там «Java» и запустите данную среду исполнения. Нажмите на кнопку «View», затем дважды кликните на «Runtime Parametres». Введите туда –Xms256m – Xmx3072m (или больше). Xms – это минимальное выделение ОЗУ, Xmx – максимальное. Значение Xmx рекомендуют устанавливать на процентов 70-80% от общего объёма ОЗУ. Примените изменения, и перезагрузите ваш ПК.

Заключение

Ошибка «Out of memory» может иметь множество причин, связанных как с физическим недостатком памяти на ПК, так и другими детерминантами, изложенными мной выше. Для решения проблемы советую закрыть ненужные программы (вкладки браузера) на вашем компьютере (тем самым разгрузив его память), а самым эффективным инструментом является установка дополнительной планки памяти на ПК, что в большинстве случаев поможет избавиться от ошибки на вашем компьютере.

Понравилась статья? Поделить с друзьями:
  • Uncaught in promise typeerror fullscreen error
  • Uncaught in promise error recaptcha has already been rendered in this element
  • Uncaught in promise error could not establish connection receiving end does not exist
  • Uncaught in promise error cannot access a chrome url
  • Uncaught exception twig error loader with message