oven-sh / bun

Incredibly fast JavaScript runtime, bundler, test runner, and package manager – all in one
https://bun.sh
Other
73.28k stars 2.69k forks source link

JSC possibly native FFI-related fatal runtime crash #9054

Open Zekiah-A opened 7 months ago

Zekiah-A commented 7 months ago

What version of Bun is running?

1.0.28+705638470

What platform is your computer?

Linux 6.2.0-34-generic x86_64 x86_64

What steps can reproduce the bug?

The issue is likely related with FFI, as only when running this FFI related program does it occur. I have provided a ZIP for convenience that contains a reproducible setup, which is just the code from this directory of a public repository plus an extra script to run the test.

Reproducible build zip: zcaptcha.zip

If you are not comfortable with using the zip, I have provided the additional script needed alongside the code from that repository to reproduce this bug below.

test-bun-runtime-crash.js

// bun run test-bun-runtime-crash.js
import * as zcaptcha from './server.js'

zcaptcha.init()
let currentCaptcha = zcaptcha.genTextCaptcha

for (let i = 0; i < 1000; i++)
{
    // This should return { answer: string, dummies: string, data: ArrayBuffer /* image data */ }
    const result = currentCaptcha()
}

What is the expected behavior?

No IOT instruction (core dumped) crash

What do you see instead?

My live server running this software is using Ubuntu 23.04 x86_64, 6.2.0-34-generic kernel, and gives the following output:

Full crash output of the program: https://gist.github.com/Zekiah-A/2130eef5984a842bf80ced38d5fa1ab0

image

I have confirmed this with my minimal reproduction build on my Arch Linux machine, running bun 1.0.28+705638470, Linux 6.7.1-arch1-1 x86_64 and got an identical result as to that on the Ubuntu server, suggesting that this is not an isolated incident. image

Additional information

No response

Zekiah-A commented 5 months ago

Update: I found a workaround to this runtime crash which might narrow down the root cause of the issue. It turns out that instead of using read.pointer to read the pointer from the returned struct, if you use read.i64 somehow the error completely disappears and everything works as expected. Here is the code change required in server.js

server.js

/*... line 44*/
function decodeGenResult(genResult) {
    // Read these two char* fields in the struct as BigInts with read.i64 instead of
    // using read.ptr (both types should be 8 bytes anyway right?)
    const answerPtr = read.i64(genResult, 0)
    const dummiesPtr = read.i64(genResult, 8)
    // Cast the BigInt back to a Number before passing it into CString to get a string
    const answerStr = new CString(Number(answerPtr))
    const dummiesStr = new CString(Number(dummiesPtr))
    // Same case with this pointer to PNG image data
    const imgPtr = read.i64(genResult, 16)
    const imgLen = read.u32(genResult, 24)
    const imageData = copy(toArrayBuffer(Number(imgPtr), 0, imgLen) 

    return { answer: answerStr.toString(), dummies: dummiesStr.toString(), data: imageData }
}
/*...*/

image

I am still not sure what the internal problem could be that causes reading as i64, or really the same struct fields as any other type (within bounds) to work perfectly fine, with only read.ptr causing the massive runtime crash, but perhaps this helps?