Repository navigation
segmentation fault after 60 seconds when trying to load socket.io #232
Copy link
Copy link
Closed
Labels
bugSomething isn't workingSomething isn't working
Description
Issue type
Bug
How did you install PythonMonkey?
None
OS platform and distribution
Ubuntu 22.04
Python version (python --version)
Python 3.10.12
PythonMonkey version (pip show pythonmonkey)
main branch
Bug Description
Title
seg fault after 60 seconds on when attempting to load the browser socketio bundle into pythonmonkey!
Repro
Client Side (the place where the seg fault shows up)
client side socketio pmjs pythonmonkey code
pmjs PythonMonkey JavaScript code for the client:
client-socketio-pmjs.js
#!/usr/bin/env pmjs
const io = require('./socket.io.min.js');
const socket = io('http://localhost:3490');
console.log(socket.on);
console.log(socket.emit);
socket.onAny((eventName, ...args) => {
console.log(eventName);
console.log(args);
});
socket.on('connect', () => {
console.log('Connected to the server');
socket.emit('clientMessage', 'hello from JS client');
});
socket.on('serverMessage', (msg) => {
console.log('Message from server:', msg);
socket.disconnect();
});
socket.on('disconnect', () => {
console.log('Disconnected from the server');
});socket.io.min.js downloaded from --> https://cdn.socket.io/4.7.4/socket.io.min.js
- just use the file I send in my slack message, not sure if this is the same one.... probably is, but use the file I sent in my slack message to make sure you're 100% using the same one as me...
how to run the client
pmjs client-socketio-pmjs.js
The NodeJS SocketIO server I happen to have talking to this client
code for the nodejs socketio server
node NodeJS JavaScript code for the server
server-socketio-nodejs.js
#!/usr/bin/env node
const http = require('http');
const server = http.createServer();
const io = require('socket.io')(server, {
cors: {
origin: "*"
}
});
io.on('connection', (socket) => {
console.log('A client connected');
socket.on('clientMessage', (msg) => {
console.log('Message from client:', msg);
socket.emit('serverMessage', 'OK I GOT IT');
});
socket.on('disconnect', () => {
console.log('A client disconnected');
});
});
server.listen(3490, () => {
console.log('Server listening on port 3490');
});package.json
{
"dependencies": {
"socket.io": "^4.7.4",
"socket.io-client": "^4.7.4",
"socketio": "^1.0.0"
}
}instructions to run nodejs socketio server:
npm i
node server-socketio-nodejs.js
Refer to this slack message on the private Distributive slack which only Distributive developers have access to: https://dstrbtv.slack.com/archives/C03RNFRL4NQ/p1706703736711539
Standalone code to reproduce the issue
Put my code above,Relevant log output or backtrace
(pythonmonkey-py3.10) will@bestia:~/test/challenge-dcp-client-pm ➡ time ./client_socketio.js
[Function]
[Function: value]
Segmentation fault (core dumped)
real 1m1.459s
user 0m0.207s
sys 0m0.065sAdditional info if applicable
No response
What branch of PythonMonkey were you developing on? (If applicable)
main
Reactions are currently unavailable
Metadata
Metadata
Assignees
Labels
bugSomething isn't workingSomething isn't working
Activity
wiwichips commentedon Jan 31, 2024
@Xmader said:
xhr.open gets called but xhr.send doesn't. Seems that the connection dies somewhere between xhr.open and xhr.send.
socketio makes a check to see if withcredentials is defined as a property of xhr, and if it isn't it tries anyways! I think its still a seg fault, I don't remember - but keep that in mine ( whoever works on this )
wiwichips commentedon Feb 2, 2024
https://github.com/socketio/socket.io-client/blob/8cfea8c/dist/socket.io.js#L1385-L1387
philippedistributive commentedon Feb 8, 2024
Slack channel, Thursday February 1st:
Tom Tang (@Xmader)
9:30 AM
socketio aways says Disconnected from the server: ping timeout .
After few hours of debugging , the reason is that there's something wrong with our clearTimeout API.
https://github.com/socketio/socket.io-client/blob/8cfea8c/dist/socket.io.js#L2194-L2197 old timers don't get cancelled properly, so the connection is closed prematurely.
socket.io.js
this.clearTimeoutFn(this.pingTimeoutTimer);
this.pingTimeoutTimer = this.setTimeoutFn(function () {
_this5.onClose("ping timeout");
}, this.pingInterval + this.pingTimeout);
Tom Tang
9:41 AM
When socketio calling clearTimeout , the timeoutId argument is a double (JSVAL_TYPE_DOUBLE), so https://github.com/Distributive-Network/PythonMonkey/blob/116f600/src/internalBinding/timers.cc#L48-L53 can't work properly (I assume integer JS number is always optimized to a int32 despite JS number should be a double).
However when calling clearTimeout directly, the timeoutId argument is of correct type JSVAL_TYPE_INT32 . It's maybe another kind of optimization in SpiderMonkey.
timers.cc
if (!timeoutIdArg.isInt32()) {
return true;
}
// Retrieve the AsyncHandle by
timeoutIDmin repro:
(socket.io uses engine.io under the hood)
code at https://drive.google.com/drive/folders/1YKotvr0KTsXgXDVbMWgy-D2O6HcxSpZO
philippedistributive commentedon Feb 9, 2024
@Xmader trying the code above, I get
node eio-server.js
/home/philippe/bug232/eio-server.js:2
const server = engine.listen(3491, {});
^
TypeError: engine.listen is not a function
at Object. (/home/philippe/bug232/eio-server.js:2:23)
at Module._compile (node:internal/modules/cjs/loader:1356:14)
at Module._extensions..js (node:internal/modules/cjs/loader:1414:10)
at Module.load (node:internal/modules/cjs/loader:1197:32)
at Module._load (node:internal/modules/cjs/loader:1013:12)
at Function.executeUserEntryPoint [as runMain] (node:internal/modules/run_main:128:12)
at node:internal/main/run_main_module:28:49
Node.js v18.19.0
Indeed:
more engine.io.js | grep listen
eventlistener that will be invoked a singleEmitter.prototype.listeners = function (event) {
return !!this.listeners(event).length;
// Firefox closes the connection when the "beforeunload" event is emitted but not Chrome. This event listener
// Emit error on next tick so it can be listened to
// set up transport listeners
// Remove all listeners on the transport and on self
// listener already closed the socket
Please provide a full reproducer sample
philippedistributive commentedon Feb 12, 2024
I could repro the crash with Will's code sometimes and other times not. Stack trace is:
#0 0x0000000000076e53 in ?? ()
, argc=argc@entry=3,#1 0x00007efe8e9b26c2 in cfunction_vectorcall_NOARGS (func=0x7efe88dc92b0, args=,
nargsf=, kwnames=) at Objects/methodobject.c:486
#2 0x00007efe8ea771eb in _PyObject_VectorcallTstate (kwnames=,
nargsf=, args=, callable=0x7efe88dc92b0,
tstate=0x7efe8ed8cf18 <_PyRuntime+166328>) at ./Include/internal/pycore_call.h:92
#3 context_run (self=0x7efe88dc5ec0, args=, nargs=,
kwnames=) at Python/context.c:673
#4 0x00007efe8e9b2456 in cfunction_vectorcall_FASTCALL_KEYWORDS (func=0x7efe8937da80,
args=0x7efe88d0c928, nargsf=, kwnames=)
at Objects/methodobject.c:443
#5 0x00007efe8e905956 in do_call_core (use_tracing=, kwdict=0x0,
callargs=0x7efe88d0c910, func=0x7efe8937da80, tstate=) at Python/ceval.c:7352
#6 _PyEval_EvalFrameDefault (tstate=, frame=,
throwflag=) at Python/ceval.c:5376
#7 0x00007efe8ea5d7f4 in _PyEval_EvalFrame (throwflag=0, frame=0x7efe8ef37020,
tstate=0x7efe8ed8cf18 <_PyRuntime+166328>) at ./Include/internal/pycore_ceval.h:73
#8 _PyEval_Vector (args=0x0, argcount=0, kwnames=0x0, locals=0x7efe8e7f6b00, func=0x7efe8e7d5f80,
tstate=0x7efe8ed8cf18 <_PyRuntime+166328>) at Python/ceval.c:6434
#9 PyEval_EvalCode (co=co@entry=0x7efe8e7a4670, globals=globals@entry=0x7efe8e7f6b00,
locals=locals@entry=0x7efe8e7f6b00) at Python/ceval.c:1148
#10 0x00007efe8eaa8079 in run_eval_code_obj (locals=0x7efe8e7f6b00, globals=0x7efe8e7f6b00,
co=0x7efe8e7a4670, tstate=0x7efe8ed8cf18 <_PyRuntime+166328>) at Python/pythonrun.c:1710
#11 run_mod (mod=mod@entry=0x55a3b0cd3c28, filename=filename@entry=0x7efe8ed69a70 <_PyRuntime+21776>,
--Type for more, q to quit, c to continue without paging--
globals=globals@entry=0x7efe8e7f6b00, locals=locals@entry=0x7efe8e7f6b00, flags=flags@entry=0x7fff4f9e3b08,
arena=arena@entry=0x7efe8e71b7d0) at Python/pythonrun.c:1731
#12 0x00007efe8eaaa20f in PyRun_StringFlags (
str=str@entry=0x7efe8e773240 "import sys; from importlib import import_module; sys.argv = ['/home/philippe/.cache/pypoetry/virtualenvs/pythonmonkey-n83Wr7Le-py3.11/bin/pmjs', 'client-socketio-pmjs.js']; sys.exit(import_module('pyt"...,
start=start@entry=257, globals=0x7efe8e7f6b00, locals=0x7efe8e7f6b00, flags=flags@entry=0x7fff4f9e3b08)
at Python/pythonrun.c:1601
#13 0x00007efe8eaaa27f in PyRun_SimpleStringFlags (
command=0x7efe8e773240 "import sys; from importlib import import_module; sys.argv = ['/home/philippe/.cache/pypoetry/virtualenvs/pythonmonkey-n83Wr7Le-py3.11/bin/pmjs', 'client-socketio-pmjs.js']; sys.exit(import_module('pyt"...,
flags=flags@entry=0x7fff4f9e3b08) at Python/pythonrun.c:487
#14 0x00007efe8eaca7a3 in pymain_run_command (command=) at Modules/main.c:255
#15 pymain_run_python (exitcode=0x7fff4f9e3b00) at Modules/main.c:592
#16 Py_RunMain () at Modules/main.c:680
#17 0x00007efe8eacb3fe in pymain_main (args=0x7fff4f9e3c20) at Modules/main.c:710
#18 Py_BytesMain (argc=, argv=) at Modules/main.c:734
#19 0x00007efe8e428150 in __libc_start_call_main (main=main@entry=0x55a3af0b3060
argv=argv@entry=0x7fff4f9e3da8) at ../sysdeps/nptl/libc_start_call_main.h:58
#20 0x00007efe8e428209 in __libc_start_main_impl (main=0x55a3af0b3060 , argc=3, argv=0x7fff4f9e3da8,
init=, fini=, rtld_fini=, stack_end=0x7fff4f9e3d98)
at ../csu/libc-start.c:360
#21 0x000055a3af0b3095 in _start ()
-> so nothing obviously ours and the top item is missing
philippedistributive commentedon Feb 12, 2024
Now got:
Exception in callback JSFunctionProxy.eventLoopJobWrapper()
handle: <TimerHandle when=93467.359174243 JSFunctionProxy.eventLoopJobWrapper()>
Traceback (most recent call last):
File "/home/philippe/.pyenv/versions/3.11.7/lib/python3.11/asyncio/events.py", line 80, in _run
self._context.run(self._callback, *self._args)
pythonmonkey.SpiderMonkeyError: uncaught exception: out of memory
Do we have a memory leak?
The above exception was the direct cause of the following exception:
Traceback (most recent call last):
File "/home/philippe/.pyenv/versions/3.11.7/lib/python3.11/asyncio/events.py", line 80, in _run
self._context.run(self._callback, *self._args)
File "/home/philippe/.pyenv/versions/3.11.7/lib/python3.11/asyncio/locks.py", line 191, in set
if not fut.done():
^^^^^^^^^^
SystemError: <method 'done' of '_asyncio.Future' objects> returned a result with an exception set
philippedistributive commentedon Feb 16, 2024
looks fixed