| author | |
| committer | |
| log | a4523a2d4a0fb2b5c660a11aa37718080eebe9d0 |
| tree | 2d03ffade98f1d46db5af94eae7be40c998b93e7 |
| parent | d060cbbec75ac7b0204c706e4dfdfb38f1b24dfd |
Previously, we'd overwrite the errors in a circular buffer. Now that
error return traces are intended to follow a stack discipline, we no
longer have to support the index rolling over. By treating the trace
like a saturating stack, any pop/restore code still behaves correctly
past-the-end of the trace.
As a bonus, this adds a small blurb to let the user know when the trace
saturated and x number of frames were dropped.2 files changed, 12 insertions(+), 2 deletions(-)
lib/std/builtin.zig+4-2| ... | ... | @@ -869,8 +869,10 @@ pub noinline fn returnError(st: *StackTrace) void { |
| 869 | 869 | } |
| 870 | 870 | |
| 871 | 871 | pub inline fn addErrRetTraceAddr(st: *StackTrace, addr: usize) void { |
| 872 | st.instruction_addresses[st.index & (st.instruction_addresses.len - 1)] = addr; | |
| 873 | st.index +%= 1; | |
| 872 | if (st.index < st.instruction_addresses.len) | |
| 873 | st.instruction_addresses[st.index] = addr; | |
| 874 | ||
| 875 | st.index += 1; | |
| 874 | 876 | } |
| 875 | 877 | |
| 876 | 878 | const std = @import("std.zig"); |
lib/std/debug.zig+8| ... | ... | @@ -411,6 +411,14 @@ pub fn writeStackTrace( |
| 411 | 411 | const return_address = stack_trace.instruction_addresses[frame_index]; |
| 412 | 412 | try printSourceAtAddress(debug_info, out_stream, return_address - 1, tty_config); |
| 413 | 413 | } |
| 414 | ||
| 415 | if (stack_trace.index > stack_trace.instruction_addresses.len) { | |
| 416 | const dropped_frames = stack_trace.index - stack_trace.instruction_addresses.len; | |
| 417 | ||
| 418 | tty_config.setColor(out_stream, .Bold); | |
| 419 | try out_stream.print("({d} additional stack frames skipped...)\n", .{dropped_frames}); | |
| 420 | tty_config.setColor(out_stream, .Reset); | |
| 421 | } | |
| 414 | 422 | } |
| 415 | 423 | |
| 416 | 424 | pub const StackIterator = struct { |