Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Segfault in freeaddrinfo, memory leak in getaddrinfo #16081

Closed
tiran opened this issue Jan 21, 2022 · 3 comments · Fixed by #16085
Closed

Segfault in freeaddrinfo, memory leak in getaddrinfo #16081

tiran opened this issue Jan 21, 2022 · 3 comments · Fixed by #16085
Assignees

Comments

@tiran
Copy link
Contributor

tiran commented Jan 21, 2022

In our effort to port CPython to wasm32-emscripten I noticed an unstable test case that crashes sometimes. I was able to reduce the reproducer to socket.gethostbyname(name) in a loop. Upon further investigation with MSan I also found a memory leak in getaddrinfo that might be related to the issue.

Version of emscripten/emsdk:

emcc (Emscripten gcc/clang-like replacement + linker emulating GNU ld) 3.1.1 (1934a98e709b57d3592b8272d3f1264a72c089e4)
clang version 14.0.0 (https://github.com/llvm/llvm-project f142c45f1e494f8dbdcc1bcf14122d128ac8f3fe)
Target: wasm32-unknown-emscripten
Thread model: posix
InstalledDir: /emsdk/upstream/bin

Failing command line in full:

node --experimental-wasm-threads --experimental-wasm-bulk-memory python.js sock.py

Full link command and output with -v appended:

# emmake make LDFLAGS="-gsource-map -s SAFE_HEAP=1 -s STACK_OVERFLOW_CHECK=1 -v"
Details
/emsdk/upstream/emscripten/emcc  -gsource-map -s SAFE_HEAP=1 -s STACK_OVERFLOW_CHECK=1 -v -s ASSERTIONS=1 -s ALLOW_MEMORY_GROWTH=1 -s NODERAWFS=1 -s EXIT_RUNTIME=1 -s USE_PTHREADS -s PROXY_TO_PTHREAD -s SAFE_HEAP=1 -s STACK_OVERFLOW_CHECK=1   -o python.js Programs/python.o Modules/getbuildinfo.o Parser/token.o  Parser/pegen.o Parser/pegen_errors.o Parser/action_helpers.o Parser/parser.o Parser/string_parser.o Parser/peg_api.o Parser/myreadline.o Parser/tokenizer.o Objects/abstract.o Objects/accu.o Objects/boolobject.o Objects/bytes_methods.o Objects/bytearrayobject.o Objects/bytesobject.o Objects/call.o Objects/capsule.o Objects/cellobject.o Objects/classobject.o Objects/codeobject.o Objects/complexobject.o Objects/descrobject.o Objects/enumobject.o Objects/exceptions.o Objects/genericaliasobject.o Objects/genobject.o Objects/fileobject.o Objects/floatobject.o Objects/frameobject.o Objects/funcobject.o Objects/interpreteridobject.o Objects/iterobject.o Objects/listobject.o Objects/longobject.o Objects/dictobject.o Objects/odictobject.o Objects/memoryobject.o Objects/methodobject.o Objects/moduleobject.o Objects/namespaceobject.o Objects/object.o Objects/obmalloc.o Objects/picklebufobject.o Objects/rangeobject.o Objects/setobject.o Objects/sliceobject.o Objects/structseq.o Objects/tupleobject.o Objects/typeobject.o Objects/unicodeobject.o Objects/unicodectype.o Objects/unionobject.o Objects/weakrefobject.o Python/_warnings.o Python/Python-ast.o Python/Python-tokenize.o Python/asdl.o Python/ast.o Python/ast_opt.o Python/ast_unparse.o Python/bltinmodule.o Python/ceval.o Python/codecs.o Python/compile.o Python/context.o Python/dynamic_annotations.o Python/errors.o Python/frame.o Python/frozenmain.o Python/future.o Python/getargs.o Python/getcompiler.o Python/getcopyright.o Python/getplatform.o Python/getversion.o Python/hamt.o Python/hashtable.o Python/import.o Python/importdl.o Python/initconfig.o Python/marshal.o Python/modsupport.o Python/mysnprintf.o Python/mystrtoul.o Python/pathconfig.o Python/preconfig.o Python/pyarena.o Python/pyctype.o Python/pyfpe.o Python/pyhash.o Python/pylifecycle.o Python/pymath.o Python/pystate.o Python/pythonrun.o Python/pytime.o Python/bootstrap_hash.o Python/specialize.o Python/structmember.o Python/symtable.o Python/sysmodule.o Python/thread.o Python/traceback.o Python/getopt.o Python/pystrcmp.o Python/pystrtod.o Python/pystrhex.o Python/dtoa.o Python/formatter_unicode.o Python/fileutils.o Python/suggestions.o Python/dynload_stub.o    Modules/config.o Modules/main.o Modules/gcmodule.o Modules/arraymodule.o  Modules/_asynciomodule.o  Modules/_bisectmodule.o  Modules/_contextvarsmodule.o  Modules/_csv.o  Modules/_heapqmodule.o  Modules/_json.o  Modules/_lsprof.o Modules/rotatingtree.o  Modules/_opcode.o  Modules/_pickle.o  Modules/_queuemodule.o  Modules/_randommodule.o  Modules/_struct.o  Modules/_typingmodule.o  Modules/_zoneinfo.o  Modules/audioop.o  Modules/mathmodule.o  Modules/cmathmodule.o  Modules/_statisticsmodule.o  Modules/_datetimemodule.o  Modules/_decimal/_decimal.o  Modules/binascii.o  Modules/zlibmodule.o  Modules/md5module.o  Modules/sha1module.o  Modules/sha256module.o  Modules/sha512module.o  Modules/_sha3/sha3module.o  Modules/_blake2/blake2module.o Modules/_blake2/blake2b_impl.o Modules/_blake2/blake2s_impl.o  Modules/pyexpat.o  Modules/_elementtree.o  Modules/cjkcodecs/_codecs_cn.o  Modules/cjkcodecs/_codecs_hk.o  Modules/cjkcodecs/_codecs_iso2022.o  Modules/cjkcodecs/_codecs_jp.o  Modules/cjkcodecs/_codecs_kr.o  Modules/cjkcodecs/_codecs_tw.o  Modules/cjkcodecs/multibytecodec.o  Modules/unicodedata.o  Modules/_cryptmodule.o  Modules/mmapmodule.o  Modules/_posixsubprocess.o  Modules/resource.o  Modules/selectmodule.o  Modules/socketmodule.o  Modules/termios.o  Modules/_multiprocessing/posixshmem.o  Modules/_xxtestfuzz/_xxtestfuzz.o Modules/_xxtestfuzz/fuzzer.o  Modules/_testbuffer.o  Modules/_testinternalcapi.o  Modules/_testcapimodule.o  Modules/atexitmodule.o  Modules/faulthandler.o  Modules/posixmodule.o  Modules/signalmodule.o  Modules/_tracemalloc.o  Modules/_codecsmodule.o  Modules/_collectionsmodule.o  Modules/errnomodule.o  Modules/_io/_iomodule.o Modules/_io/iobase.o Modules/_io/fileio.o Modules/_io/bytesio.o Modules/_io/bufferedio.o Modules/_io/textio.o Modules/_io/stringio.o  Modules/itertoolsmodule.o  Modules/_sre.o  Modules/_threadmodule.o  Modules/timemodule.o  Modules/_weakref.o  Modules/_abc.o  Modules/_functoolsmodule.o  Modules/_localemodule.o  Modules/_operator.o  Modules/_stat.o  Modules/symtablemodule.o  Modules/pwdmodule.o  Modules/xxsubtype.o Python/deepfreeze/deepfreeze.o Modules/getpath.o Python/frozen.o -ldl                 -lm -lm -lm -lm -lm -lm Modules/_decimal/libmpdec/libmpdec.a -lz -lz       -lm Modules/expat/libexpat.a                                             -lm 
emcc: warning: USE_PTHREADS + ALLOW_MEMORY_GROWTH may run non-wasm code slowly, see https://github.com/WebAssembly/design/issues/1271 [-Wpthreads-mem-growth]
 "/emsdk/upstream/bin/wasm-ld" -o python.wasm Programs/python.o Modules/getbuildinfo.o Parser/token.o Parser/pegen.o Parser/pegen_errors.o Parser/action_helpers.o Parser/parser.o Parser/string_parser.o Parser/peg_api.o Parser/myreadline.o Parser/tokenizer.o Objects/abstract.o Objects/accu.o Objects/boolobject.o Objects/bytes_methods.o Objects/bytearrayobject.o Objects/bytesobject.o Objects/call.o Objects/capsule.o Objects/cellobject.o Objects/classobject.o Objects/codeobject.o Objects/complexobject.o Objects/descrobject.o Objects/enumobject.o Objects/exceptions.o Objects/genericaliasobject.o Objects/genobject.o Objects/fileobject.o Objects/floatobject.o Objects/frameobject.o Objects/funcobject.o Objects/interpreteridobject.o Objects/iterobject.o Objects/listobject.o Objects/longobject.o Objects/dictobject.o Objects/odictobject.o Objects/memoryobject.o Objects/methodobject.o Objects/moduleobject.o Objects/namespaceobject.o Objects/object.o Objects/obmalloc.o Objects/picklebufobject.o Objects/rangeobject.o Objects/setobject.o Objects/sliceobject.o Objects/structseq.o Objects/tupleobject.o Objects/typeobject.o Objects/unicodeobject.o Objects/unicodectype.o Objects/unionobject.o Objects/weakrefobject.o Python/_warnings.o Python/Python-ast.o Python/Python-tokenize.o Python/asdl.o Python/ast.o Python/ast_opt.o Python/ast_unparse.o Python/bltinmodule.o Python/ceval.o Python/codecs.o Python/compile.o Python/context.o Python/dynamic_annotations.o Python/errors.o Python/frame.o Python/frozenmain.o Python/future.o Python/getargs.o Python/getcompiler.o Python/getcopyright.o Python/getplatform.o Python/getversion.o Python/hamt.o Python/hashtable.o Python/import.o Python/importdl.o Python/initconfig.o Python/marshal.o Python/modsupport.o Python/mysnprintf.o Python/mystrtoul.o Python/pathconfig.o Python/preconfig.o Python/pyarena.o Python/pyctype.o Python/pyfpe.o Python/pyhash.o Python/pylifecycle.o Python/pymath.o Python/pystate.o Python/pythonrun.o Python/pytime.o Python/bootstrap_hash.o Python/specialize.o Python/structmember.o Python/symtable.o Python/sysmodule.o Python/thread.o Python/traceback.o Python/getopt.o Python/pystrcmp.o Python/pystrtod.o Python/pystrhex.o Python/dtoa.o Python/formatter_unicode.o Python/fileutils.o Python/suggestions.o Python/dynload_stub.o Modules/config.o Modules/main.o Modules/gcmodule.o Modules/arraymodule.o Modules/_asynciomodule.o Modules/_bisectmodule.o Modules/_contextvarsmodule.o Modules/_csv.o Modules/_heapqmodule.o Modules/_json.o Modules/_lsprof.o Modules/rotatingtree.o Modules/_opcode.o Modules/_pickle.o Modules/_queuemodule.o Modules/_randommodule.o Modules/_struct.o Modules/_typingmodule.o Modules/_zoneinfo.o Modules/audioop.o Modules/mathmodule.o Modules/cmathmodule.o Modules/_statisticsmodule.o Modules/_datetimemodule.o Modules/_decimal/_decimal.o Modules/binascii.o Modules/zlibmodule.o Modules/md5module.o Modules/sha1module.o Modules/sha256module.o Modules/sha512module.o Modules/_sha3/sha3module.o Modules/_blake2/blake2module.o Modules/_blake2/blake2b_impl.o Modules/_blake2/blake2s_impl.o Modules/pyexpat.o Modules/_elementtree.o Modules/cjkcodecs/_codecs_cn.o Modules/cjkcodecs/_codecs_hk.o Modules/cjkcodecs/_codecs_iso2022.o Modules/cjkcodecs/_codecs_jp.o Modules/cjkcodecs/_codecs_kr.o Modules/cjkcodecs/_codecs_tw.o Modules/cjkcodecs/multibytecodec.o Modules/unicodedata.o Modules/_cryptmodule.o Modules/mmapmodule.o Modules/_posixsubprocess.o Modules/resource.o Modules/selectmodule.o Modules/socketmodule.o Modules/termios.o Modules/_multiprocessing/posixshmem.o Modules/_xxtestfuzz/_xxtestfuzz.o Modules/_xxtestfuzz/fuzzer.o Modules/_testbuffer.o Modules/_testinternalcapi.o Modules/_testcapimodule.o Modules/atexitmodule.o Modules/faulthandler.o Modules/posixmodule.o Modules/signalmodule.o Modules/_tracemalloc.o Modules/_codecsmodule.o Modules/_collectionsmodule.o Modules/errnomodule.o Modules/_io/_iomodule.o Modules/_io/iobase.o Modules/_io/fileio.o Modules/_io/bytesio.o Modules/_io/bufferedio.o Modules/_io/textio.o Modules/_io/stringio.o Modules/itertoolsmodule.o Modules/_sre.o Modules/_threadmodule.o Modules/timemodule.o Modules/_weakref.o Modules/_abc.o Modules/_functoolsmodule.o Modules/_localemodule.o Modules/_operator.o Modules/_stat.o Modules/symtablemodule.o Modules/pwdmodule.o Modules/xxsubtype.o Python/deepfreeze/deepfreeze.o Modules/getpath.o Python/frozen.o Modules/_decimal/libmpdec/libmpdec.a /emsdk/upstream/emscripten/cache/sysroot/lib/wasm32-emscripten/libz.a /emsdk/upstream/emscripten/cache/sysroot/lib/wasm32-emscripten/libz.a Modules/expat/libexpat.a -L/emsdk/upstream/emscripten/cache/sysroot/lib/wasm32-emscripten /emsdk/upstream/emscripten/cache/sysroot/lib/wasm32-emscripten/crtbegin.o -lGL-mt -lal -lhtml5 -lstubs-debug -lc-mt-debug -lcompiler_rt-mt -lc++-mt-noexcept -lc++abi-mt-noexcept -ldlmalloc-mt -lc_rt-mt -lsockets-mt -mllvm -combiner-global-alias-analysis=false -mllvm -enable-emscripten-sjlj -mllvm -disable-lsr --import-undefined --import-memory --shared-memory --export-if-defined=main --export-if-defined=_emscripten_thread_init --export-if-defined=_emscripten_thread_exit --export-if-defined=emscripten_tls_init --export-if-defined=emscripten_current_thread_process_queued_calls --export-if-defined=pthread_self --export-if-defined=__start_em_asm --export-if-defined=__stop_em_asm --export-if-defined=fflush --export=sbrk --export=emscripten_stack_get_end --export=emscripten_stack_get_free --export=emscripten_stack_init --export=stackSave --export=stackRestore --export=stackAlloc --export=__wasm_call_ctors --export=__errno_location --export=emscripten_get_sbrk_ptr --export=emscripten_stack_get_base --export=emscripten_dispatch_to_thread_ --export=_emscripten_main_thread_futex --export=_emscripten_thread_free_data --export=_emscripten_allow_main_runtime_queued_calls --export=emscripten_main_browser_thread_id --export=emscripten_main_thread_process_queued_calls --export=emscripten_run_in_main_runtime_thread_js --export=emscripten_stack_set_limits --export=emscripten_sync_run_in_main_thread_2 --export=emscripten_sync_run_in_main_thread_4 --export=memalign --export=emscripten_proxy_main --export=__funcs_on_exit --export=malloc --export=free --export=_get_tzname --export=_get_daylight --export=_get_timezone --export=ntohs --export=htons --export=htonl --export=raise --export-table -z stack-size=5242880 --initial-memory=16777216 --no-entry --max-memory=2147483648 --global-base=1024
 "/usr/bin/python3" /emsdk/upstream/emscripten/tools/wasm-sourcemap.py python.wasm --dwarfdump=/emsdk/upstream/bin/llvm-dwarfdump -o python.wasm.map --basepath=/python-wasm/cpython/builddir/emscripten-node
 "/emsdk/upstream/bin/wasm-emscripten-finalize" --minimize-wasm-changes --output-source-map-url=python.wasm.map -g --dyncalls-i64 --dwarf python.wasm -o python.wasm --detect-features --input-source-map=python.wasm.map --output-source-map=python.wasm.map
 "/emsdk/node/14.18.2_64bit/bin/node" /emsdk/upstream/emscripten/src/compiler.js /tmp/tmpzxuj7f53.json
emcc:WARNING: Wasm source map won't be usable in a browser without --source-map-base
 "/emsdk/upstream/bin/wasm-opt" --strip-dwarf --safe-heap --strip-producers python.wasm -o python.wasm -g --mvp-features --enable-threads --enable-mutable-globals --enable-bulk-memory --enable-sign-ext --input-source-map=python.wasm.map --output-source-map=python.wasm.map
 "/emsdk/node/14.18.2_64bit/bin/node" /emsdk/upstream/emscripten/tools/acorn-optimizer.js /tmp/emscripten_temp_8at6r3un/python.js growableHeap
 "/emsdk/node/14.18.2_64bit/bin/node" /emsdk/upstream/emscripten/tools/acorn-optimizer.js /tmp/emscripten_temp_8at6r3un/python.js.pgrow.js safeHeap
 "/emsdk/node/14.18.2_64bit/bin/node" /emsdk/upstream/emscripten/tools/preprocessor.js /tmp/emscripten_temp_8at6r3un/settings.js worker.js --expandMacros

freeaddrinfo crash

# cat sock.py
import socket
name = socket.gethostname()
while True:
    print(socket.gethostbyname(name))

# node --experimental-wasm-threads --experimental-wasm-bulk-memory python.js sock.py 
172.29.1.0
172.29.1.0
Aborted(segmentation fault)
worker.js onmessage() captured an uncaught exception: RuntimeError: Aborted(segmentation fault)
Pthread 0x8912f8 sent an error! undefined:undefined: Aborted(segmentation fault)

/python-wasm/cpython/builddir/emscripten-node/python.js:161
   throw ex;
   ^
Error [RuntimeError]: Aborted(segmentation fault)
    at abort (eval at importScripts (/python-wasm/cpython/builddir/emscripten-node/python.worker.js:38:16), <anonymous>:1431:10)
    at segfault (eval at importScripts (/python-wasm/cpython/builddir/emscripten-node/python.worker.js:38:16), <anonymous>:785:2)
    at SAFE_HEAP_LOAD_i32_2_U_2 (<anonymous>:wasm-function[8674]:0x348d3e)
    at freeaddrinfo (<anonymous>:wasm-function[8637]:0x348772)
    at setipaddr (<anonymous>:wasm-function[5809]:0x272285)
    at socket_gethostbyname (<anonymous>:wasm-function[5814]:0x2724ae)
    at cfunction_call (<anonymous>:wasm-function[1850]:0xa9e17)
    at _PyObject_MakeTpCall (<anonymous>:wasm-function[820]:0x5748c)
    at PyObject_Vectorcall (<anonymous>:wasm-function[828]:0x57c4c)
    at _PyEval_EvalFrameDefault (<anonymous>:wasm-function[3084]:0x1510a4)
Emitted 'error' event on process instance at:
    at emitUnhandledRejectionOrErr (internal/event_target.js:579:11)
    at MessagePort.[nodejs.internal.kHybridDispatch] (internal/event_target.js:403:9)
    at MessagePort.exports.emitMessage (internal/per_context/messageport.js:18:26)
WASM dis of freeaddrinfo
# /emsdk/upstream/bin/wasm-dis python.wasm -sm python.wasm.map -o python.wat

 ;;@ ../../../../b/s/w/ir/x/w/install/emscripten/system/lib/libc/musl/src/network/freeaddrinfo.c:8:0
 (func $freeaddrinfo (param $0 i32)
  (local $1 i32)
  (local $2 i32)
  (local $3 i32)
  (local.set $1
   (i32.const 1)
  )
  (loop $label$1
   ;;@ ../../../../b/s/w/ir/x/w/install/emscripten/system/lib/libc/musl/src/network/freeaddrinfo.c:10:28
   (local.set $1
    (i32.add
     (local.tee $2
      (local.get $1)
     )
     (i32.const 1)
    )
   )
   (br_if $label$1
    (local.tee $0
     (call $SAFE_HEAP_LOAD_i32_4_4
      (local.tee $3
       (local.get $0)
      )
      (i32.const 28)
     )
    )
   )
  )
  ;;@ ../../../../b/s/w/ir/x/w/install/emscripten/system/lib/libc/musl/src/network/freeaddrinfo.c:13:1
  (call $__lock
   (local.tee $3
    (i32.add
     ;;@ ../../../../b/s/w/ir/x/w/install/emscripten/system/lib/libc/musl/src/network/freeaddrinfo.c:12:3
     (local.tee $0
      (i32.add
       ;;@ ../../../../b/s/w/ir/x/w/install/emscripten/system/lib/libc/musl/src/network/freeaddrinfo.c:10:1
       (local.get $3)
       ;;@ ../../../../b/s/w/ir/x/w/install/emscripten/system/lib/libc/musl/src/network/freeaddrinfo.c:12:3
       (i32.mul
        ;;@ ../../../../b/s/w/ir/x/w/install/emscripten/system/lib/libc/musl/src/network/freeaddrinfo.c:12:9
        (i32.sub
         ;;@ ../../../../b/s/w/ir/x/w/install/emscripten/system/lib/libc/musl/src/network/freeaddrinfo.c:10:1
         (i32.const 0)
         ;;@ ../../../../b/s/w/ir/x/w/install/emscripten/system/lib/libc/musl/src/network/freeaddrinfo.c:12:9
         (call $SAFE_HEAP_LOAD_i32_2_2
          (local.get $3)
          (i32.const 64)
         )
        )
        ;;@ ../../../../b/s/w/ir/x/w/install/emscripten/system/lib/libc/musl/src/network/freeaddrinfo.c:12:3
        (i32.const 68)
       )
      )
     )
     ;;@ ../../../../b/s/w/ir/x/w/install/emscripten/system/lib/libc/musl/src/network/freeaddrinfo.c:13:1
     (i32.const 60)
    )
   )
  )
  ;;@ ../../../../b/s/w/ir/x/w/install/emscripten/system/lib/libc/musl/src/network/freeaddrinfo.c:14:14
  (call $SAFE_HEAP_STORE_i32_2_2
   (local.get $0)
   (i32.const 66)
   (local.tee $1
    (i32.sub
     (call $SAFE_HEAP_LOAD_i32_2_U_2
      (local.get $0)
      (i32.const 66)
     )
     (local.get $2)
    )
   )
  )
  (block $label$2
   (br_if $label$2
    (i32.and
     (local.get $1)
     (i32.const 65535)
    )
   )
   ;;@ ../../../../b/s/w/ir/x/w/install/emscripten/system/lib/libc/musl/src/network/freeaddrinfo.c:14:23
   (call $dlfree
    (local.get $0)
   )
   ;;@ ../../../../b/s/w/ir/x/w/install/emscripten/system/lib/libc/musl/src/network/freeaddrinfo.c:16:0
   (return)
  )
  ;;@ ../../../../b/s/w/ir/x/w/install/emscripten/system/lib/libc/musl/src/network/freeaddrinfo.c:15:6
  (call $__unlock
   (local.get $3)
  )
  ;;@ ../../../../b/s/w/ir/x/w/install/emscripten/system/lib/libc/musl/src/network/freeaddrinfo.c:16:0
 )

If I understand the assembly code correctly, then the crash is caused by deref of b->ref on line 14 of github.com/emscripten-core/emscripten/blob/3.1.1/system/lib/libc/musl/src/network/freeaddrinfo.c#L14 . I think there is a mismatch between JS allocaddrinfo and MUSL freeaddrinfo struct aibuf.

getaddrinfo memory leak

#define _POSIX_C_SOURCE 200112L

#include <string.h>
#include <stdio.h>
#include <arpa/inet.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netdb.h>
#include <unistd.h>

int main(void)
{
    struct addrinfo hints, *res;
    struct sockaddr_in *addr;
    int i, error;

    memset(&hints, 0, sizeof(hints));
    hints.ai_family = AF_UNSPEC;

    for (i=0; i < 10000; i++) {
        char host[1024];
        char out[16];
        
        error = gethostname(host, (int)sizeof(host) -1);
        if (error < 0) {
            fprintf(stderr, "gethostname\n");
            return -1;
        }
        
        error = getaddrinfo(host, NULL, &hints, &res);
        if (error) {
            fprintf(stderr, "%s\n", gai_strerror(error));
            return -1;
        }
        addr = (struct sockaddr_in *)res->ai_addr;
        inet_ntop(AF_INET, &addr->sin_addr, out, sizeof(out));
        fprintf(stdout, "addr: %s\n", out);
        freeaddrinfo(res);
    }

    return 0;
}
# emcc -s ASSERTIONS=1 -s ALLOW_MEMORY_GROWTH=1 -s NODERAWFS=1 -s EXIT_RUNTIME=1 -s USE_PTHREADS -s PROXY_TO_PTHREAD -fsanitize=address -gsource-map -o addrtest.js addrtest.c
# node --experimental-wasm-threads --experimental-wasm-bulk-memory addrtest.js
...
Direct leak of 319968 byte(s) in 9999 object(s) allocated from:
    #0 0x1f21d in malloc ../../../b/s/w/ir/x/w/install/emscripten/system/lib/compiler-rt/lib/asan/asan_malloc_linux.cpp:129:3
    #1 0x80000578  (JavaScript+0x578)
    #2 0x8000194c in allocaddrinfo /python-wasm/cpython/builddir/addrtest.js:6476:8
    #3 0x800019bb in _getaddrinfo /python-wasm/cpython/builddir/addrtest.js:6587:7
    #4 0x800015f5 in _emscripten_receive_on_main_thread_js /python-wasm/cpython/builddir/addrtest.js:5621:14
    #5 0xba67 in _do_call ../../../b/s/w/ir/x/w/install/emscripten/system/lib/pthread/library_pthread.c:207:86
    #6 0xad3f in emscripten_current_thread_process_queued_calls ../../../b/s/w/ir/x/w/install/emscripten/system/lib/pthread/library_pthread.c:637:5
    #7 0xe603 in emscripten_main_thread_process_queued_calls ../../../b/s/w/ir/x/w/install/emscripten/system/lib/pthread/library_pthread.c:661:3

Indirect leak of 159984 byte(s) in 9999 object(s) allocated from:
    #0 0x1f21d in malloc ../../../b/s/w/ir/x/w/install/emscripten/system/lib/compiler-rt/lib/asan/asan_malloc_linux.cpp:129:3
    #1 0x80000578  (JavaScript+0x578)
    #2 0x80001949 in allocaddrinfo /python-wasm/cpython/builddir/addrtest.js:6473:8
    #3 0x800019bb in _getaddrinfo /python-wasm/cpython/builddir/addrtest.js:6587:7
    #4 0x800015f5 in _emscripten_receive_on_main_thread_js /python-wasm/cpython/builddir/addrtest.js:5621:14
    #5 0xba67 in _do_call ../../../b/s/w/ir/x/w/install/emscripten/system/lib/pthread/library_pthread.c:207:86
    #6 0xad3f in emscripten_current_thread_process_queued_calls ../../../b/s/w/ir/x/w/install/emscripten/system/lib/pthread/library_pthread.c:637:5
    #7 0xe603 in emscripten_main_thread_process_queued_calls ../../../b/s/w/ir/x/w/install/emscripten/system/lib/pthread/library_pthread.c:661:3
@kripken
Copy link
Member

kripken commented Jan 21, 2022

Thannks @tiran !

#16085 fixes the leak. I think it might fix the segfault as well, as there seems to have been a memory corruption issue that that PR now fixes. I don't see a testcase for the segfault, can you test that please?

kripken added a commit that referenced this issue Jan 21, 2022
It is risky to allocate in JS and free in C, when given matching allocate/free
pairs like getaddrinfo/freeaddrinfo, and it looks like we had things wrong
here. That is, the existing musl code did not match how we use that
structure. The worst part is that musl appears to assume the struct is
identical/can alias some other struct, and that led to memory corruption.

Not sure if we can test this reliably as the issue is corruption.

Fixes #16081
@tiran
Copy link
Contributor Author

tiran commented Jan 22, 2022

I patched /emsdk/upstream/emscripten/system/lib/libc/musl/src/network/freeaddrinfo.c, removed /emsdk/upstream/emscripten/cache/sysroot/lib/wasm32-emscripten/*.a, and rebuilt CPython with patched freeaddrinfo. The segfault is gone and socket.gethostbyname() no longer crashes. Good work!

@kripken
Copy link
Member

kripken commented Jan 25, 2022

Great, thanks for verifying @tiran !

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants