emscripten icon indicating copy to clipboard operation
emscripten copied to clipboard

boost/simple_segregated_storage won't work (but I can't replicate the failure)

Open conversy opened this issue 1 year ago • 2 comments

Please include the following in your bug report:

Version of emscripten/emsdk: emcc (Emscripten gcc/clang-like replacement + linker emulating GNU ld) 3.1.61-git clang version 19.0.0git Target: wasm32-unknown-emscripten Thread model: posix InstalledDir: /opt/homebrew/Cellar/emscripten/3.1.61/libexec/llvm/bin

Failing command line in full: If this is compile or link-time failure please include the full failing command along with its entire output. => it's not

Full link command and output with -v appended: Even for runtime issues it helps a lot if you can include the full link command. Adding -v to the link command will show all of the sub-commands run which can help us diagnose your issue.

brew --prefix emscripten/bin/em++ -v build/cookbook/gui/direct_manipulation/simplest/simplest.o -o build/cookbook/gui/direct_manipulation/simplest/simplest_app.html -s USE_SDL=2 -pthread -gsource-map -s USE_SDL=2 -s FULL_ES3 -s MIN_WEBGL_VERSION=2 -s MAX_WEBGL_VERSION=2 -s ASSERTIONS=2 -s NO_DISABLE_EXCEPTION_CATCHING -s ERROR_ON_UNDEFINED_SYMBOLS=1 -s PTHREAD_POOL_SIZE=5 -L../../misc/emscripten/local-install/lib -s USE_SDL=2 -pthread -gsource-map -s USE_SDL=2 -s FULL_ES3 -s MIN_WEBGL_VERSION=2 -s MAX_WEBGL_VERSION=2 -s ASSERTIONS=2 -s NO_DISABLE_EXCEPTION_CATCHING -s ERROR_ON_UNDEFINED_SYMBOLS=1 -s PTHREAD_POOL_SIZE=5 -L../../misc/emscripten/local-install/lib -L../djnn-cpp/build/lib -ldjnn-utils -ldjnn-gui -ldjnn-display -ldjnn-base -ldjnn-exec_env -ldjnn-core /opt/homebrew/Cellar/emscripten/3.1.61/libexec/llvm/bin/clang --version /opt/homebrew/Cellar/emscripten/3.1.61/libexec/llvm/bin/wasm-ld -o build/cookbook/gui/direct_manipulation/simplest/simplest_app.wasm build/cookbook/gui/direct_manipulation/simplest/simplest.o -L../../misc/emscripten/local-install/lib -L../../misc/emscripten/local-install/lib -L../djnn-cpp/build/lib ../djnn-cpp/build/lib/libdjnn-utils.a ../djnn-cpp/build/lib/libdjnn-gui.a ../djnn-cpp/build/lib/libdjnn-display.a ../djnn-cpp/build/lib/libdjnn-base.a ../djnn-cpp/build/lib/libdjnn-exec_env.a ../djnn-cpp/build/lib/libdjnn-core.a -L/opt/homebrew/Cellar/emscripten/3.1.61/libexec/cache/sysroot/lib/wasm32-emscripten /opt/homebrew/Cellar/emscripten/3.1.61/libexec/cache/sysroot/lib/wasm32-emscripten/libSDL2-mt.a /opt/homebrew/Cellar/emscripten/3.1.61/libexec/cache/sysroot/lib/wasm32-emscripten/crtbegin.o -lGL-mt-webgl2-full_es3-getprocaddr -lal -lhtml5 -lbulkmemory -lstubs-debug -lnoexit -lc-mt-debug -ldlmalloc-mt-debug -lcompiler_rt-mt -lc++-mt -lc++abi-debug-mt -lsockets-mt -mllvm -combiner-global-alias-analysis=false -mllvm -enable-emscripten-cxx-exceptions -mllvm -enable-emscripten-sjlj -mllvm -disable-lsr /var/folders/_y/mk1ljg908xj95w0059blfnxr0000gp/T/tmpld89c5idlibemscripten_js_symbols.so --import-memory --shared-memory --export=emscripten_stack_get_end --export=emscripten_stack_get_free --export=emscripten_stack_get_base --export=emscripten_stack_get_current --export=emscripten_stack_init --export=_emscripten_stack_alloc --export=_emscripten_thread_free_data --export=_emscripten_thread_crashed --export=emscripten_main_runtime_thread_id --export=emscripten_main_thread_process_queued_calls --export=_emscripten_run_on_main_thread_js --export=emscripten_stack_set_limits --export=__get_temp_ret --export=__set_temp_ret --export=__cxa_is_pointer_type --export=__cxa_can_catch --export=__cxa_increment_exception_refcount --export=__cxa_decrement_exception_refcount --export=setThrew --export=__cxa_free_exception --export=__wasm_call_ctors --export=_emscripten_tls_init --export=_emscripten_thread_init --export=_emscripten_stack_restore --export=_emscripten_thread_exit --export=__get_exception_message --export=free --export-if-defined=__start_em_asm --export-if-defined=__stop_em_asm --export-if-defined=__start_em_lib_deps --export-if-defined=__stop_em_lib_deps --export-if-defined=__start_em_js --export-if-defined=__stop_em_js --export-if-defined=main --export-if-defined=__main_argc_argv --export-if-defined=fflush --export-table -z stack-size=65536 --no-growable-memory --initial-memory=16777216 --no-entry --stack-first --table-base=1 "/opt/homebrew/opt/[email protected]/bin/python3.12" -E /opt/homebrew/Cellar/emscripten/3.1.61/libexec/tools/wasm-sourcemap.py build/cookbook/gui/direct_manipulation/simplest/simplest_app.wasm --dwarfdump=/opt/homebrew/Cellar/emscripten/3.1.61/libexec/llvm/bin/llvm-dwarfdump -o build/cookbook/gui/direct_manipulation/simplest/simplest_app.wasm.map --basepath=/Users/conversy/recherche/istar/code/djnn/smala/build/cookbook/gui/direct_manipulation/simplest /opt/homebrew/Cellar/emscripten/3.1.61/libexec/llvm/bin/llvm-objcopy build/cookbook/gui/direct_manipulation/simplest/simplest_app.wasm build/cookbook/gui/direct_manipulation/simplest/simplest_app.wasm --remove-section=.debug* --remove-section=producers /opt/homebrew/Cellar/emscripten/3.1.61/libexec/binaryen/bin/wasm-emscripten-finalize -g --dyncalls-i64 --pass-arg=legalize-js-interface-exported-helpers --check-stack-overflow --dwarf --output-source-map-url=simplest_app.wasm.map build/cookbook/gui/direct_manipulation/simplest/simplest_app.wasm -o build/cookbook/gui/direct_manipulation/simplest/simplest_app.wasm --detect-features --input-source-map=build/cookbook/gui/direct_manipulation/simplest/simplest_app.wasm.map --output-source-map=build/cookbook/gui/direct_manipulation/simplest/simplest_app.wasm.map /opt/homebrew/opt/node/bin/node /opt/homebrew/Cellar/emscripten/3.1.61/libexec/src/compiler.mjs /var/folders/_y/mk1ljg908xj95w0059blfnxr0000gp/T/tmpzgzr1wi6.json /opt/homebrew/opt/node/bin/node /opt/homebrew/Cellar/emscripten/3.1.61/libexec/tools/preprocessor.mjs /var/folders/_y/mk1ljg908xj95w0059blfnxr0000gp/T/emscripten_temp_ke3ux0zh/settings.js shell.html

Note: Where possible, please avoid attaching screen shots of code or console logs. Instead, please include them as text so that they may be copied / searched. To make code blocks more readable and syntax highlighted, please escape them with three backticks before and after, like this:

This function: https://github.com/boostorg/pool/blob/ec7da07ed13e0c61e50d945b574a12ae7ec83cf4/include/boost/pool/simple_segregated_storage.hpp#L91 seems to sometimes fail with emscripten.

    static void * & nextof(void * const ptr)
    { //! The return value is just *ptr cast to the appropriate type. ptr must not be 0. (For the sake of code readability :)
    //! As an example, let us assume that we want to truncate the free list after the first chunk.
    //! That is, we want to set *first to 0; this will result in a free list with only one entry.
    //! The normal way to do this is to first cast first to a pointer to a pointer to void,
    //! and then dereference and assign (*static_cast<void **>(first) = 0;).
    //! This can be done more easily through the use of this convenience function (nextof(first) = 0;).
    //! \returns dereferenced pointer.
      return *(static_cast<void **>(ptr));
    }

The problem is: I can't replicate the failure with this simple program (which is a simple adaptation of my real code):

//#define BOOST_POOL_VALIDATE
#include <boost/pool/simple_segregated_storage.hpp>
#include <assert.h>

//char cmap [256 * (2 * sizeof(float))];
float pool [256 * 2];

unsigned int 
allocate_coords_plain(boost::simple_segregated_storage<size_t>& alloc, size_t num)
{
    if (num%4) num += 4-num%4; // align to 4

    //auto cmap = pool;
    char* const cmap = (char*) pool;

    auto mem = (char*) alloc.malloc_n(num/4, 4 * (2 * sizeof(float)));
    assert(mem >= cmap);
 
    unsigned int result = (mem - cmap) / (2 * sizeof(float));
    return result;
}

int main()
{
    boost::simple_segregated_storage<size_t> alloc;
    alloc.add_ordered_block((float*)pool, 256 * (2 * sizeof(float)), 4 * (2 * sizeof(float)));

    for (size_t i=0; i<16; ++i) {
        auto mem = allocate_coords_plain (alloc, 4);
        printf("%d\n", mem);
    }

    return 0;
}

This simple program works with emscripten. In my real code, it returns 0.

Does someone know of any possible reason why this code would fail?

Best,

Stéphane

conversy avatar Jul 05 '24 10:07 conversy

Likely some kind of memory corruption issue. You could try ASan (-fsanitize=address).

sbc100 avatar Jul 05 '24 22:07 sbc100

@sbc100 thank you for the tip. I check with -fsanitize=address regularly.

Using regular c++, there is no problem with -fsanitize=address. With emscripten, I get an Uncaught RuntimeError: memory access out of bounds, when I try to allocate some memory from the pool...

It's in boost::simple_segregated_storage<unsigned long>::try_malloc_n(void*&, unsigned long, unsigned long) here: https://github.com/boostorg/pool/blob/ec7da07ed13e0c61e50d945b574a12ae7ec83cf4/include/boost/pool/simple_segregated_storage.hpp#L326

conversy avatar Jul 06 '24 15:07 conversy