oven-sh / bun

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

Weird behaviour on SIGINT when using `cc` from `bun:ffi` #14043

Open sadkebab opened 2 days ago

sadkebab commented 2 days ago

What version of Bun is running?

1.1.28-canary.3+866a6d918

What platform is your computer?

Darwin 22.3.0 arm64 arm

What steps can reproduce the bug?

  1. Create a c file with a function to be imported in JS in a file called test.c
    
    #include <stdio.h>
    #include <stdlib.h>

int myFn() { return 1; }

2. Compile the file in JS with the `cc` function in a file called c.js
```js
import { cc } from "bun:ffi";

const {
  symbols: { myFn },
} = cc({
  source: "./test.c",
  symbols: {
    myFn: {
      returns: "int",
      rags: [],
    },
  },
});

export { myFn };
  1. Make a index.js file that does nothing for few seconds
    
    function sleep(ms) {
    return new Promise((resolve) => setTimeout(resolve, ms));
    }

console.log("start"); await sleep(10000); console.log("end");

4. Run it with `bun run index.js` and press `ctrl+C` to send a SIGINT, the process will be terminated as expected
5. Import `myFn` from `c.js` in index.js, even without ever calling it
```js
import { myFn } from "./c.js";

function sleep(ms) {
  return new Promise((resolve) => setTimeout(resolve, ms));
}

console.log("start");
await sleep(10000);
console.log("end");
  1. Run it with bun run index.js and press ctrl+C to send a SIGINT, the execution will stop because "end" won't get printed but the process won't be terminated and it will start eating all the CPU power

    Screenshot 2024-09-19 at 15 23 29
  2. If you add a handler on SIGINT it will be handled correctly and execution will stop if process.exit is called

    
    import { myFn } from "./c.js";

process.on("SIGINT", async () => { process.exit(0); });

function sleep(ms) { return new Promise((resolve) => setTimeout(resolve, ms)); }

console.log("start"); await sleep(10000); console.log("end");



### What is the expected behavior?

The process should have been terminated even without a handler on SIGINT, as it does when `myFn` is not imported in the index file.

### What do you see instead?

Importing a function created with `cc` will cause weird behaviours on SIGINT

### Additional information

This behaviour happens only in the current canary revision, in the stable version it works as expected.
Jarred-Sumner commented 1 day ago

interesting

i wonder if #include <stdin.h> has a side effect here causing this

sadkebab commented 1 day ago

I didn't include stdin.h in the file tho.

I tried removing the headers in the C file (since they are not needed for my example) but the behaviour stays the same. And as I stated in the issue description this behaviour was not present in v1.1.28, it only happened in canary and now that v1.1.29 has been released it is in the stable version too.