breejs / bree

Bree is a Node.js and JavaScript job task scheduler with worker threads, cron, Date, and human syntax. Built for @ladjs, @forwardemail, @spamscanner, @cabinjs.
https://jobscheduler.net
MIT License
2.96k stars 80 forks source link

[fix] script works in main thread but fails in worker thread with FATAL ERROR or silent crash #214

Closed akakoori closed 1 year ago

akakoori commented 1 year ago

Describe the bug

Node.js version: v19.7.0

OS version: Linux version 5.4.0-1105-azure (buildd@lcy02-amd64-082) (gcc version 7.5.0 (Ubuntu 7.5.0-3ubuntu1~18.04)) #111~18.04.1-Ubuntu SMP Fri Mar 3 22:47:43 UTC 2023

Description: script works in main thread but fails in worker thread with FATAL ERROR or silent crash

Actual behavior

it sliently crashes:

0|Dingbition  | info:    Worker for job "test.mjs" online
0|Dingbition  | (node:20482) ExperimentalWarning: Importing JSON modules is an experimental feature and might change at any time
0|Dingbition  | (Use `node --trace-warnings ...` to show where the warning was created)
PM2           | App [Dingbition:0] exited with code [0] via signal [SIGSEGV]

and if add more code lines like

let accessToken = await new jose.SignJWT({ '_appId': TB_APP_ID })
        .setProtectedHeader({ alg: 'HS256' })
        .setIssuedAt()
        .setExpirationTime('2h')
        .sign(new TextEncoder().encode(TB_APP_SECRET))

then it throws error like:

0|Dingbition  | FATAL ERROR: v8::HandleScope::CreateHandle() Cannot create a handle without a HandleScope
0|Dingbition  |  1: 0xbe6ce0 node::Abort() [node /workspaces/Dingbition/app.mjs]
0|Dingbition  |  2: 0xaf27c0 node::FatalError(char const*, char const*) [node /workspaces/Dingbition/app.mjs]
0|Dingbition  |  3: 0xdc987a v8::Utils::ReportApiFailure(char const*, char const*) [node /workspaces/Dingbition/app.mjs]
0|Dingbition  |  4: 0xf65ea2 v8::internal::HandleScope::Extend(v8::internal::Isolate*) [node /workspaces/Dingbition/app.mjs]
0|Dingbition  |  5: 0x11e7424 v8::internal::JSReceiver::GetCreationContext() [node /workspaces/Dingbition/app.mjs]
0|Dingbition  |  6: 0xdd3d98 v8::Object::GetCreationContext() [node /workspaces/Dingbition/app.mjs]
0|Dingbition  |  7: 0xb252b3 node::MakeCallback(v8::Isolate*, v8::Local<v8::Object>, v8::Local<v8::Function>, int, v8::Local<v8::Value>*, node::async_context) [node /workspaces/Dingbition/app.mjs]
0|Dingbition  |  8: 0x7f72fd5b9c39 Canvas::ToBufferAsyncAfter(uv_work_s*) [/workspaces/Dingbition/node_modules/canvas/build/Release/canvas.node]
0|Dingbition  |  9: 0x178415d  [node /workspaces/Dingbition/app.mjs]
0|Dingbition  | 10: 0x1788946  [node /workspaces/Dingbition/app.mjs]
0|Dingbition  | 11: 0x179ae84  [node /workspaces/Dingbition/app.mjs]
0|Dingbition  | 12: 0x17892ae uv_run [node /workspaces/Dingbition/app.mjs]
0|Dingbition  | 13: 0xb25b5d node::SpinEventLoopInternal(node::Environment*) [node /workspaces/Dingbition/app.mjs]
0|Dingbition  | 14: 0xc2dc54 node::NodeMainInstance::Run() [node /workspaces/Dingbition/app.mjs]
0|Dingbition  | 15: 0xba042b node::LoadSnapshotDataAndRun(node::SnapshotData const**, node::InitializationResultImpl const*) [node /workspaces/Dingbition/app.mjs]
0|Dingbition  | 16: 0xba41e9 node::Start(int, char**) [node /workspaces/Dingbition/app.mjs]
0|Dingbition  | 17: 0x7f7596ba5083 __libc_start_main [/lib/x86_64-linux-gnu/libc.so.6]
0|Dingbition  | 18: 0xb23b1e _start [node /workspaces/Dingbition/app.mjs]
PM2           | App [Dingbition:0] exited with code [0] via signal [SIGABRT]

Expected behavior

works like it does in main thread

Code to reproduce

this is a test.mjs, run it as `node test.mjs' works as expected, while run it with bree in worker thread, it fails.

import { parentPort } from 'worker_threads'
import { ChartJSNodeCanvas } from 'chartjs-node-canvas'

try {
    const chartJSNodeCanvas = new ChartJSNodeCanvas({
        width: 640,
        height: 360,
        backgroundColour: 'white',
    })
    const chartConfig = {
        type: 'line',
        options: {
            scales: {
                y: {
                    min: 0,
                },
            }
        },
        data: {
            datasets: [{
                label: 'test',
                data: { '2023-04-13': 9 },
            }],
        },
    }

    const data = await chartJSNodeCanvas.renderToBuffer(chartConfig)
    console.log(data)
}
catch (error) {
    console.log(error)
}

if (parentPort) parentPort.postMessage('done')
else process.exit(0)

Checklist

titanism commented 1 year ago

This is not an issue with Bree. This is an issue with canvas library which i used by the library in your example of chartjs-node-canvas. See https://github.com/Automattic/node-canvas/issues?q=SIGSEGV.

akakoori commented 1 year ago

@titanism thank you, I've searched in the node-canvas repo but still don't know how to fix this, I know this is not your responsibility, maybe you could give me a hint? Do I have to edit the C++ source code?

nevermind, switched from node-canvas to @napi-rs/canvas, problem solved