mirror of
https://github.com/ziglang/zig.git
synced 2025-01-21 01:14:32 +00:00
ZIG_DEBUG_COLOR=1 overrides tty detection for runtime stack traces
This commit is contained in:
parent
2ee67b7642
commit
05f1ea33d2
@ -689,7 +689,10 @@ fn termColor(allocator: *mem.Allocator, input: []const u8) ![]u8 {
|
|||||||
fn genHtml(allocator: *mem.Allocator, tokenizer: *Tokenizer, toc: *Toc, out: var, zig_exe: []const u8) !void {
|
fn genHtml(allocator: *mem.Allocator, tokenizer: *Tokenizer, toc: *Toc, out: var, zig_exe: []const u8) !void {
|
||||||
var code_progress_index: usize = 0;
|
var code_progress_index: usize = 0;
|
||||||
|
|
||||||
const builtin_code = try escapeHtml(allocator, try getBuiltinCode(allocator, zig_exe));
|
var env_map = try os.getEnvMap(allocator);
|
||||||
|
try env_map.set("ZIG_DEBUG_COLOR", "1");
|
||||||
|
|
||||||
|
const builtin_code = try escapeHtml(allocator, try getBuiltinCode(allocator, &env_map, zig_exe));
|
||||||
|
|
||||||
for (toc.nodes) |node| {
|
for (toc.nodes) |node| {
|
||||||
switch (node) {
|
switch (node) {
|
||||||
@ -778,12 +781,12 @@ fn genHtml(allocator: *mem.Allocator, tokenizer: *Tokenizer, toc: *Toc, out: var
|
|||||||
try build_args.append("c");
|
try build_args.append("c");
|
||||||
try out.print(" --library c");
|
try out.print(" --library c");
|
||||||
}
|
}
|
||||||
_ = exec(allocator, build_args.toSliceConst()) catch return parseError(tokenizer, code.source_token, "example failed to compile");
|
_ = exec(allocator, &env_map, build_args.toSliceConst()) catch return parseError(tokenizer, code.source_token, "example failed to compile");
|
||||||
|
|
||||||
const run_args = [][]const u8{tmp_bin_file_name};
|
const run_args = [][]const u8{tmp_bin_file_name};
|
||||||
|
|
||||||
const result = if (expected_outcome == ExpectedOutcome.Fail) blk: {
|
const result = if (expected_outcome == ExpectedOutcome.Fail) blk: {
|
||||||
const result = try os.ChildProcess.exec(allocator, run_args, null, null, max_doc_file_size);
|
const result = try os.ChildProcess.exec(allocator, run_args, null, &env_map, max_doc_file_size);
|
||||||
switch (result.term) {
|
switch (result.term) {
|
||||||
os.ChildProcess.Term.Exited => |exit_code| {
|
os.ChildProcess.Term.Exited => |exit_code| {
|
||||||
if (exit_code == 0) {
|
if (exit_code == 0) {
|
||||||
@ -799,7 +802,7 @@ fn genHtml(allocator: *mem.Allocator, tokenizer: *Tokenizer, toc: *Toc, out: var
|
|||||||
}
|
}
|
||||||
break :blk result;
|
break :blk result;
|
||||||
} else blk: {
|
} else blk: {
|
||||||
break :blk exec(allocator, run_args) catch return parseError(tokenizer, code.source_token, "example crashed");
|
break :blk exec(allocator, &env_map, run_args) catch return parseError(tokenizer, code.source_token, "example crashed");
|
||||||
};
|
};
|
||||||
|
|
||||||
const escaped_stderr = try escapeHtml(allocator, result.stderr);
|
const escaped_stderr = try escapeHtml(allocator, result.stderr);
|
||||||
@ -845,7 +848,7 @@ fn genHtml(allocator: *mem.Allocator, tokenizer: *Tokenizer, toc: *Toc, out: var
|
|||||||
"msvc",
|
"msvc",
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
const result = exec(allocator, test_args.toSliceConst()) catch return parseError(tokenizer, code.source_token, "test failed");
|
const result = exec(allocator, &env_map, test_args.toSliceConst()) catch return parseError(tokenizer, code.source_token, "test failed");
|
||||||
const escaped_stderr = try escapeHtml(allocator, result.stderr);
|
const escaped_stderr = try escapeHtml(allocator, result.stderr);
|
||||||
const escaped_stdout = try escapeHtml(allocator, result.stdout);
|
const escaped_stdout = try escapeHtml(allocator, result.stdout);
|
||||||
try out.print("\n{}{}</code></pre>\n", escaped_stderr, escaped_stdout);
|
try out.print("\n{}{}</code></pre>\n", escaped_stderr, escaped_stdout);
|
||||||
@ -877,7 +880,7 @@ fn genHtml(allocator: *mem.Allocator, tokenizer: *Tokenizer, toc: *Toc, out: var
|
|||||||
try out.print(" --release-small");
|
try out.print(" --release-small");
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
const result = try os.ChildProcess.exec(allocator, test_args.toSliceConst(), null, null, max_doc_file_size);
|
const result = try os.ChildProcess.exec(allocator, test_args.toSliceConst(), null, &env_map, max_doc_file_size);
|
||||||
switch (result.term) {
|
switch (result.term) {
|
||||||
os.ChildProcess.Term.Exited => |exit_code| {
|
os.ChildProcess.Term.Exited => |exit_code| {
|
||||||
if (exit_code == 0) {
|
if (exit_code == 0) {
|
||||||
@ -923,7 +926,7 @@ fn genHtml(allocator: *mem.Allocator, tokenizer: *Tokenizer, toc: *Toc, out: var
|
|||||||
builtin.Mode.ReleaseSmall => try test_args.append("--release-small"),
|
builtin.Mode.ReleaseSmall => try test_args.append("--release-small"),
|
||||||
}
|
}
|
||||||
|
|
||||||
const result = try os.ChildProcess.exec(allocator, test_args.toSliceConst(), null, null, max_doc_file_size);
|
const result = try os.ChildProcess.exec(allocator, test_args.toSliceConst(), null, &env_map, max_doc_file_size);
|
||||||
switch (result.term) {
|
switch (result.term) {
|
||||||
os.ChildProcess.Term.Exited => |exit_code| {
|
os.ChildProcess.Term.Exited => |exit_code| {
|
||||||
if (exit_code == 0) {
|
if (exit_code == 0) {
|
||||||
@ -1000,7 +1003,7 @@ fn genHtml(allocator: *mem.Allocator, tokenizer: *Tokenizer, toc: *Toc, out: var
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (maybe_error_match) |error_match| {
|
if (maybe_error_match) |error_match| {
|
||||||
const result = try os.ChildProcess.exec(allocator, build_args.toSliceConst(), null, null, max_doc_file_size);
|
const result = try os.ChildProcess.exec(allocator, build_args.toSliceConst(), null, &env_map, max_doc_file_size);
|
||||||
switch (result.term) {
|
switch (result.term) {
|
||||||
os.ChildProcess.Term.Exited => |exit_code| {
|
os.ChildProcess.Term.Exited => |exit_code| {
|
||||||
if (exit_code == 0) {
|
if (exit_code == 0) {
|
||||||
@ -1032,7 +1035,7 @@ fn genHtml(allocator: *mem.Allocator, tokenizer: *Tokenizer, toc: *Toc, out: var
|
|||||||
try out.print("</code></pre>\n");
|
try out.print("</code></pre>\n");
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
_ = exec(allocator, build_args.toSliceConst()) catch return parseError(tokenizer, code.source_token, "example failed to compile");
|
_ = exec(allocator, &env_map, build_args.toSliceConst()) catch return parseError(tokenizer, code.source_token, "example failed to compile");
|
||||||
}
|
}
|
||||||
if (!code.is_inline) {
|
if (!code.is_inline) {
|
||||||
try out.print("</code></pre>\n");
|
try out.print("</code></pre>\n");
|
||||||
@ -1045,8 +1048,8 @@ fn genHtml(allocator: *mem.Allocator, tokenizer: *Tokenizer, toc: *Toc, out: var
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn exec(allocator: *mem.Allocator, args: []const []const u8) !os.ChildProcess.ExecResult {
|
fn exec(allocator: *mem.Allocator, env_map: *std.BufMap, args: []const []const u8) !os.ChildProcess.ExecResult {
|
||||||
const result = try os.ChildProcess.exec(allocator, args, null, null, max_doc_file_size);
|
const result = try os.ChildProcess.exec(allocator, args, null, env_map, max_doc_file_size);
|
||||||
switch (result.term) {
|
switch (result.term) {
|
||||||
os.ChildProcess.Term.Exited => |exit_code| {
|
os.ChildProcess.Term.Exited => |exit_code| {
|
||||||
if (exit_code != 0) {
|
if (exit_code != 0) {
|
||||||
@ -1070,8 +1073,8 @@ fn exec(allocator: *mem.Allocator, args: []const []const u8) !os.ChildProcess.Ex
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
fn getBuiltinCode(allocator: *mem.Allocator, zig_exe: []const u8) ![]const u8 {
|
fn getBuiltinCode(allocator: *mem.Allocator, env_map: *std.BufMap, zig_exe: []const u8) ![]const u8 {
|
||||||
const result = try exec(allocator, []const []const u8{
|
const result = try exec(allocator, env_map, []const []const u8{
|
||||||
zig_exe,
|
zig_exe,
|
||||||
"builtin",
|
"builtin",
|
||||||
});
|
});
|
||||||
|
@ -10,6 +10,7 @@ const ArrayList = std.ArrayList;
|
|||||||
const builtin = @import("builtin");
|
const builtin = @import("builtin");
|
||||||
|
|
||||||
pub const FailingAllocator = @import("failing_allocator.zig").FailingAllocator;
|
pub const FailingAllocator = @import("failing_allocator.zig").FailingAllocator;
|
||||||
|
pub const failing_allocator = FailingAllocator.init(global_allocator, 0);
|
||||||
|
|
||||||
/// Tries to write to stderr, unbuffered, and ignores any error returned.
|
/// Tries to write to stderr, unbuffered, and ignores any error returned.
|
||||||
/// Does not append a newline.
|
/// Does not append a newline.
|
||||||
@ -44,6 +45,12 @@ pub fn getSelfDebugInfo() !*ElfStackTrace {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn wantTtyColor() bool {
|
||||||
|
var bytes: [128]u8 = undefined;
|
||||||
|
const allocator = &std.heap.FixedBufferAllocator.init(bytes[0..]).allocator;
|
||||||
|
return if (std.os.getEnvVarOwned(allocator, "ZIG_DEBUG_COLOR")) |_| true else |_| stderr_file.isTty();
|
||||||
|
}
|
||||||
|
|
||||||
/// Tries to print the current stack trace to stderr, unbuffered, and ignores any error returned.
|
/// Tries to print the current stack trace to stderr, unbuffered, and ignores any error returned.
|
||||||
pub fn dumpCurrentStackTrace(start_addr: ?usize) void {
|
pub fn dumpCurrentStackTrace(start_addr: ?usize) void {
|
||||||
const stderr = getStderrStream() catch return;
|
const stderr = getStderrStream() catch return;
|
||||||
@ -51,7 +58,7 @@ pub fn dumpCurrentStackTrace(start_addr: ?usize) void {
|
|||||||
stderr.print("Unable to dump stack trace: Unable to open debug info: {}\n", @errorName(err)) catch return;
|
stderr.print("Unable to dump stack trace: Unable to open debug info: {}\n", @errorName(err)) catch return;
|
||||||
return;
|
return;
|
||||||
};
|
};
|
||||||
writeCurrentStackTrace(stderr, getDebugInfoAllocator(), debug_info, stderr_file.isTty(), start_addr) catch |err| {
|
writeCurrentStackTrace(stderr, getDebugInfoAllocator(), debug_info, wantTtyColor(), start_addr) catch |err| {
|
||||||
stderr.print("Unable to dump stack trace: {}\n", @errorName(err)) catch return;
|
stderr.print("Unable to dump stack trace: {}\n", @errorName(err)) catch return;
|
||||||
return;
|
return;
|
||||||
};
|
};
|
||||||
@ -64,7 +71,7 @@ pub fn dumpStackTrace(stack_trace: *const builtin.StackTrace) void {
|
|||||||
stderr.print("Unable to dump stack trace: Unable to open debug info: {}\n", @errorName(err)) catch return;
|
stderr.print("Unable to dump stack trace: Unable to open debug info: {}\n", @errorName(err)) catch return;
|
||||||
return;
|
return;
|
||||||
};
|
};
|
||||||
writeStackTrace(stack_trace, stderr, getDebugInfoAllocator(), debug_info, stderr_file.isTty()) catch |err| {
|
writeStackTrace(stack_trace, stderr, getDebugInfoAllocator(), debug_info, wantTtyColor()) catch |err| {
|
||||||
stderr.print("Unable to dump stack trace: {}\n", @errorName(err)) catch return;
|
stderr.print("Unable to dump stack trace: {}\n", @errorName(err)) catch return;
|
||||||
return;
|
return;
|
||||||
};
|
};
|
||||||
|
@ -544,8 +544,13 @@ pub fn getEnvPosix(key: []const u8) ?[]const u8 {
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub const GetEnvVarOwnedError = error{
|
||||||
|
OutOfMemory,
|
||||||
|
EnvironmentVariableNotFound,
|
||||||
|
};
|
||||||
|
|
||||||
/// Caller must free returned memory.
|
/// Caller must free returned memory.
|
||||||
pub fn getEnvVarOwned(allocator: *mem.Allocator, key: []const u8) ![]u8 {
|
pub fn getEnvVarOwned(allocator: *mem.Allocator, key: []const u8) GetEnvVarOwnedError![]u8 {
|
||||||
if (is_windows) {
|
if (is_windows) {
|
||||||
const key_with_null = try cstr.addNullByte(allocator, key);
|
const key_with_null = try cstr.addNullByte(allocator, key);
|
||||||
defer allocator.free(key_with_null);
|
defer allocator.free(key_with_null);
|
||||||
@ -554,14 +559,17 @@ pub fn getEnvVarOwned(allocator: *mem.Allocator, key: []const u8) ![]u8 {
|
|||||||
errdefer allocator.free(buf);
|
errdefer allocator.free(buf);
|
||||||
|
|
||||||
while (true) {
|
while (true) {
|
||||||
const windows_buf_len = try math.cast(windows.DWORD, buf.len);
|
const windows_buf_len = math.cast(windows.DWORD, buf.len) catch return error.OutOfMemory;
|
||||||
const result = windows.GetEnvironmentVariableA(key_with_null.ptr, buf.ptr, windows_buf_len);
|
const result = windows.GetEnvironmentVariableA(key_with_null.ptr, buf.ptr, windows_buf_len);
|
||||||
|
|
||||||
if (result == 0) {
|
if (result == 0) {
|
||||||
const err = windows.GetLastError();
|
const err = windows.GetLastError();
|
||||||
return switch (err) {
|
return switch (err) {
|
||||||
windows.ERROR.ENVVAR_NOT_FOUND => error.EnvironmentVariableNotFound,
|
windows.ERROR.ENVVAR_NOT_FOUND => error.EnvironmentVariableNotFound,
|
||||||
else => unexpectedErrorWindows(err),
|
else => {
|
||||||
|
_ = unexpectedErrorWindows(err);
|
||||||
|
return error.EnvironmentVariableNotFound;
|
||||||
|
},
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user