Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Segfault caused by macro oddities #1257

Closed
Validark opened this issue Sep 20, 2022 · 1 comment
Closed

Segfault caused by macro oddities #1257

Validark opened this issue Sep 20, 2022 · 1 comment
Labels
bug Something isn't working crash An issue that could cause a crash

Comments

@Validark
Copy link
Contributor

Validark commented Sep 20, 2022

Version

0.1.13

Platform

Linux 5be22774b6dc 5.19.0-76051900-generic #202207312230~1660780566~22.04~9d60db1 SMP PREEMPT_DYNAMIC Thu A x86_64 x86_64 x86_64 GNU/Linux

What steps will reproduce the bug?

This only happens on some runs, so one has to run bun dev and spam F5 to get the segfault.

bun create blank ./_new_test

src/index.js:

// import { graphql } from 'react-relay';

// graphql(['a', 'b']);
console.log("Hello via Bun!");

const a = { a: 1, b: 2, c: 3, d: 4, e: 5 }.b;
// console.log(a.b)

const date = new Date(1996, 8, 1, 0, 0, 0, 0).toUTCString();
const realDate = new Date(date).toISOString();

console.log(date)

console.log(typeof process.env.QUIET3, `"${process.env.QUIET3}"`);
console.log(typeof !process.env.QUIET3, !process.env.QUIET3);
console.log(typeof !!!!process.env.QUIET, !!!!process.env.QUIET);
console.log(typeof process.env.QUIET, `"${process.env.QUIET}"`);
console.log(typeof process.env.bagel, process.env.bagel);
console.log(typeof process.env.donut, process.env.donut);
console.log(typeof process.env.pie, process.env.pie);
console.log(typeof process.env.pie2, process.env.pie2);
console.log(typeof process.env.pie3, process.env.pie3);
console.log(typeof process.env.pie4, process.env.pie4);
// console.log(typeof process.env.pie5, process.env.pie5);
const k = 0.1.toString();
console.log(k)
const { bagel: bagelboi } = process.env;
const { env: { QUIET } } = process
console.log(QUIET)
const b = JSON.parse('{"a":1,"b":2,"c":3,"d":4}');
console.log(b.c);
process.env.pie5.b;

Make a bunfig.toml file:

# Set a default framework to use
# By default, bun will look for an npm package like `bun-framework-${framework}`, followed by `${framework}`

macros.react-relay.graphql = "bun-macro-relay"
macros.relay-runtime.graphql = "bun-macro-relay"

[define]
# Replace any usage of "process.env.bagel" with the string `lox`.
# The values are parsed as JSON, except single-quoted strings are supported and `'undefined'` becomes `undefined` in JS.
# This will probably change in a future release to be just regular TOML instead. It is a holdover from the CLI argument parsing.
"process.env.bagel" = "'lox'"
"process.env.donut" = "[1, 2]"
"process.env.pie" = "null"
"process.env.pie2" = 'noob'
"process.env.pie3" = '"noob"'
"process.env.pie4" = '`${noob}`'
"process.env.pie5" = '{"a":1,"b":2,"c":3}'

Now run:

FORCE_COLOR=1 QUIET= QUIET2= bun dev

Or (Linux x64):

FORCE_COLOR=1 QUIET= QUIET2= /build/bun/packages/debug-bun-linux-x64/bun-debug dev

After opening localhost:3000 and refreshing the page 4 to 10 times, we get a Segfault. I did not narrow the files down more because there are some other weird interactions going on.

When tsconfig.json is configured like so, we get another weird behavior:

{
	"compilerOptions": {
	  "lib": ["ESNext"],
	  "module": "esnext",
	  "target": "esnext",
	  "moduleResolution": "node",

	  // so that if your project isn't using TypeScript, it still has autocomplete
	  "allowJs": true,

	  // "bun-types" is the important part
	  "types": ["bun-types"]
	}
  }

The line process.env.pie5.b; is supposed to compile to ({ a: 1, b: 2, c: 3 }).b;, and correctly compiles the first time localhost:3000/ is opened. However, after refreshing the page 4 to 10 times it compiles to ({ "": 1, "": 2, string: 3 }).b;. (With slightly different environment variables I was about to get one of those keys to be object instead)

Unfortunately stack trace does not work on Linux so here's my handwritten trace for the Segfault:

main.zig
  60 |   cli.Cli.start(default_allocator, stdout, stderr, MainPanicHandler);

cli.zig
  76 |   Command.start(allocator, log) catch |err| {

cli.zig
 932 |   try DevCommand.exec(ctx);

dev_command.zig
   7 |   try Server.start(ctx.allocator, ctx.args, @TypeOf(ctx.debug), ctx.debug);

http.zig
4031 |   try server.run(ConnectionFeatures{.public_folder = .first,},);

http.zig
3609 |   server.handleConnection(&conn, comptime features);

http.zig
3829 |   req_ctx.handleRequest() catch |err| {

http.zig
3153 |   return ctx.handleGet();

http.zig
3147 |   try @call(.{ .modifier = .always_inline }, RequestContext.renderServeResult, .{ ctx, result });

http.zig
2473-4 |   if (!ctx.url.is_source_map)
                    ctx.bundler.buildWithResolveResult(

bundler.zig
890 |   .none, .esm => try bundler.printWithSourceMapMaybe(

bundler.zig
1141 |   .esm => try js_printer.printAst(

js_printer.zig, `stmt` is 
`
{
	loc: { start: -1 },
	data: {
		s_expr: {
			does_not_affect_tree_shaking: false,
			value: { loc: { start: -1 } }
		}
	}
}
`
5014 |   try printer.printStmt(stmt);

js_printer.zig
4031 |   p.printExpr(s.value, .lowest, ExprFlag.ExprResultIsUnused());

js_printer.zig
1631 |   p.printExpr(e.target, .postfix, target_flags);

js_printer.zig
2353 |   p.printExpr(e.right, right_level, flags);

js_printer.zig
1906 |   p.printFunc(e.func);

js_printer.zig
 933 |   p.printBlock(func.body.loc, func.body.stmts);

js_printer.zig
825 |   p.printBlockBody(stmts);

js_printer.zig
815 |   p.printStmt(stmt) catch unreachable;

js_printer.zig
4031 |   p.printExpr(s.value, .lowest, ExprFlag.ExprResultIsUnused());

js_printer.zig
1741 |   p.printExpr(e.target, .postfix, flags, );

js_printer.zig (property.key.data supposedly has a payload of `e_unary` according to debugger, but in the next layer it has an e_string whose `data` is `{ptr:0x00007fff00000484, len:5309989061088}`
1997 |   p.printProperty(property);

js_printer.zig
2580 |   key.resovleRopeIfNeeded(p.options.allocator);

js_printer.zig `ptr` is `"\xaa"` (i.e. null for debug mode) `this.data` is `{ptr:0x00007fff00000484, len:5309989061088}`
1680 |   @memcpy(ptr, this.data.ptr, this.data.len);

Here's the call stack from VSCode:

___lldb_unnamed_symbol4284 (@___lldb_unnamed_symbol4284:7)
src.js_ast.E.String.resovleRopeIfNeeded (/build/bun/src/js_ast.zig:1680)
src.js_printer.NewPrinter(false,src.js_printer.NewWriter(src.http.SocketPrinterInternal,src.http.SocketPrinterInternal.writeByte,src.http.SocketPrinterInternal.writeAll,src.http.SocketPrinterInternal.getLastByte,src.http.SocketPrinterInternal.getLastLastByte,src.http.SocketPrinterInternal.reserveNext,src.http.SocketPrinterInternal.advanceBy),src.linker.Linker,false,false,false,false,false).printProperty (/build/bun/src/js_printer.zig:2580)
src.js_printer.NewPrinter(false,src.js_printer.NewWriter(src.http.SocketPrinterInternal,src.http.SocketPrinterInternal.writeByte,src.http.SocketPrinterInternal.writeAll,src.http.SocketPrinterInternal.getLastByte,src.http.SocketPrinterInternal.getLastLastByte,src.http.SocketPrinterInternal.reserveNext,src.http.SocketPrinterInternal.advanceBy),src.linker.Linker,false,false,false,false,false).printExpr (/build/bun/src/js_printer.zig:1997)
src.js_printer.NewPrinter(false,src.js_printer.NewWriter(src.http.SocketPrinterInternal,src.http.SocketPrinterInternal.writeByte,src.http.SocketPrinterInternal.writeAll,src.http.SocketPrinterInternal.getLastByte,src.http.SocketPrinterInternal.getLastLastByte,src.http.SocketPrinterInternal.reserveNext,src.http.SocketPrinterInternal.advanceBy),src.linker.Linker,false,false,false,false,false).printExpr (/build/bun/src/js_printer.zig:1741)
src.js_printer.NewPrinter(false,src.js_printer.NewWriter(src.http.SocketPrinterInternal,src.http.SocketPrinterInternal.writeByte,src.http.SocketPrinterInternal.writeAll,src.http.SocketPrinterInternal.getLastByte,src.http.SocketPrinterInternal.getLastLastByte,src.http.SocketPrinterInternal.reserveNext,src.http.SocketPrinterInternal.advanceBy),src.linker.Linker,false,false,false,false,false).printStmt (/build/bun/src/js_printer.zig:4031)
src.js_printer.NewPrinter(false,src.js_printer.NewWriter(src.http.SocketPrinterInternal,src.http.SocketPrinterInternal.writeByte,src.http.SocketPrinterInternal.writeAll,src.http.SocketPrinterInternal.getLastByte,src.http.SocketPrinterInternal.getLastLastByte,src.http.SocketPrinterInternal.reserveNext,src.http.SocketPrinterInternal.advanceBy),src.linker.Linker,false,false,false,false,false).printBlockBody (/build/bun/src/js_printer.zig:815)
src.js_printer.NewPrinter(false,src.js_printer.NewWriter(src.http.SocketPrinterInternal,src.http.SocketPrinterInternal.writeByte,src.http.SocketPrinterInternal.writeAll,src.http.SocketPrinterInternal.getLastByte,src.http.SocketPrinterInternal.getLastLastByte,src.http.SocketPrinterInternal.reserveNext,src.http.SocketPrinterInternal.advanceBy),src.linker.Linker,false,false,false,false,false).printBlock (/build/bun/src/js_printer.zig:825)
src.js_printer.NewPrinter(false,src.js_printer.NewWriter(src.http.SocketPrinterInternal,src.http.SocketPrinterInternal.writeByte,src.http.SocketPrinterInternal.writeAll,src.http.SocketPrinterInternal.getLastByte,src.http.SocketPrinterInternal.getLastLastByte,src.http.SocketPrinterInternal.reserveNext,src.http.SocketPrinterInternal.advanceBy),src.linker.Linker,false,false,false,false,false).printFunc (/build/bun/src/js_printer.zig:933)
src.js_printer.NewPrinter(false,src.js_printer.NewWriter(src.http.SocketPrinterInternal,src.http.SocketPrinterInternal.writeByte,src.http.SocketPrinterInternal.writeAll,src.http.SocketPrinterInternal.getLastByte,src.http.SocketPrinterInternal.getLastLastByte,src.http.SocketPrinterInternal.reserveNext,src.http.SocketPrinterInternal.advanceBy),src.linker.Linker,false,false,false,false,false).printExpr (/build/bun/src/js_printer.zig:1906)
src.js_printer.NewPrinter(false,src.js_printer.NewWriter(src.http.SocketPrinterInternal,src.http.SocketPrinterInternal.writeByte,src.http.SocketPrinterInternal.writeAll,src.http.SocketPrinterInternal.getLastByte,src.http.SocketPrinterInternal.getLastLastByte,src.http.SocketPrinterInternal.reserveNext,src.http.SocketPrinterInternal.advanceBy),src.linker.Linker,false,false,false,false,false).printExpr (/build/bun/src/js_printer.zig:2353)
src.js_printer.NewPrinter(false,src.js_printer.NewWriter(src.http.SocketPrinterInternal,src.http.SocketPrinterInternal.writeByte,src.http.SocketPrinterInternal.writeAll,src.http.SocketPrinterInternal.getLastByte,src.http.SocketPrinterInternal.getLastLastByte,src.http.SocketPrinterInternal.reserveNext,src.http.SocketPrinterInternal.advanceBy),src.linker.Linker,false,false,false,false,false).printExpr (/build/bun/src/js_printer.zig:1631)
src.js_printer.NewPrinter(false,src.js_printer.NewWriter(src.http.SocketPrinterInternal,src.http.SocketPrinterInternal.writeByte,src.http.SocketPrinterInternal.writeAll,src.http.SocketPrinterInternal.getLastByte,src.http.SocketPrinterInternal.getLastLastByte,src.http.SocketPrinterInternal.reserveNext,src.http.SocketPrinterInternal.advanceBy),src.linker.Linker,false,false,false,false,false).printStmt (/build/bun/src/js_printer.zig:4031)
src.js_printer.printAst (/build/bun/src/js_printer.zig:5014)
src.bundler.Bundler.printWithSourceMapMaybe (/build/bun/src/bundler.zig:1141)
src.bundler.Bundler.buildWithResolveResult (/build/bun/src/bundler.zig:890)
src.http.RequestContext.renderServeResult (/build/bun/src/http.zig:2474)
src.http.RequestContext.handleGet (/build/bun/src/http.zig:3147)
src.http.RequestContext.handleRequest (/build/bun/src/http.zig:3153)
src.http.Server.handleConnection (/build/bun/src/http.zig:3829)
src.http.Server.run (/build/bun/src/http.zig:3609)
src.http.Server.start (/build/bun/src/http.zig:4031)
src.cli.dev_command.DevCommand.exec (/build/bun/src/cli/dev_command.zig:7)
src.cli.Command.start (/build/bun/src/cli.zig:932)
src.cli.Cli.start (/build/bun/src/cli.zig:76)
main (/build/bun/src/main.zig:60)
std.start.callMain (/build/zig/lib/std/start.zig:571)
std.start.initEventLoopAndCallMain (/build/zig/lib/std/start.zig:515)
std.start.callMainWithArgs (/build/zig/lib/std/start.zig:465)
std.start.main (/build/zig/lib/std/start.zig:480)
___lldb_unnamed_symbol3139 (@___lldb_unnamed_symbol3139:29)
__libc_start_main (@__libc_start_main:43)
_start (@_start:15)

Additional information

Perhaps there is some hashing issue going on?

@Validark Validark added bug Something isn't working needs repro Needs an example to reproduce labels Sep 20, 2022
@github-actions github-actions bot removed the crash label Oct 22, 2022
@Electroid Electroid added crash An issue that could cause a crash and removed needs repro Needs an example to reproduce labels Nov 3, 2022
@Electroid
Copy link
Contributor

bun dev was changed in Bun v1.0, it will now run the "dev" script in your package.json. Because of that, this issue is no longer applicable.

@Electroid Electroid closed this as not planned Won't fix, can't repro, duplicate, stale Oct 25, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working crash An issue that could cause a crash
Projects
None yet
Development

No branches or pull requests

2 participants