Compare commits
2 commits
dfd3c5d66e
...
1afaa3be4f
Author | SHA1 | Date | |
---|---|---|---|
1afaa3be4f | |||
e558502ea2 |
6 changed files with 73 additions and 47 deletions
10
build.zig
10
build.zig
|
@ -447,9 +447,11 @@ pub fn build_exe(
|
||||||
|
|
||||||
const keybind_test_run_cmd = blk: {
|
const keybind_test_run_cmd = blk: {
|
||||||
const tests = b.addTest(.{
|
const tests = b.addTest(.{
|
||||||
|
.root_module = b.createModule(.{
|
||||||
.root_source_file = b.path("src/keybind/keybind.zig"),
|
.root_source_file = b.path("src/keybind/keybind.zig"),
|
||||||
.target = target,
|
.target = target,
|
||||||
.optimize = optimize,
|
.optimize = optimize,
|
||||||
|
}),
|
||||||
});
|
});
|
||||||
tests.root_module.addImport("cbor", cbor_mod);
|
tests.root_module.addImport("cbor", cbor_mod);
|
||||||
tests.root_module.addImport("command", command_mod);
|
tests.root_module.addImport("command", command_mod);
|
||||||
|
@ -568,10 +570,12 @@ pub fn build_exe(
|
||||||
|
|
||||||
const exe = b.addExecutable(.{
|
const exe = b.addExecutable(.{
|
||||||
.name = exe_name,
|
.name = exe_name,
|
||||||
|
.root_module = b.createModule(.{
|
||||||
.root_source_file = b.path("src/main.zig"),
|
.root_source_file = b.path("src/main.zig"),
|
||||||
.target = target,
|
.target = target,
|
||||||
.optimize = optimize,
|
.optimize = optimize,
|
||||||
.strip = strip,
|
.strip = strip,
|
||||||
|
}),
|
||||||
.win32_manifest = b.path("src/win32/flow.manifest"),
|
.win32_manifest = b.path("src/win32/flow.manifest"),
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -620,9 +624,11 @@ pub fn build_exe(
|
||||||
|
|
||||||
const check_exe = b.addExecutable(.{
|
const check_exe = b.addExecutable(.{
|
||||||
.name = exe_name,
|
.name = exe_name,
|
||||||
|
.root_module = b.createModule(.{
|
||||||
.root_source_file = b.path("src/main.zig"),
|
.root_source_file = b.path("src/main.zig"),
|
||||||
.target = target,
|
.target = target,
|
||||||
.optimize = optimize,
|
.optimize = optimize,
|
||||||
|
}),
|
||||||
});
|
});
|
||||||
|
|
||||||
check_exe.root_module.addImport("build_options", options_mod);
|
check_exe.root_module.addImport("build_options", options_mod);
|
||||||
|
@ -645,12 +651,14 @@ pub fn build_exe(
|
||||||
check_step.dependOn(&check_exe.step);
|
check_step.dependOn(&check_exe.step);
|
||||||
|
|
||||||
const tests = b.addTest(.{
|
const tests = b.addTest(.{
|
||||||
|
.root_module = b.createModule(.{
|
||||||
.root_source_file = b.path("test/tests.zig"),
|
.root_source_file = b.path("test/tests.zig"),
|
||||||
.target = target,
|
.target = target,
|
||||||
.optimize = optimize,
|
.optimize = optimize,
|
||||||
|
.strip = strip,
|
||||||
|
}),
|
||||||
.use_llvm = use_llvm,
|
.use_llvm = use_llvm,
|
||||||
.use_lld = use_llvm,
|
.use_lld = use_llvm,
|
||||||
.strip = strip,
|
|
||||||
});
|
});
|
||||||
|
|
||||||
tests.pie = pie;
|
tests.pie = pie;
|
||||||
|
|
|
@ -18,8 +18,8 @@
|
||||||
.hash = "dizzy-1.0.0-q40X4YCRAAAGYO9QOZiYYSOwiiFlqZlecMuQcxPiBcXM",
|
.hash = "dizzy-1.0.0-q40X4YCRAAAGYO9QOZiYYSOwiiFlqZlecMuQcxPiBcXM",
|
||||||
},
|
},
|
||||||
.thespian = .{
|
.thespian = .{
|
||||||
.url = "git+https://github.com/neurocyte/thespian?ref=master#8b2535db199d2215bea438abb323f3e3f6c58d99",
|
.url = "git+https://github.com/neurocyte/thespian?ref=master#d9c93e9783546f2fb040ffcff84576fe46d6495b",
|
||||||
.hash = "thespian-0.0.1-owFOjjQbBgABzTPy7sWTQMJ7Ts5ielIYO3_6hfhxbQa_",
|
.hash = "thespian-0.0.1-owFOjjQbBgAxIs7QYErDVaESLxgLdNQcoTIgU-QoNqlt",
|
||||||
},
|
},
|
||||||
.themes = .{
|
.themes = .{
|
||||||
.url = "https://github.com/neurocyte/flow-themes/releases/download/master-952f9f630ea9544088fd30293666ee0650b7a690/flow-themes.tar.gz",
|
.url = "https://github.com/neurocyte/flow-themes/releases/download/master-952f9f630ea9544088fd30293666ee0650b7a690/flow-themes.tar.gz",
|
||||||
|
|
|
@ -10,7 +10,7 @@ const checkmark_width = if (builtin.os.tag != .windows) 2 else 3;
|
||||||
const success_mark = if (builtin.os.tag != .windows) "✓ " else "[y]";
|
const success_mark = if (builtin.os.tag != .windows) "✓ " else "[y]";
|
||||||
const fail_mark = if (builtin.os.tag != .windows) "✘ " else "[n]";
|
const fail_mark = if (builtin.os.tag != .windows) "✘ " else "[n]";
|
||||||
|
|
||||||
pub fn list(allocator: std.mem.Allocator, writer: anytype, tty_config: std.io.tty.Config) !void {
|
pub fn list(allocator: std.mem.Allocator, writer: *std.io.Writer, tty_config: std.io.tty.Config) !void {
|
||||||
var max_language_len: usize = 0;
|
var max_language_len: usize = 0;
|
||||||
var max_langserver_len: usize = 0;
|
var max_langserver_len: usize = 0;
|
||||||
var max_formatter_len: usize = 0;
|
var max_formatter_len: usize = 0;
|
||||||
|
|
44
src/main.zig
44
src/main.zig
|
@ -122,32 +122,41 @@ pub fn main() anyerror!void {
|
||||||
scratch: bool,
|
scratch: bool,
|
||||||
new_file: bool,
|
new_file: bool,
|
||||||
version: bool,
|
version: bool,
|
||||||
|
|
||||||
|
positional: struct {
|
||||||
|
trailing: []const []const u8,
|
||||||
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
var arg_iter = try std.process.argsWithAllocator(a);
|
const args_alloc = try std.process.argsAlloc(a);
|
||||||
defer arg_iter.deinit();
|
defer std.process.argsFree(a, args_alloc);
|
||||||
|
|
||||||
var diag: flags.Diagnostics = undefined;
|
var diag: flags.Diagnostics = undefined;
|
||||||
var positional_args = std.ArrayList([]const u8).init(a);
|
|
||||||
defer positional_args.deinit();
|
|
||||||
|
|
||||||
const args = flags.parse(&arg_iter, "flow", Flags, .{
|
const args = flags.parse(args_alloc, "flow", Flags, .{
|
||||||
.diagnostics = &diag,
|
.diagnostics = &diag,
|
||||||
.trailing_list = &positional_args,
|
|
||||||
}) catch |err| {
|
}) catch |err| {
|
||||||
if (err == error.PrintedHelp) exit(0);
|
if (err == error.PrintedHelp) exit(0);
|
||||||
diag.help.generated.render(std.io.getStdOut(), flags.ColorScheme.default) catch {};
|
try diag.printUsage(&flags.ColorScheme.default);
|
||||||
exit(1);
|
exit(1);
|
||||||
return err;
|
return err;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
var stdout_buf: [4096]u8 = undefined;
|
||||||
|
var stdout_file = std.fs.File.stdout().writer(&stdout_buf);
|
||||||
|
const stdout = &stdout_file.interface;
|
||||||
|
defer stdout.flush() catch {};
|
||||||
|
var stderr_buf: [4096]u8 = undefined;
|
||||||
|
var stderr_file = std.fs.File.stderr().writer(&stderr_buf);
|
||||||
|
const stderr = &stderr_file.interface;
|
||||||
|
defer stderr.flush() catch {};
|
||||||
|
|
||||||
if (args.version)
|
if (args.version)
|
||||||
return std.io.getStdOut().writeAll(version_info);
|
return std.fs.File.stdout().writeAll(version_info);
|
||||||
|
|
||||||
if (args.list_languages) {
|
if (args.list_languages) {
|
||||||
const stdout = std.io.getStdOut();
|
const tty_config = std.io.tty.detectConfig(std.fs.File.stdout());
|
||||||
const tty_config = std.io.tty.detectConfig(stdout);
|
return list_languages.list(a, stdout, tty_config);
|
||||||
return list_languages.list(a, stdout.writer(), tty_config);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (builtin.os.tag != .windows and @hasDecl(renderer, "install_crash_handler")) {
|
if (builtin.os.tag != .windows and @hasDecl(renderer, "install_crash_handler")) {
|
||||||
|
@ -158,11 +167,12 @@ pub fn main() anyerror!void {
|
||||||
if (args.debug_wait) {
|
if (args.debug_wait) {
|
||||||
std.debug.print("press return to start", .{});
|
std.debug.print("press return to start", .{});
|
||||||
var buf: [1]u8 = undefined;
|
var buf: [1]u8 = undefined;
|
||||||
_ = try std.io.getStdIn().read(&buf);
|
_ = try std.fs.File.stdin().read(&buf);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (c.setlocale(c.LC_ALL, "") == null) {
|
if (c.setlocale(c.LC_ALL, "") == null) {
|
||||||
try std.io.getStdErr().writer().print("Failed to set locale. Is your locale valid?\n", .{});
|
try stderr.print("Failed to set locale. Is your locale valid?\n", .{});
|
||||||
|
stderr.flush() catch {};
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -245,7 +255,7 @@ pub fn main() anyerror!void {
|
||||||
defer links.deinit();
|
defer links.deinit();
|
||||||
var prev: ?*file_link.Dest = null;
|
var prev: ?*file_link.Dest = null;
|
||||||
var line_next: ?usize = null;
|
var line_next: ?usize = null;
|
||||||
for (positional_args.items) |arg| {
|
for (args.positional.trailing.items) |arg| {
|
||||||
if (arg.len == 0) continue;
|
if (arg.len == 0) continue;
|
||||||
|
|
||||||
if (!args.literal and arg[0] == '+') {
|
if (!args.literal and arg[0] == '+') {
|
||||||
|
@ -372,17 +382,17 @@ fn count_args() usize {
|
||||||
return count;
|
return count;
|
||||||
}
|
}
|
||||||
|
|
||||||
fn trace(m: thespian.message.c_buffer_type) callconv(.C) void {
|
fn trace(m: thespian.message.c_buffer_type) callconv(.c) void {
|
||||||
thespian.message.from(m).to_json_cb(trace_json);
|
thespian.message.from(m).to_json_cb(trace_json);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn trace_json(json: thespian.message.json_string_view) callconv(.C) void {
|
fn trace_json(json: thespian.message.json_string_view) callconv(.c) void {
|
||||||
const callstack_depth = 10;
|
const callstack_depth = 10;
|
||||||
___tracy_emit_message(json.base, json.len, callstack_depth);
|
___tracy_emit_message(json.base, json.len, callstack_depth);
|
||||||
}
|
}
|
||||||
extern fn ___tracy_emit_message(txt: [*]const u8, size: usize, callstack: c_int) void;
|
extern fn ___tracy_emit_message(txt: [*]const u8, size: usize, callstack: c_int) void;
|
||||||
|
|
||||||
fn trace_to_file(m: thespian.message.c_buffer_type) callconv(.C) void {
|
fn trace_to_file(m: thespian.message.c_buffer_type) callconv(.c) void {
|
||||||
const State = struct {
|
const State = struct {
|
||||||
file: std.fs.File,
|
file: std.fs.File,
|
||||||
last_time: i64,
|
last_time: i64,
|
||||||
|
|
|
@ -156,7 +156,10 @@ fn handle_crash(sig: i32, info: *const std.posix.siginfo_t, ctx_ptr: ?*anyopaque
|
||||||
self.tty.deinit();
|
self.tty.deinit();
|
||||||
}
|
}
|
||||||
if (builtin.os.tag == .linux and jit_debugger_enabled) {
|
if (builtin.os.tag == .linux and jit_debugger_enabled) {
|
||||||
handleSegfaultPosixNoAbort(sig, info, ctx_ptr);
|
var buf: [4096]u8 = undefined;
|
||||||
|
var stderr = std.fs.File.stderr().writer(&buf);
|
||||||
|
defer stderr.interface.flush() catch {};
|
||||||
|
handleSegfaultPosixNoAbort(&stderr.interface, sig, info, ctx_ptr);
|
||||||
@import("thespian").sighdl_debugger(sig, @ptrCast(@constCast(info)), ctx_ptr);
|
@import("thespian").sighdl_debugger(sig, @ptrCast(@constCast(info)), ctx_ptr);
|
||||||
std.posix.abort();
|
std.posix.abort();
|
||||||
} else {
|
} else {
|
||||||
|
@ -165,7 +168,7 @@ fn handle_crash(sig: i32, info: *const std.posix.siginfo_t, ctx_ptr: ?*anyopaque
|
||||||
unreachable;
|
unreachable;
|
||||||
}
|
}
|
||||||
|
|
||||||
fn handleSegfaultPosixNoAbort(sig: i32, info: *const std.posix.siginfo_t, ctx_ptr: ?*anyopaque) void {
|
fn handleSegfaultPosixNoAbort(stderr: *std.io.Writer, sig: i32, info: *const std.posix.siginfo_t, ctx_ptr: ?*anyopaque) void {
|
||||||
const debug = @import("std/debug.zig");
|
const debug = @import("std/debug.zig");
|
||||||
debug.resetSegfaultHandler();
|
debug.resetSegfaultHandler();
|
||||||
const addr = switch (builtin.os.tag) {
|
const addr = switch (builtin.os.tag) {
|
||||||
|
@ -177,7 +180,7 @@ fn handleSegfaultPosixNoAbort(sig: i32, info: *const std.posix.siginfo_t, ctx_pt
|
||||||
else => unreachable,
|
else => unreachable,
|
||||||
};
|
};
|
||||||
const code = if (builtin.os.tag == .netbsd) info.info.code else info.code;
|
const code = if (builtin.os.tag == .netbsd) info.info.code else info.code;
|
||||||
debug.dumpSegfaultInfoPosix(sig, code, addr, ctx_ptr);
|
debug.dumpSegfaultInfoPosix(stderr, sig, code, addr, ctx_ptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn run(self: *Self) Error!void {
|
pub fn run(self: *Self) Error!void {
|
||||||
|
|
|
@ -384,16 +384,14 @@ pub inline fn getContext(context: *ThreadContext) bool {
|
||||||
/// Tries to print the stack trace starting from the supplied base pointer to stderr,
|
/// Tries to print the stack trace starting from the supplied base pointer to stderr,
|
||||||
/// unbuffered, and ignores any error returned.
|
/// unbuffered, and ignores any error returned.
|
||||||
/// TODO multithreaded awareness
|
/// TODO multithreaded awareness
|
||||||
pub fn dumpStackTraceFromBase(context: *ThreadContext) void {
|
pub fn dumpStackTraceFromBase(stderr: *io.Writer, context: *ThreadContext) void {
|
||||||
nosuspend {
|
nosuspend {
|
||||||
if (builtin.target.cpu.arch.isWasm()) {
|
if (builtin.target.cpu.arch.isWasm()) {
|
||||||
if (native_os == .wasi) {
|
if (native_os == .wasi) {
|
||||||
const stderr = io.getStdErr().writer();
|
|
||||||
stderr.print("Unable to dump stack trace: not implemented for Wasm\n", .{}) catch return;
|
stderr.print("Unable to dump stack trace: not implemented for Wasm\n", .{}) catch return;
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
const stderr = io.getStdErr().writer();
|
|
||||||
if (builtin.strip_debug_info) {
|
if (builtin.strip_debug_info) {
|
||||||
stderr.print("Unable to dump stack trace: debug info stripped\n", .{}) catch return;
|
stderr.print("Unable to dump stack trace: debug info stripped\n", .{}) catch return;
|
||||||
return;
|
return;
|
||||||
|
@ -402,7 +400,7 @@ pub fn dumpStackTraceFromBase(context: *ThreadContext) void {
|
||||||
stderr.print("Unable to dump stack trace: Unable to open debug info: {s}\n", .{@errorName(err)}) catch return;
|
stderr.print("Unable to dump stack trace: Unable to open debug info: {s}\n", .{@errorName(err)}) catch return;
|
||||||
return;
|
return;
|
||||||
};
|
};
|
||||||
const tty_config = io.tty.detectConfig(io.getStdErr());
|
const tty_config = io.tty.detectConfig(fs.File.stderr());
|
||||||
if (native_os == .windows) {
|
if (native_os == .windows) {
|
||||||
// On x86_64 and aarch64, the stack will be unwound using RtlVirtualUnwind using the context
|
// On x86_64 and aarch64, the stack will be unwound using RtlVirtualUnwind using the context
|
||||||
// provided by the exception handler. On x86, RtlVirtualUnwind doesn't exist. Instead, a new backtrace
|
// provided by the exception handler. On x86, RtlVirtualUnwind doesn't exist. Instead, a new backtrace
|
||||||
|
@ -759,7 +757,7 @@ pub const StackIterator = struct {
|
||||||
"flushw"
|
"flushw"
|
||||||
else
|
else
|
||||||
"ta 3" // ST_FLUSH_WINDOWS
|
"ta 3" // ST_FLUSH_WINDOWS
|
||||||
::: "memory");
|
::: .{ .memory = true });
|
||||||
}
|
}
|
||||||
|
|
||||||
return StackIterator{
|
return StackIterator{
|
||||||
|
@ -1425,14 +1423,22 @@ pub fn handleSegfaultPosix(sig: i32, info: *const posix.siginfo_t, ctx_ptr: ?*an
|
||||||
lockStdErr();
|
lockStdErr();
|
||||||
defer unlockStdErr();
|
defer unlockStdErr();
|
||||||
|
|
||||||
dumpSegfaultInfoPosix(sig, code, addr, ctx_ptr);
|
var buf: [4096]u8 = undefined;
|
||||||
|
var stderr = fs.File.stderr().writer(&buf);
|
||||||
|
defer stderr.interface.flush() catch {};
|
||||||
|
|
||||||
|
dumpSegfaultInfoPosix(&stderr.interface, sig, code, addr, ctx_ptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
waitForOtherThreadToFinishPanicking();
|
waitForOtherThreadToFinishPanicking();
|
||||||
},
|
},
|
||||||
else => {
|
else => {
|
||||||
|
var buf: [4096]u8 = undefined;
|
||||||
|
var stderr = fs.File.stderr().writer(&buf);
|
||||||
|
defer stderr.interface.flush() catch {};
|
||||||
|
|
||||||
// panic mutex already locked
|
// panic mutex already locked
|
||||||
dumpSegfaultInfoPosix(sig, code, addr, ctx_ptr);
|
dumpSegfaultInfoPosix(&stderr.interface, sig, code, addr, ctx_ptr);
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -1442,8 +1448,7 @@ pub fn handleSegfaultPosix(sig: i32, info: *const posix.siginfo_t, ctx_ptr: ?*an
|
||||||
posix.abort();
|
posix.abort();
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn dumpSegfaultInfoPosix(sig: i32, code: i32, addr: usize, ctx_ptr: ?*anyopaque) void {
|
pub fn dumpSegfaultInfoPosix(stderr: *io.Writer, sig: i32, code: i32, addr: usize, ctx_ptr: ?*anyopaque) void {
|
||||||
const stderr = io.getStdErr().writer();
|
|
||||||
_ = switch (sig) {
|
_ = switch (sig) {
|
||||||
posix.SIG.SEGV => if (native_arch == .x86_64 and native_os == .linux and code == 128) // SI_KERNEL
|
posix.SIG.SEGV => if (native_arch == .x86_64 and native_os == .linux and code == 128) // SI_KERNEL
|
||||||
// x86_64 doesn't have a full 64-bit virtual address space.
|
// x86_64 doesn't have a full 64-bit virtual address space.
|
||||||
|
@ -1491,7 +1496,7 @@ pub fn dumpSegfaultInfoPosix(sig: i32, code: i32, addr: usize, ctx_ptr: ?*anyopa
|
||||||
}, @ptrCast(ctx)).__mcontext_data;
|
}, @ptrCast(ctx)).__mcontext_data;
|
||||||
}
|
}
|
||||||
relocateContext(&new_ctx);
|
relocateContext(&new_ctx);
|
||||||
dumpStackTraceFromBase(&new_ctx);
|
dumpStackTraceFromBase(stderr, &new_ctx);
|
||||||
},
|
},
|
||||||
else => {},
|
else => {},
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue