From 6d58d9cb8d76b5f6e2930bc3a82d75aac1c48cfd Mon Sep 17 00:00:00 2001 From: Sergej Jaskiewicz Date: Thu, 10 Nov 2022 19:31:55 +0100 Subject: [PATCH] [JS] Attempt to fix OOM in Node.js But there are still segfaults, see https://github.com/nodejs/node/issues/45410 --- .../js/test/debugger/NodeJsInspectorClient.kt | 26 ++++++++++++++++++- 1 file changed, 25 insertions(+), 1 deletion(-) diff --git a/js/js.tests/test/org/jetbrains/kotlin/js/test/debugger/NodeJsInspectorClient.kt b/js/js.tests/test/org/jetbrains/kotlin/js/test/debugger/NodeJsInspectorClient.kt index 6b87f856a93..962d3f36f7a 100644 --- a/js/js.tests/test/org/jetbrains/kotlin/js/test/debugger/NodeJsInspectorClient.kt +++ b/js/js.tests/test/org/jetbrains/kotlin/js/test/debugger/NodeJsInspectorClient.kt @@ -8,6 +8,7 @@ import io.ktor.client.* import io.ktor.client.engine.cio.* import io.ktor.client.plugins.websocket.* import io.ktor.websocket.* +import kotlinx.coroutines.channels.ClosedReceiveChannelException import kotlinx.coroutines.runBlocking import kotlinx.serialization.SerializationException import kotlinx.serialization.encodeToString @@ -35,6 +36,26 @@ class NodeJsInspectorClient(val scriptPath: String, val args: List) { val context = NodeJsInspectorClientContextImpl(this@NodeJsInspectorClient) try { runWithContext(context, block) + } catch (e: ClosedReceiveChannelException) { + val nodeExitCode = try { + context.nodeProcess.exitValue() + } catch (_: IllegalThreadStateException) { + throw e + } + throw IllegalStateException(buildString { + append("Node process exited with exit code ") + append(nodeExitCode) + when (nodeExitCode) { + 134 -> { + append(" (out of memory). Consider increasing ") + append((::V8_MAX_OLD_SPACE_SIZE_MB).name) + } + 139 -> { + append(" (segmentation fault). Probably a bug in Node (see https://github.com/nodejs/node/issues/45410)") + } + } + append('.') + }, e) } finally { context.release() } @@ -97,6 +118,8 @@ class NodeJsInspectorClient(val scriptPath: String, val args: List) { private const val NODE_WS_DEBUG_URL_PREFIX = "Debugger listening on ws://" +private const val V8_MAX_OLD_SPACE_SIZE_MB = 4096 + /** * The actual implementation of the Node.js inspector client. */ @@ -104,9 +127,10 @@ private class NodeJsInspectorClientContextImpl(engine: NodeJsInspectorClient) : private val logger = Logger.getLogger(this::class.java.name) - private val nodeProcess = ProcessBuilder( + val nodeProcess: Process = ProcessBuilder( System.getProperty("javascript.engine.path.NodeJs"), "--inspect-brk=0", + "--max-old-space-size=$V8_MAX_OLD_SPACE_SIZE_MB", engine.scriptPath, *engine.args.toTypedArray() ).also {