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

Memory access out of bounds in Chrome #1384

Closed
dmondev opened this issue Mar 28, 2021 · 67 comments · Fixed by #1449
Closed

Memory access out of bounds in Chrome #1384

dmondev opened this issue Mar 28, 2021 · 67 comments · Fixed by #1449
Labels
Blocker bug Something isn't working
Milestone

Comments

@dmondev
Copy link
Contributor

dmondev commented Mar 28, 2021

I'm getting the following intermittent error running the develop version in Chrome, running from a web worker.

Chrome Version 89.0.4389.90 (Official Build) (64-bit)
Windows 10 1909 build 18363.1379

pyodide.js:406 The cause of the fatal error was:
RuntimeError: memory access out of bounds
at PyArray_IntpFromIndexSequence (:wasm-function[991]:0x737a1)
at PyArray_IntpConverter (:wasm-function[990]:0x73702)
at byn$fpcast-emu$PyArray_IntpConverter (:wasm-function[3415]:0x15bfeb)

@leopsidom
Copy link
Contributor

I can confirm this behavior for 0.17.0a2. I'm getting quite a few crashes when trying to load pandas. It seems like the dev version consumes more memory than the previous version ?

@hoodmane
Copy link
Member

I've seen this a couple of times too, but not enough times to have any idea of a pattern for when it happens. If anyone can figure out a way to reproduce it, that would be super helpful.

@hoodmane
Copy link
Member

Also it would be useful to know whether it is browser dependent, so if anyone has seen a similar crash in firefox that'd be interesting info.

@dmondev
Copy link
Contributor Author

dmondev commented Mar 28, 2021

Weirdly enough it happens less when I have dev tools open. I'll try to reproduce with a minimal setup/MRE.

@hoodmane
Copy link
Member

Thanks!

@leopsidom
Copy link
Contributor

+1 on open dev tool makes this happen less frequently. Another pattern I observe is that this seems to happen more frequently on Mac (chrome) than Windows (chrome).

@dmondev
Copy link
Contributor Author

dmondev commented Mar 29, 2021

I can now say that this happens constantly when Chrome DEV tools is NOT open.

The issue doesn't happen in Firefox.

I'm able to reproduce with the following codepen: https://codepen.io/dmondev/pen/eYgdBmm

This is as close as possible to how I'm using pyodide (in a worker, with custom namespaces).

Also, the error goes away if I remove the imports

import pandas as pd
import numpy as np

@hoodmane
Copy link
Member

@dmondev I can confirm the reproduction on my computer, thanks!

@hoodmane
Copy link
Member

Note that the problem goes away here if you import numpy before pandas. Have you tried that in your actual use case? Presumably the error just appears further down the road?

@dmondev
Copy link
Contributor Author

dmondev commented Mar 29, 2021

Done. updated the codepen with output to the document itself.

Yes, the error happens further down the road ...so dependency order issues ?

@hoodmane
Copy link
Member

It's confusing because pandas depends on numpy so by the time pandas is imported, numpy must have been imported too.

Does the error always happen inside of PyArray_IntpFromIndexSequence?

@dmondev
Copy link
Contributor Author

dmondev commented Mar 29, 2021

It app

It's confusing because pandas depends on numpy so by the time pandas is imported, numpy must have been imported too.

Does the error always happen inside of PyArray_IntpFromIndexSequence?

It appears so.
Also, I cleaned up everything that is not necessary to reproduce the issue in the codepen (https://codepen.io/dmondev/pen/eYgdBmm)

Removed pandas as well. Issue seems to be with loading numpy.

@dmondev
Copy link
Contributor Author

dmondev commented Mar 29, 2021

Additional note: Not happening in v0.17.0a1

@hoodmane
Copy link
Member

This probably originated when #887 was merged (since the bug only really has to do with numpy, loading pandas just helps to trigger it). @rth

@hoodmane
Copy link
Member

If this hypothesis is correct, the bug shouldn't appear on commit fdfc56f and should appear starting with commit d175636.

@rth
Copy link
Member

rth commented Mar 29, 2021

This probably originated when #887 was merged

I don't think that's it, since #887 is not included in 0.17.0a2.

It seems like the dev version consumes more memory than the previous version ?

@leopsidom 0.17.0a1 (or the dev version) should consume less. Doing memory snapshots in Firefox 87,

  • 0.16.1: empty REPL -> 55MB, additionally load numpy -> 115 MB (total)
  • dev version: empty REPL -> 52 MB , additionally load numpy -> 85 MB (total)

In what code did you see a memory increase?

@rth
Copy link
Member

rth commented Mar 29, 2021

Additional note: Not happening in v0.17.0a1

We might be able to git bisect it between 0.17.0a1 and 0.17.0a2 using CircleCI artifacts of commits on master, though those are only kept for a month I think (#648). Personally I am not able to reproduce with the provided codepen in Chrome 88 on Linux (with the dev tools closed).

@jmsmdy
Copy link
Contributor

jmsmdy commented Mar 29, 2021

Can confirm both codepens also crash consistently with dev tools closed on MacOS.

MacOS: Version 10.15.7 (19H524)
Chrome: Version 89.0.4389.90 (Official Build) (x86_64)

@leopsidom
Copy link
Contributor

@rth I don't think my assumption was correct now. I had the belief based on page crash info given by chrome, which I think is too general to identify the issue. But I double checked the memory on chrome. It was somewhere around 50 ~ 60MB IIRC after pandas is loaded, which should be far below the per tab memory limit (I believe it's at least GB level based on my research). So I guess the issue is due to something else.

@hoodmane
Copy link
Member

The memory limit might be lower in a webworker, though I have seen this a couple of times on the main thread.

Also, I am no longer getting either codepen to reproduce the issue, I only ever got the original version to show the error. So it seems to be pretty inconsistent.

@dmondev
Copy link
Contributor Author

dmondev commented Mar 29, 2021

I pasted the codepen twice, but it's just one. As I made a few changes to cleanup, just want to make sure we are all seeing the same thing:
https://codepen.io/dmondev/pen/eYgdBmm
image

@jmsmdy
Copy link
Contributor

jmsmdy commented Mar 29, 2021

@rth I don't think my assumption was correct now. I had the belief based on page crash info given by chrome, which I think is too general to identify the issue. But I double checked the memory on chrome. It was somewhere around 50 ~ 60MB IIRC after pandas is loaded, which should be far below the per tab memory limit (I believe it's at least GB level based on my research). So I guess the issue is due to something else.

I'm seeing higher than that in Chrome Task Manager:

Screen Shot 2021-03-29 at 2 38 59 PM

Also, Chrome sometimes groups multiple tabs per process, which could possible push the memory up.

Screen Shot 2021-03-29 at 2 47 50 PM

Googling a bit about this issue, one common cause of "memory access out of bounds" is apparently an object being garbage-collected before use. "Intp" stands for "integer pointer", which I'm guessing numpy uses for things like allowing a slice of an array to point to the same memory location as the original array. Perhaps there is some over-eager garbage collection happening?

EDIT: Possibly relevant: https://old.reddit.com/r/WebAssembly/comments/g44ldd/what_are_some_possible_causes_of_runtimeerror/fnw9kw2/

Since it happens when numpy is imported, there may be some platform tests that happen on load (e.g., "try creating such and such arrays, and depending on which ones fail, set the following parameters").

@hoodmane
Copy link
Member

hoodmane commented Mar 29, 2021

@hoodmane
Copy link
Member

I should update the fatal error handling so that it prints the current Python stack frame if possible.

@hoodmane
Copy link
Member

hoodmane commented Mar 29, 2021

Okay using _Py_DumpTraceback I managed to extract the Python traceback:

File "/lib/python3.8/site-packages/numpy/core/numerictypes.py", line 853 in <module> 
File "/lib/python3.8/site-packages/numpy/core/_internal.py", line 18 in <module>
File "/lib/python3.8/site-packages/numpy/core/__init__.py", line 35 in <module>
File "/lib/python3.8/site-packages/numpy/lib/type_check.py", line 11 in <module>
File "/lib/python3.8/site-packages/numpy/lib/__init__.py", line 8 in <module>
File "/lib/python3.8/site-packages/numpy/add_newdocs.py", line 13 in <module>
File "/lib/python3.8/site-packages/numpy/__init__.py", line 142 in <module>
File "<exec>", line 1 in <module>
File "/lib/python3.8/site-packages/pyodide/_base.py", line 270 in run_async
File "/lib/python3.8/site-packages/pyodide/_base.py", line 419 in eval_code_async
File "/lib/python3.8/asyncio/tasks.py", line 280 in __step
File "/lib/python3.8/asyncio/events.py", line 81 in _run

Links to numpy source code:
core/numerictypes.py#L853
core/_internal.py#L18
core/init.py#L35
lib/type_check.py#L11
lib/init.py#L8
add_newdocs.py#L13
init.py#L142

@hoodmane
Copy link
Member

hoodmane commented Mar 29, 2021

@jmsmdy
Copy link
Contributor

jmsmdy commented Mar 29, 2021

Looking at line 853 in numerictypes.py: https://github.com/numpy/numpy/blob/v1.15.4/numpy/core/numerictypes.py#L853

    else:
        _typestr[key] = empty((1,), key).dtype.str[1:]

we see a call to "empty", which is imported from numpy.core.multiarray (compiled from C).
Taking a look inside multiarraymodule.c, in the definition of 'array_empty' (exported as python 'empty'): https://github.com/numpy/numpy/blob/v1.15.4/numpy/core/src/multiarray/multiarraymodule.c#L1887

    if (!PyArg_ParseTupleAndKeywords(args, kwds, "O&|O&O&:empty", kwlist,
                PyArray_IntpConverter, &shape,
                PyArray_DescrConverter, &typecode,
                PyArray_OrderConverter, &order)) {
        goto fail;
    }

We see a use of PyArray_IntpConverter (in this case, it looks like it is called by this function PyArg_ParseTupleAndKeywords).

Taking a look inside conversion_utils.c, at the function PyArray_IntpConverter: https://github.com/numpy/numpy/blob/v1.15.4/numpy/core/src/multiarray/conversion_utils.c#L131

    seq->len = len;
    nd = PyArray_IntpFromIndexSequence(obj, (npy_intp *)seq->ptr, len);
    if (nd == -1 || nd != len) {

Which finally gives us our call to PyArray_IntpFromIndexSequence: https://github.com/numpy/numpy/blob/v1.15.4/numpy/core/src/multiarray/conversion_utils.c#L902

The only relevant changes I could see from 0.17.0a1 to 0.17.0a2 in numpy itself are in make_int_return_values.patch: diff here

I think this change should only affect calls to Fortran code, and in a cursory glance I don't see any of those in PyArray_IntpFromIndexSequence (but I haven't traced back every function call here, it's kind of hard to follow!).

EDIT: I see hoodmane beat me to the punch!

@hoodmane
Copy link
Member

Yeah, PyArg_ParseTupleAndKeywords will call PyArray_IntpConverter(first_argument, &shape). It considers the argument fetch to have succeeded if PyArray_IntpConverter returns 0.

@hoodmane
Copy link
Member

I opened PR #1390 to dump stack on fatal error so this will be easier in the future.

@hoodmane
Copy link
Member

I think this change should only affect calls to Fortran code, and in a cursory glance I don't see any of those in PyArray_IntpFromIndexSequence (but I haven't traced back every function call here, it's kind of hard to follow!).

@joemarshall you have any ideas about what's going on?

@rth rth added the Blocker label Apr 7, 2021
@dmondev
Copy link
Contributor Author

dmondev commented Apr 7, 2021

Thanks for the additional input @jmsmdy !

I have a way to test easily in 7df15d1

As far as I can tell there should be no relevant changes between that commit and master, so the same might apply on master.

BTW, I can no longer reproduce it when building numpy with no optimization and emscripten assertions,

diff --git a/packages/numpy/meta.yaml b/packages/numpy/meta.yaml
index 2bd617e..83d4540 100644
--- a/packages/numpy/meta.yaml
+++ b/packages/numpy/meta.yaml
@@ -22,7 +22,8 @@ source:
 
 build:
   skip_host: False
-  cflags: -include math.h -I../../config -Werror=implicit-function-declaration -Werror=mismatched-parameter-types -Werror=mismatched-return-types
+  cflags: -O0 -include math.h -I../../config -Werror=implicit-function-declaration -Werror=mismatched-parameter-types -Werror=mismatched-return-types
+  ldflags: -O0 -s ASSERTIONS=1
   post: |
     # copy the correct numpy config into the build artifacts. Otherwise scipy will try to build with the config
     # from the build computer and bad things will happen

It still fails with -O2 instead of -O3 (by default)

I'm still able to reproduce building this way.

@hoodmane
Copy link
Member

hoodmane commented Apr 10, 2021

Well I built with debug symbols using:

export EXTRA_CFLAGS="-g4"
export EXTRA_LD_FLAGS="-g4 --source-map-base=localhost:8000"
export PYODIDE_PACKAGES="numpy"
make

Following @joemarshall's advice on #1102, I made a custom server to fix up the source map urls:

import socket
import socketserver
from http.server import SimpleHTTPRequestHandler
import pathlib

alternative_bases=["cpython/build/Python-3.8.2/","src/", "build/"]
def fixup_url(path):
    if pathlib.Path("." + path).exists():
        return path
    for base in alternative_bases:
        q = pathlib.Path(base + path)
        if q.exists():
            return str(q)
    dir = list(
        pathlib.Path("packages/numpy/build/numpy-1.17.5/").glob("**" + path),
    )
    if dir:
        return str(dir[0])
    print("not found:", path)
    return path


class MyTCPServer(socketserver.TCPServer):
    def server_bind(self):
        """Use socket.SO_REUSEADDR to allow faster restart"""
        self.socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
        self.socket.bind(self.server_address)
    
class Handler(SimpleHTTPRequestHandler):
    def end_headers(self):
        # Enable Cross-Origin Resource Sharing (CORS)
        self.send_header('Access-Control-Allow-Origin', '*')
        super().end_headers()

    def do_GET(self):
        self.path = fixup_url(self.path)
        super().do_GET()


if __name__ == '__main__':
    port = 8000 
    with MyTCPServer(("", port), Handler) as httpd:
        print("Serving at: http://127.0.0.1:{}".format(port))
        httpd.serve_forever()

Using this, the source map identified that the fatal error happens on line 960:
https://github.com/numpy/numpy/blob/648fe68f79dfbad21947db4b55873703db0675c4/numpy/core/src/multiarray/conversion_utils.c#L938

            vals[i] = PyArray_PyIntAsIntp(op);
            Py_DECREF(op);
            if(vals[i] == -1) { // error happened here

@hoodmane
Copy link
Member

hoodmane commented Apr 11, 2021

Okay here's the WAT from PyArray_IntpFromIndexSequence. I added annotations cross referenced against the source code.
The debugger suggested that the error occurred on line 960, see the ====== marker for the instruction where the error occurs.

I think this shows that this is a v8 bug. A pointer is stored into $var7, a store is performed successfully into that pointer. Then a load is performed from the same pointer and v8 crashes with RuntimeError: memory access out of bounds.

 (func $PyArray_IntpFromIndexSequence (;1429;) 
    (export "PyArray_IntpFromIndexSequence") 
    (param $var0 i32) ;; seq
    (param $var1 i32) ;; vals
    (param $var2 i32) ;; maxvals, reused for op and err
    (result i32)

    (local $var3 i32) ;; i / loop variable
    (local $var4 i32) ;; return value (so sometimes nd)
    (local $var5 i32) ;; nd
    (local $var6 i32) ;; min(nd, maxvals)
    (local $var7 i32) ;; &vals[i]
    (local $var8 i32) ;; used for op->obj_refcnt (in code from Py_DECREF)
    block $label0 ;; wraps the whole body, we use jump to $label0 to return $var4
      ;; line 931
      local.get $var0 
      call $PySequence_Size 
      local.tee $var5 ;; nd 5 = PySequence_Size(seq 0)
      ;; line 932
      i32.const -1
      i32.ne
      if ;; no error occurred
        ;; line 952, computing min(nd, maxvals)
        local.get $var5
        local.get $var2
        local.get $var2
        local.get $var5
        i32.gt_s
        select 
        local.tee $var6 ;; set var6 = min(nd, maxvals)
        i32.const 0
        i32.gt_s 
        if ;; min(nd, maxvals) > 0, (otherwise loop skipped entirely)
          i32.const -1
          local.set $var4 ;; return value is -1
          loop $label2
            ;; line 953
            local.get $var0 ;; seq
            local.get $var3 ;; i (loop variable)
            call $PySequence_GetItem ;; GetItem(seq, i)
            local.tee $var2 ;; op = GetItem(seq, i) (overwrite maxvals)
            ;; line 954
            i32.eqz ;; if(op == NULL)
            ;; line 955
            br_if $label0 ;; return -1 (in $var4)
            ;; line 958, start with LHS
            local.get $var1 ;; vals
            local.get $var3 ;; i
            i32.const 2 
            i32.shl ;; i << 2
            i32.add ;; &vals[i] == vals + 4*i
            local.tee $var7 ;; v7 = &vals[i]
            ;; inlined PyArray_PyIntAsIntp here
            local.get $var2 ;; op
            ;; fetch static string "an integer is required"
            global.get $__memory_base
            i32.const 9084
            i32.add       
            call $PyArray_PyIntAsIntp_ErrMsg ;; PyArray_PyIntAsIntp_ErrMsg(o, "an integer is required")
            i32.store ;; vals[i] = PyArray_PyIntAsIntp(op)
            ;; line 959, Py_DECREF macro
            local.get $var2
            local.get $var2
            i32.load ;; op->ob_refcnt
            i32.const 1 
            i32.sub ;; 
            local.tee $var8
            i32.store ;; store back op->ob_refcnt -= 1
            local.get $var8
            i32.eqz
            if ;; if new refcount is 0, dealloc op
              local.get $var2
              call $_Py_Dealloc
            end ;; Py_DECREF is done now
            block $label1
              ;; line 960 -----------------------------------------------------------------------------------
              local.get $var7 ;; &vals[i]
              i32.load ;; vals[i]  ;; <================================== crashes here!
              i32.const -1 
              i32.ne ;; vals[i] != -1
              br_if $label1 ;; no error, continue loop 
              ;; line 961  ------------------------------------------------------------------------------------
              call $PyErr_Occurred
              local.tee $var2 ;; store err into $var2
              i32.eqz
              br_if $label1 ;; no error, continue loop
              ;; Now we know there was an error, replace overflow error message
              local.get $var2
              global.get $PyExc_OverflowError
              i32.load
              call $PyErr_GivenExceptionMatches
              i32.eqz
              br_if $label0 ;; Not an overflow error, return -1 ($var4)
              ;; An overflow error, replace error message
              ;; lines 964 / 965
              global.get $PyExc_ValueError
              i32.load
              ;; Look up static string "Maximum allowed dimension exceeded"
              global.get $__memory_base
              local.tee $var2
              i32.const 9107
              i32.add
              call $PyErr_SetString
              i32.const -1
              return
            end $label1 
            ;; Now we need to decide whether to loop again
            ;; line 952 again. increment i then test whether we are done
            local.get $var3 ;; i / loop variable
            i32.const 1 
            i32.add ;; i + 1
            local.tee $var3 ;; store back
            local.get $var6 ;; MIN(nd, maxvals)
            i32.ne ;; i != MIN(nd, maxvals)
            br_if $label2 ;; loop unless we're done (?)
          end $label2
        end
        local.get $var5 
        local.set $var4 ;; move nd from $var5 into $var4 (now that we succeeded)
        br $label0 ;; return nd (in $var4)
      end
      ;; 933 (an error occurred in PySequenceLength(seq))
      call $PyErr_Occurred
      if
        ;; line 934
        call $PyErr_Clear
      end
      ;; line 937
      ;; inlined PyArray_PyIntAsIntp again
      local.get $var1 ;; vals (used by i32.store for assign to vals[0])
      ;; fetch static string "an integer is required"
      local.get $var0 
      global.get $__memory_base
      i32.const 9084
      i32.add
      call $PyArray_PyIntAsIntp_ErrMsg
      ;; PyArray_PyIntAsIntp_ErrMsg(o, "an integer is required")
      local.tee $var2 ;; override maxvals with result
      i32.store ;; vals[0] = PyArray_PyIntAsIntp_ErrMsg(o, "an integer is required")
      i32.const 1
      ;; line 949
      local.set $var4 ;; nd = 1
      ;; line 938
      local.get $var2 ;; vals[0]
      i32.const -1
      i32.ne ;; vals[0] != -1
      br_if $label0 ;; if vals[0] != -1 return nd (in $var4)
      ;; line 939
      call $PyErr_Occurred
      local.tee $var2 ;; use $var2 as err
      ;; line 940/941
      i32.eqz ;; err == 0
      br_if $label0 ;; if(err == 0) return nd (in $var4)
      ;; Now there was an error.
      i32.const -1
      local.set $var4 ;; there was an error, we're going to return -1
      local.get $var2
      global.get $PyExc_OverflowError
      i32.load
      call $PyErr_GivenExceptionMatches ;; PyErr_GivenExceptionMatches(err, PyExc_OverflowError)
      i32.eqz 
      br_if $label0 ;; not an overflow error, return -1 (in $var4)
      ;; An overflow error, replace error message
      ;; lines 942/943
      global.get $PyExc_ValueError
      i32.load
      ;; get static string "Maximum allowed dimension exceeded"
      global.get $__memory_base
      local.tee $var2
      i32.const 9107
      i32.add
      call $PyErr_SetString
      i32.const -1
      return
    end $label0
    local.get $var4
  )

@hoodmane
Copy link
Member

I guess I'll patch numpy a bit to remove the offending load and see what happens...

@hoodmane
Copy link
Member

Okay I think I may have fixed it.

hoodmane pushed a commit to hoodmane/pyodide that referenced this issue Apr 11, 2021
@hoodmane
Copy link
Member

hoodmane commented Apr 11, 2021

If anyone is willing to build my branch in #1449 and import numpy, I'd appreciate verification that it works. It seems to fix the problem on my machine. We don't have any test coverage for this so it's a bit hard to be sure.

@hoodmane
Copy link
Member

Okay, so on my computer the version that I built locally doesn't crash but the version built on CI does crash. I wonder if it's because the CPython that I'm using locally was built with debug symbols? Very frustrating...

Here's the link to the CI build:
https://1061-322074228-gh.circle-artifacts.com/0/root/repo/build/console.html

@hoodmane
Copy link
Member

hoodmane commented Apr 11, 2021

Update: generated WASM from the CI was identical to the WASM generated from the original code without my numpy patch.

@jmsmdy
Copy link
Contributor

jmsmdy commented Apr 12, 2021

Update: generated WASM from the CI was identical to the WASM generated from the original code without my numpy patch. Maybe this is a problem with ccache?

I've had similar problems (seemingly solved by deleting everything in the numpy build folder to force recompile). I'll check if your branch fixes it for me later tonight.

@hoodmane
Copy link
Member

deleting everything in the numpy build folder to force recompile

Yup I've been doing that a lot, can never be too safe.

The problem I was having though is that
https://1061-322074228-gh.circle-artifacts.com/0/root/repo/build/console.html
loads numpy from https://cdn.jsdelivr.net/pyodide/dev/full/numpy.js, so of course it was loading the original version.
When modified to load numpy from https://1061-322074228-gh.circle-artifacts.com/0/root/repo/build/numpy.js it works for me.

I was able to load the circle-ci build from console.html using a local override for console.html replacing the cdn url with the circle-ci one. When I did this it worked for me as expected.
https://developer.chrome.com/blog/new-in-devtools-65/#overrides

With the local override I was able to avoid the CORS proxy issue they talk about here:
#648

@hoodmane
Copy link
Member

I'll check if your branch fixes it for me later tonight.

Thanks!

@jmsmdy
Copy link
Contributor

jmsmdy commented Apr 12, 2021

Ran a few tests, seems to be working!

@JackChen20200818
Copy link
Contributor

Very pleased to hear the fix!

@daoxian
Copy link
Contributor

daoxian commented Apr 15, 2021

Still have crash problem using Chrome 90.0.4430.72 in Windows with the latest master branch pyodide code. @hoodmane @jmsmdy

(I've substituded the domain name)

pyodide.js:432 Pyodide has suffered a fatal error, refresh the page. Please report this to the Pyodide maintainers.
Module.fatal_error @ pyodide.js:432
pyodide.js:433 The cause of the fatal error was:
Module.fatal_error @ pyodide.js:433
pyodide.js:434 RuntimeError: memory access out of bounds
    at PyArray_Broadcast (<anonymous>:wasm-function[1536]:0xcdab3)
    at <anonymous>:wasm-function[1538]:0xce06f
    at __static_809 (<anonymous>:wasm-function[1542]:0xce5f0)
    at byn$fpcast-emu$__static_809 (<anonymous>:wasm-function[6879]:0x219772)
    at __static_861 (https://【MY-DOMAIN】/wasm.master/pyodide.asm.wasm:wasm-function[1972]:0x22cb48)
    at byn$fpcast-emu$__static_861 (https://【MY-DOMAIN】/wasm.master/pyodide.asm.wasm:wasm-function[22302]:0x7be3ba)
    at PyObject_Call (https://【MY-DOMAIN】/wasm.master/pyodide.asm.wasm:wasm-function[763]:0x1caf37)
    at _PyEval_EvalFrameDefault (https://【MY-DOMAIN】/wasm.master/pyodide.asm.wasm:wasm-function[2758]:0x2a9d54)
    at byn$fpcast-emu$_PyEval_EvalFrameDefault (https://【MY-DOMAIN】/wasm.master/pyodide.asm.wasm:wasm-function[15507]:0x7a5f64)
    at _PyEval_EvalCodeWithName (https://【MY-DOMAIN】/wasm.master/pyodide.asm.wasm:wasm-function[2754]:0x2a422c)
Module.fatal_error @ pyodide.js:434
pyodide.asm.js:9 Stack (most recent call first):
pyodide.asm.js:9   File "/lib/python3.8/site-packages/numpy/lib/stride_tricks.py", line 191 in _broadcast_shape
pyodide.asm.js:9   File "/lib/python3.8/site-packages/numpy/lib/stride_tricks.py", line 264 in broadcast_arrays
pyodide.asm.js:9   File "<__array_function__ internals>", line 5 in broadcast_arrays
pyodide.asm.js:9   File "/lib/python3.8/site-packages/numpy/lib/function_base.py", line 4213 in meshgrid
pyodide.asm.js:9   File "<__array_function__ internals>", line 5 in meshgrid
pyodide.asm.js:9   File "/lib/python3.8/site-packages/pysot/tracker/siamrpn_tracker.py", line 73 in generate_anchor
pyodide.asm.js:9   File "/lib/python3.8/site-packages/pysot/tracker/siamrpn_tracker.py", line 54 in __init__
pyodide.asm.js:9   File "<exec>", line 8 in <module>
pyodide.asm.js:9   File "/lib/python3.8/site-packages/pyodide/_base.py", line 270 in run_async
pyodide.asm.js:9   File "/lib/python3.8/site-packages/pyodide/_base.py", line 419 in eval_code_async
pyodide.asm.js:9   File "/lib/python3.8/asyncio/tasks.py", line 280 in __step
pyodide.asm.js:9   File "/lib/python3.8/asyncio/events.py", line 81 in _run
pyodide.js:456 Uncaught RuntimeError: memory access out of bounds
    at PyArray_Broadcast (<anonymous>:wasm-function[1536]:0xcdab3)
    at <anonymous>:wasm-function[1538]:0xce06f
    at __static_809 (<anonymous>:wasm-function[1542]:0xce5f0)
    at byn$fpcast-emu$__static_809 (<anonymous>:wasm-function[6879]:0x219772)
    at __static_861 (https://【MY-DOMAIN】/wasm.master/pyodide.asm.wasm:wasm-function[1972]:0x22cb48)
    at byn$fpcast-emu$__static_861 (https://【MY-DOMAIN】/wasm.master/pyodide.asm.wasm:wasm-function[22302]:0x7be3ba)
    at PyObject_Call (https://【MY-DOMAIN】/wasm.master/pyodide.asm.wasm:wasm-function[763]:0x1caf37)
    at _PyEval_EvalFrameDefault (https://【MY-DOMAIN】/wasm.master/pyodide.asm.wasm:wasm-function[2758]:0x2a9d54)
    at byn$fpcast-emu$_PyEval_EvalFrameDefault (https://【MY-DOMAIN】/wasm.master/pyodide.asm.wasm:wasm-function[15507]:0x7a5f64)
    at _PyEval_EvalCodeWithName (https://【MY-DOMAIN】/wasm.master/pyodide.asm.wasm:wasm-function[2754]:0x2a422c)

@hoodmane
Copy link
Member

Yes, this fatal error occurs even in the benchmarks, I haven't minimized the reproduction on this one yet would appreciate it if anyone can provide a simple way to produce it.

@hoodmane hoodmane reopened this Apr 15, 2021
@hoodmane
Copy link
Member

Okay I can sometimes trigger this with

np.meshgrid(range(10), range(10))

but it's a bit inconsistent.

@daoxian
Copy link
Contributor

daoxian commented Apr 15, 2021

Okay I can sometimes trigger this with

np.meshgrid(range(10), range(10))

Correct, that's the crash point.

image

@hoodmane
Copy link
Member

Crash happens on line 1177:

it = mit->iters[j];

https://github.com/numpy/numpy/blob/648fe68f79dfbad21947db4b55873703db0675c4/numpy/core/src/multiarray/iterators.c#L1177

A bit perplexing...

@hoodmane
Copy link
Member

hoodmane commented Apr 15, 2021

Okay I'm going to close this in favor of a clean issue, since this discussion is already quite long. (#1473)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Blocker bug Something isn't working
Projects
None yet
Development

Successfully merging a pull request may close this issue.

7 participants