aboutsummaryrefslogtreecommitdiff
path: root/lib/std/debug.zig
diff options
context:
space:
mode:
Diffstat (limited to 'lib/std/debug.zig')
-rw-r--r--lib/std/debug.zig137
1 files changed, 30 insertions, 107 deletions
diff --git a/lib/std/debug.zig b/lib/std/debug.zig
index 4d3437f665..a3a8a533ee 100644
--- a/lib/std/debug.zig
+++ b/lib/std/debug.zig
@@ -14,9 +14,12 @@ const native_os = builtin.os.tag;
const native_endian = native_arch.endian();
pub const MemoryAccessor = @import("debug/MemoryAccessor.zig");
+pub const FixedBufferReader = @import("debug/FixedBufferReader.zig");
pub const Dwarf = @import("debug/Dwarf.zig");
pub const Pdb = @import("debug/Pdb.zig");
pub const SelfInfo = @import("debug/SelfInfo.zig");
+pub const Info = @import("debug/Info.zig");
+pub const Coverage = @import("debug/Coverage.zig");
/// Unresolved source locations can be represented with a single `usize` that
/// corresponds to a virtual memory address of the program counter. Combined
@@ -26,6 +29,18 @@ pub const SourceLocation = struct {
line: u64,
column: u64,
file_name: []const u8,
+
+ pub const invalid: SourceLocation = .{
+ .line = 0,
+ .column = 0,
+ .file_name = &.{},
+ };
+};
+
+pub const Symbol = struct {
+ name: []const u8 = "???",
+ compile_unit_name: []const u8 = "???",
+ source_location: ?SourceLocation = null,
};
/// Deprecated because it returns the optimization mode of the standard
@@ -748,7 +763,7 @@ pub fn writeCurrentStackTrace(
// an overflow. We do not need to signal `StackIterator` as it will correctly detect this
// condition on the subsequent iteration and return `null` thus terminating the loop.
// same behaviour for x86-windows-msvc
- const address = if (return_address == 0) return_address else return_address - 1;
+ const address = return_address -| 1;
try printSourceAtAddress(debug_info, out_stream, address, tty_config);
} else printLastUnwindError(&it, debug_info, out_stream, tty_config);
}
@@ -871,13 +886,13 @@ pub fn printSourceAtAddress(debug_info: *SelfInfo, out_stream: anytype, address:
error.MissingDebugInfo, error.InvalidDebugInfo => return printUnknownSource(debug_info, out_stream, address, tty_config),
else => return err,
};
- defer symbol_info.deinit(debug_info.allocator);
+ defer if (symbol_info.source_location) |sl| debug_info.allocator.free(sl.file_name);
return printLineInfo(
out_stream,
- symbol_info.line_info,
+ symbol_info.source_location,
address,
- symbol_info.symbol_name,
+ symbol_info.name,
symbol_info.compile_unit_name,
tty_config,
printLineFromFileAnyOs,
@@ -886,7 +901,7 @@ pub fn printSourceAtAddress(debug_info: *SelfInfo, out_stream: anytype, address:
fn printLineInfo(
out_stream: anytype,
- line_info: ?SourceLocation,
+ source_location: ?SourceLocation,
address: usize,
symbol_name: []const u8,
compile_unit_name: []const u8,
@@ -896,8 +911,8 @@ fn printLineInfo(
nosuspend {
try tty_config.setColor(out_stream, .bold);
- if (line_info) |*li| {
- try out_stream.print("{s}:{d}:{d}", .{ li.file_name, li.line, li.column });
+ if (source_location) |*sl| {
+ try out_stream.print("{s}:{d}:{d}", .{ sl.file_name, sl.line, sl.column });
} else {
try out_stream.writeAll("???:?:?");
}
@@ -910,11 +925,11 @@ fn printLineInfo(
try out_stream.writeAll("\n");
// Show the matching source code line if possible
- if (line_info) |li| {
- if (printLineFromFile(out_stream, li)) {
- if (li.column > 0) {
+ if (source_location) |sl| {
+ if (printLineFromFile(out_stream, sl)) {
+ if (sl.column > 0) {
// The caret already takes one char
- const space_needed = @as(usize, @intCast(li.column - 1));
+ const space_needed = @as(usize, @intCast(sl.column - 1));
try out_stream.writeByteNTimes(' ', space_needed);
try tty_config.setColor(out_stream, .green);
@@ -932,10 +947,10 @@ fn printLineInfo(
}
}
-fn printLineFromFileAnyOs(out_stream: anytype, line_info: SourceLocation) !void {
+fn printLineFromFileAnyOs(out_stream: anytype, source_location: SourceLocation) !void {
// Need this to always block even in async I/O mode, because this could potentially
// be called from e.g. the event loop code crashing.
- var f = try fs.cwd().openFile(line_info.file_name, .{});
+ var f = try fs.cwd().openFile(source_location.file_name, .{});
defer f.close();
// TODO fstat and make sure that the file has the correct size
@@ -944,7 +959,7 @@ fn printLineFromFileAnyOs(out_stream: anytype, line_info: SourceLocation) !void
const line_start = seek: {
var current_line_start: usize = 0;
var next_line: usize = 1;
- while (next_line != line_info.line) {
+ while (next_line != source_location.line) {
const slice = buf[current_line_start..amt_read];
if (mem.indexOfScalar(u8, slice, '\n')) |pos| {
next_line += 1;
@@ -1481,99 +1496,6 @@ pub const SafetyLock = struct {
}
};
-/// Deprecated. Don't use this, just read from your memory directly.
-///
-/// This only exists because someone was too lazy to rework logic that used to
-/// operate on an open file to operate on a memory buffer instead.
-pub const DeprecatedFixedBufferReader = struct {
- buf: []const u8,
- pos: usize = 0,
- endian: std.builtin.Endian,
-
- pub const Error = error{ EndOfBuffer, Overflow, InvalidBuffer };
-
- pub fn seekTo(fbr: *DeprecatedFixedBufferReader, pos: u64) Error!void {
- if (pos > fbr.buf.len) return error.EndOfBuffer;
- fbr.pos = @intCast(pos);
- }
-
- pub fn seekForward(fbr: *DeprecatedFixedBufferReader, amount: u64) Error!void {
- if (fbr.buf.len - fbr.pos < amount) return error.EndOfBuffer;
- fbr.pos += @intCast(amount);
- }
-
- pub inline fn readByte(fbr: *DeprecatedFixedBufferReader) Error!u8 {
- if (fbr.pos >= fbr.buf.len) return error.EndOfBuffer;
- defer fbr.pos += 1;
- return fbr.buf[fbr.pos];
- }
-
- pub fn readByteSigned(fbr: *DeprecatedFixedBufferReader) Error!i8 {
- return @bitCast(try fbr.readByte());
- }
-
- pub fn readInt(fbr: *DeprecatedFixedBufferReader, comptime T: type) Error!T {
- const size = @divExact(@typeInfo(T).Int.bits, 8);
- if (fbr.buf.len - fbr.pos < size) return error.EndOfBuffer;
- defer fbr.pos += size;
- return std.mem.readInt(T, fbr.buf[fbr.pos..][0..size], fbr.endian);
- }
-
- pub fn readIntChecked(
- fbr: *DeprecatedFixedBufferReader,
- comptime T: type,
- ma: *MemoryAccessor,
- ) Error!T {
- if (ma.load(T, @intFromPtr(fbr.buf[fbr.pos..].ptr)) == null)
- return error.InvalidBuffer;
-
- return fbr.readInt(T);
- }
-
- pub fn readUleb128(fbr: *DeprecatedFixedBufferReader, comptime T: type) Error!T {
- return std.leb.readUleb128(T, fbr);
- }
-
- pub fn readIleb128(fbr: *DeprecatedFixedBufferReader, comptime T: type) Error!T {
- return std.leb.readIleb128(T, fbr);
- }
-
- pub fn readAddress(fbr: *DeprecatedFixedBufferReader, format: std.dwarf.Format) Error!u64 {
- return switch (format) {
- .@"32" => try fbr.readInt(u32),
- .@"64" => try fbr.readInt(u64),
- };
- }
-
- pub fn readAddressChecked(
- fbr: *DeprecatedFixedBufferReader,
- format: std.dwarf.Format,
- ma: *MemoryAccessor,
- ) Error!u64 {
- return switch (format) {
- .@"32" => try fbr.readIntChecked(u32, ma),
- .@"64" => try fbr.readIntChecked(u64, ma),
- };
- }
-
- pub fn readBytes(fbr: *DeprecatedFixedBufferReader, len: usize) Error![]const u8 {
- if (fbr.buf.len - fbr.pos < len) return error.EndOfBuffer;
- defer fbr.pos += len;
- return fbr.buf[fbr.pos..][0..len];
- }
-
- pub fn readBytesTo(fbr: *DeprecatedFixedBufferReader, comptime sentinel: u8) Error![:sentinel]const u8 {
- const end = @call(.always_inline, std.mem.indexOfScalarPos, .{
- u8,
- fbr.buf,
- fbr.pos,
- sentinel,
- }) orelse return error.EndOfBuffer;
- defer fbr.pos = end + 1;
- return fbr.buf[fbr.pos..end :sentinel];
- }
-};
-
/// Detect whether the program is being executed in the Valgrind virtual machine.
///
/// When Valgrind integrations are disabled, this returns comptime-known false.
@@ -1587,6 +1509,7 @@ pub inline fn inValgrind() bool {
test {
_ = &Dwarf;
_ = &MemoryAccessor;
+ _ = &FixedBufferReader;
_ = &Pdb;
_ = &SelfInfo;
_ = &dumpHex;