authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2018-12-02 18:54:04-05:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2018-12-02 18:54:04-05:00
log4292ed9571ede4d616e92e9cba3986a07d135955
treef9ba80e08378d86dc6b39b35a257417058867aad
parenta40d160a5ca7fe50680578541c40038e280272ce
signature Commit is signed but in an unrecognized format.

std.debug.StackIterator


1 files changed, 33 insertions(+), 36 deletions(-)

std/debug/index.zig+33-36
......@@ -198,49 +198,46 @@ pub fn writeStackTrace(stack_trace: *const builtin.StackTrace, out_stream: var,
198198 }
199199}
200200
201pub inline fn getReturnAddress(frame_count: usize) usize {
202 var fp = @ptrToInt(@frameAddress());
203 var i: usize = 0;
204 while (fp != 0 and i < frame_count) {
205 fp = @intToPtr(*const usize, fp).*;
206 i += 1;
201pub const StackIterator = struct {
202 first_addr: ?usize,
203 debug_info: *DebugInfo,
204 fp: usize,
205
206 pub fn init(debug_info: *DebugInfo, first_addr: ?usize) StackIterator {
207 return StackIterator{
208 .debug_info = debug_info,
209 .first_addr = first_addr,
210 .fp = @ptrToInt(@frameAddress()),
211 };
207212 }
208 return @intToPtr(*const usize, fp + @sizeOf(usize)).*;
209}
213
214 fn next(self: *StackIterator) ?usize {
215 if (self.fp == 0) return null;
216 self.fp = @intToPtr(*const usize, self.fp).*;
217 if (self.fp == 0) return null;
218
219 if (self.first_addr) |addr| {
220 while (self.fp != 0) : (self.fp = @intToPtr(*const usize, self.fp).*) {
221 const return_address = @intToPtr(*const usize, self.fp + @sizeOf(usize)).*;
222 if (addr == return_address) {
223 self.first_addr = null;
224 return return_address;
225 }
226 }
227 }
228
229 const return_address = @intToPtr(*const usize, self.fp + @sizeOf(usize)).*;
230 return return_address;
231 }
232};
210233
211234pub fn writeCurrentStackTrace(out_stream: var, debug_info: *DebugInfo, tty_color: bool, start_addr: ?usize) !void {
212235 switch (builtin.os) {
213236 builtin.Os.windows => return writeCurrentStackTraceWindows(out_stream, debug_info, tty_color, start_addr),
214237 else => {},
215238 }
216 const AddressState = union(enum) {
217 NotLookingForStartAddress,
218 LookingForStartAddress: usize,
219 };
220 // TODO: I want to express like this:
221 //var addr_state = if (start_addr) |addr| AddressState { .LookingForStartAddress = addr }
222 // else AddressState.NotLookingForStartAddress;
223 var addr_state: AddressState = undefined;
224 if (start_addr) |addr| {
225 addr_state = AddressState{ .LookingForStartAddress = addr };
226 } else {
227 addr_state = AddressState.NotLookingForStartAddress;
228 }
229
230 var fp = @ptrToInt(@frameAddress());
231 while (fp != 0) : (fp = @intToPtr(*const usize, fp).*) {
232 const return_address = @intToPtr(*const usize, fp + @sizeOf(usize)).*;
233
234 switch (addr_state) {
235 AddressState.NotLookingForStartAddress => {},
236 AddressState.LookingForStartAddress => |addr| {
237 if (return_address == addr) {
238 addr_state = AddressState.NotLookingForStartAddress;
239 } else {
240 continue;
241 }
242 },
243 }
239 var it = StackIterator.init(debug_info, start_addr);
240 while (it.next()) |return_address| {
244241 try printSourceAtAddress(debug_info, out_stream, return_address, tty_color);
245242 }
246243}