Как отладить ошибку сегментации Emscripten из-за превышения доступной динамической кучи - PullRequest
0 голосов
/ 09 апреля 2019

Я пытаюсь скомпилировать библиотеку с открытым исходным кодом, используя Emscripten, и после внесения нескольких незначительных изменений у меня она компилируется и запускается, но когда я пытаюсь использовать ее слишком часто, я получаю:

segmentation fault, exceeded the top of the available dynamic heap when loading 1 bytes from address 1869770797. STATICTOP=184544, DYNAMICTOP=21213184 melt.html:1246:11
exception thrown: abort("segmentation fault, exceeded the top of the available dynamic heap when loading 1 bytes from address 1869770797. STATICTOP=184544, DYNAMICTOP=21213184") at jsStackTrace@http://localhost:6931/melt.js:1603:13
stackTrace@http://localhost:6931/melt.js:1620:12
abort@http://localhost:6931/melt.js:52047:44
SAFE_HEAP_LOAD@http://localhost:6931/melt.js:926:51
_strcmp@http://localhost:6931/melt.wasm:wasm-function[912]:0x67c58

Но я действительно не думаю, что это должно использовать столько памяти? Каков наилучший способ устранения проблем с памятью, таких как Emscripten в браузере?

Кажется, я даже не могу найти точный вызов "strcmp", на котором он терпит неудачу, так как информация о стеке вроде бы отстой.

Если я скомпилирую без -s SAFE_HEAP=1, ошибка будет выглядеть следующим образом:

exception thrown: RuntimeError: index out of bounds,_strcmp@http://localhost:6931/melt.wasm:wasm-function[771]:0x34dcf
Module._strcmp@http://localhost:6931/melt.js:50463:10

Библиотека, которую я пытаюсь скомпилировать, представляет собой среду MLT (https://github.com/mltframework/mlt)

Это немного сложно, так как для загрузки большинства своих функций используется динамическое связывание - сейчас я просто пытаюсь заставить его работать с абсолютным минимумом - сам mltframework (статически связанный с исполняемым файлом), libmltcore (загружается через dlload), libmltsdl2 (загружается через dlload)

Флаги компиляции для MLT следующие (с использованием WASM = 0, но, похоже, это не имеет значения, WASM или нет):

emcc -g -s WASM=0 -dynamiclib -current_version 6.14.0 
-compatibility_version 6 
-o ../../../lib/libmlt.bc 
mlt_frame.o mlt_version.o mlt_geometry.o mlt_deque.o mlt_property.o mlt_properties.o mlt_events.o mlt_parser.o mlt_service.o mlt_producer.o mlt_multitrack.o mlt_playlist.o mlt_consumer.o mlt_filter.o mlt_transition.o mlt_field.o mlt_tractor.o mlt_factory.o mlt_repository.o mlt_pool.o mlt_tokeniser.o mlt_profile.o mlt_log.o mlt_cache.o mlt_animation.o mlt_slices.o  
-lpthread -lm

libmltcore:

emcc -g -s EXPORT_ALL=1 -s WASM=0 -s SIDE_MODULE=1 -dynamiclib 
-o ../../../../lib/mlt/libmltcore.js 
factory.o producer_colour.o producer_consumer.o producer_hold.o producer_loader.o producer_melt.o producer_noise.o producer_timewarp.o producer_tone.o filter_audiochannels.o filter_audiomap.o filter_audioconvert.o filter_audiowave.o filter_brightness.o filter_channelcopy.o filter_crop.o filter_data_feed.o filter_data_show.o filter_fieldorder.o filter_gamma.o filter_greyscale.o filter_imageconvert.o filter_luma.o filter_mirror.o filter_mono.o filter_obscure.o filter_panner.o filter_region.o filter_rescale.o filter_resize.o filter_transition.o filter_watermark.o transition_composite.o transition_luma.o transition_mix.o transition_region.o transition_matte.o consumer_multi.o consumer_null.o 
-L../../framework -lmlt -lm -lpthread

litmltsdl2:

emcc -g -s EXPORT_ALL=1 -s SIDE_MODULE=1 -s WASM=0 -dynamiclib 
-o ../../../../lib/mlt/libmltsdl2.js 
factory.o common.o consumer_sdl2.o consumer_sdl2_audio.o 
-L../../framework -lmlt -lpthread -lm -s USE_SDL=2

И, наконец, мой исполняемый файл:

emcc -g -s SAFE_HEAP=1 -s WASM=0 -s TOTAL_MEMORY=1024MB -s EXIT_RUNTIME=1 -s EXPORT_ALL=1 -s MAIN_MODULE=1 
-O2 -I$(pwd)/dist/include/mlt $(pwd)/dist/lib/libmlt.bc 
--preload-file lib/mlt 
--preload-file lib/share 
melt.c -o melt.html --pre-js melt_pre.js

Я пробовал другие флаги:

ALIASING_FUNCTION_POINTERS=0
SAFE_HEAP=1
STACK_OVERFLOW_CHECK=1
EMULATE_FUNCTION_POINTER_CASTS=1 
ASSERTIONS=2

-g4 может показаться полезным, но при сборке библиотек tt не может найти исходные файлы.

1 Ответ

0 голосов
/ 09 апреля 2019

Стоит взглянуть на полный список и описания параметров компилятора emcc . Вы поймете, что все другие упомянутые вами флаги не помогут вашему делу после прочтения описания по ссылке.

Во-первых, я уверен, что вы не можете использовать нотации MB для флага -s TOTAL_MEMORY=, поскольку, как вы можете видеть выше, флаги -s на самом деле являются JavaScript. Попробуйте вместо этого использовать простое целое число. Также -s ALLOW_MEMORY_GROWTH=1 позволит куче расти автоматически по мере необходимости.

Обратите внимание, что по умолчанию pthread недоступен в некоторых браузерах, поскольку он (точно SharedArrayBuffer) был подвержен уязвимости Meltdown, поэтому он отключен в браузерах.

...