mirror of
https://github.com/ziglang/zig.git
synced 2024-11-26 15:12:31 +00:00
dwarf: fix stepping through an inline loop containing one statement
Previously, stepping from the single statement within the loop would always exit the loop because all of the code unrolled from the loop is associated with the same line and treated by the debugger as one line.
This commit is contained in:
parent
6d781e0955
commit
c894ac09a3
@ -6024,7 +6024,7 @@ fn tryExpr(
|
||||
if (!parent_gz.is_comptime) {
|
||||
try emitDbgNode(parent_gz, node);
|
||||
}
|
||||
const try_lc = LineColumn{ astgen.source_line - parent_gz.decl_line, astgen.source_column };
|
||||
const try_lc: LineColumn = .{ astgen.source_line - parent_gz.decl_line, astgen.source_column };
|
||||
|
||||
const operand_rl: ResultInfo.Loc, const block_tag: Zir.Inst.Tag = switch (ri.rl) {
|
||||
.ref => .{ .ref, .try_ptr },
|
||||
@ -6577,6 +6577,7 @@ fn whileExpr(
|
||||
const astgen = parent_gz.astgen;
|
||||
const tree = astgen.tree;
|
||||
const token_tags = tree.tokens.items(.tag);
|
||||
const token_starts = tree.tokens.items(.start);
|
||||
|
||||
const need_rl = astgen.nodes_need_rl.contains(node);
|
||||
const block_ri: ResultInfo = if (need_rl) ri else .{
|
||||
@ -6774,6 +6775,16 @@ fn whileExpr(
|
||||
try checkUsed(parent_gz, &then_scope.base, then_sub_scope);
|
||||
const break_tag: Zir.Inst.Tag = if (is_inline) .break_inline else .@"break";
|
||||
if (!continue_scope.endsWithNoReturn()) {
|
||||
astgen.advanceSourceCursor(token_starts[tree.lastToken(then_node)]);
|
||||
try emitDbgStmt(parent_gz, .{ astgen.source_line - parent_gz.decl_line, astgen.source_column });
|
||||
_ = try parent_gz.add(.{
|
||||
.tag = .extended,
|
||||
.data = .{ .extended = .{
|
||||
.opcode = .dbg_empty_stmt,
|
||||
.small = undefined,
|
||||
.operand = undefined,
|
||||
} },
|
||||
});
|
||||
_ = try continue_scope.addBreak(break_tag, continue_block, .void_value);
|
||||
}
|
||||
try continue_scope.setBlockBody(continue_block);
|
||||
@ -6882,6 +6893,7 @@ fn forExpr(
|
||||
}
|
||||
const tree = astgen.tree;
|
||||
const token_tags = tree.tokens.items(.tag);
|
||||
const token_starts = tree.tokens.items(.start);
|
||||
const node_tags = tree.nodes.items(.tag);
|
||||
const node_data = tree.nodes.items(.data);
|
||||
const gpa = astgen.gpa;
|
||||
@ -7087,8 +7099,18 @@ fn forExpr(
|
||||
|
||||
try checkUsed(parent_gz, &then_scope.base, then_sub_scope);
|
||||
|
||||
const break_tag: Zir.Inst.Tag = if (is_inline) .break_inline else .@"break";
|
||||
astgen.advanceSourceCursor(token_starts[tree.lastToken(then_node)]);
|
||||
try emitDbgStmt(parent_gz, .{ astgen.source_line - parent_gz.decl_line, astgen.source_column });
|
||||
_ = try parent_gz.add(.{
|
||||
.tag = .extended,
|
||||
.data = .{ .extended = .{
|
||||
.opcode = .dbg_empty_stmt,
|
||||
.small = undefined,
|
||||
.operand = undefined,
|
||||
} },
|
||||
});
|
||||
|
||||
const break_tag: Zir.Inst.Tag = if (is_inline) .break_inline else .@"break";
|
||||
_ = try then_scope.addBreak(break_tag, cond_block, .void_value);
|
||||
|
||||
var else_scope = parent_gz.makeSubBlock(&cond_scope.base);
|
||||
@ -7135,6 +7157,7 @@ fn forExpr(
|
||||
.lhs = index_ptr,
|
||||
.rhs = index_plus_one,
|
||||
});
|
||||
|
||||
const repeat_tag: Zir.Inst.Tag = if (is_inline) .repeat_inline else .repeat;
|
||||
_ = try loop_scope.addNode(repeat_tag, node);
|
||||
|
||||
@ -7279,7 +7302,7 @@ fn switchExprErrUnion(
|
||||
};
|
||||
|
||||
astgen.advanceSourceCursorToNode(operand_node);
|
||||
const operand_lc = LineColumn{ astgen.source_line - parent_gz.decl_line, astgen.source_column };
|
||||
const operand_lc: LineColumn = .{ astgen.source_line - parent_gz.decl_line, astgen.source_column };
|
||||
|
||||
const raw_operand = try reachableExpr(parent_gz, scope, operand_ri, operand_node, switch_node);
|
||||
const item_ri: ResultInfo = .{ .rl = .none };
|
||||
@ -7868,7 +7891,7 @@ fn switchExpr(
|
||||
const operand_ri: ResultInfo = .{ .rl = if (any_payload_is_ref) .ref else .none };
|
||||
|
||||
astgen.advanceSourceCursorToNode(operand_node);
|
||||
const operand_lc = LineColumn{ astgen.source_line - parent_gz.decl_line, astgen.source_column };
|
||||
const operand_lc: LineColumn = .{ astgen.source_line - parent_gz.decl_line, astgen.source_column };
|
||||
|
||||
const raw_operand = try expr(parent_gz, scope, operand_ri, operand_node);
|
||||
const item_ri: ResultInfo = .{ .rl = .none };
|
||||
@ -8214,7 +8237,7 @@ fn ret(gz: *GenZir, scope: *Scope, node: Ast.Node.Index) InnerError!Zir.Inst.Ref
|
||||
if (!gz.is_comptime) {
|
||||
try emitDbgNode(gz, node);
|
||||
}
|
||||
const ret_lc = LineColumn{ astgen.source_line - gz.decl_line, astgen.source_column };
|
||||
const ret_lc: LineColumn = .{ astgen.source_line - gz.decl_line, astgen.source_column };
|
||||
|
||||
const defer_outer = &astgen.fn_block.?.base;
|
||||
|
||||
|
@ -2088,6 +2088,8 @@ pub const Inst = struct {
|
||||
/// `operand` is `Zir.Inst.Ref` of the loaded LHS (*not* its type).
|
||||
/// `small` is an `Inst.InplaceOp`.
|
||||
inplace_arith_result_ty,
|
||||
/// Marks a statement that can be stepped to but produces no code.
|
||||
dbg_empty_stmt,
|
||||
|
||||
pub const InstData = struct {
|
||||
opcode: Extended,
|
||||
@ -4062,6 +4064,7 @@ fn findDeclsInner(
|
||||
.branch_hint,
|
||||
.inplace_arith_result_ty,
|
||||
.tuple_decl,
|
||||
.dbg_empty_stmt,
|
||||
=> return,
|
||||
|
||||
// `@TypeOf` has a body.
|
||||
|
@ -460,6 +460,8 @@ pub const Inst = struct {
|
||||
/// Result type is always void.
|
||||
/// Uses the `dbg_stmt` field.
|
||||
dbg_stmt,
|
||||
/// Marks a statement that can be stepped to but produces no code.
|
||||
dbg_empty_stmt,
|
||||
/// A block that represents an inlined function call.
|
||||
/// Uses the `ty_pl` field. Payload is `DbgInlineBlock`.
|
||||
dbg_inline_block,
|
||||
@ -1468,6 +1470,7 @@ pub fn typeOfIndex(air: *const Air, inst: Air.Inst.Index, ip: *const InternPool)
|
||||
|
||||
.breakpoint,
|
||||
.dbg_stmt,
|
||||
.dbg_empty_stmt,
|
||||
.dbg_var_ptr,
|
||||
.dbg_var_val,
|
||||
.dbg_arg_inline,
|
||||
@ -1629,6 +1632,7 @@ pub fn mustLower(air: Air, inst: Air.Inst.Index, ip: *const InternPool) bool {
|
||||
.try_ptr,
|
||||
.try_ptr_cold,
|
||||
.dbg_stmt,
|
||||
.dbg_empty_stmt,
|
||||
.dbg_inline_block,
|
||||
.dbg_var_ptr,
|
||||
.dbg_var_val,
|
||||
|
@ -417,6 +417,7 @@ fn checkBody(air: Air, body: []const Air.Inst.Index, zcu: *Zcu) bool {
|
||||
.work_group_size,
|
||||
.work_group_id,
|
||||
.dbg_stmt,
|
||||
.dbg_empty_stmt,
|
||||
.err_return_trace,
|
||||
.save_err_return_trace_index,
|
||||
.repeat,
|
||||
|
@ -334,6 +334,7 @@ pub fn categorizeOperand(
|
||||
.repeat,
|
||||
.switch_dispatch,
|
||||
.dbg_stmt,
|
||||
.dbg_empty_stmt,
|
||||
.unreach,
|
||||
.ret_addr,
|
||||
.frame_addr,
|
||||
@ -973,6 +974,7 @@ fn analyzeInst(
|
||||
.ret_ptr,
|
||||
.breakpoint,
|
||||
.dbg_stmt,
|
||||
.dbg_empty_stmt,
|
||||
.ret_addr,
|
||||
.frame_addr,
|
||||
.wasm_memory_size,
|
||||
|
@ -56,6 +56,7 @@ fn verifyBody(self: *Verify, body: []const Air.Inst.Index) Error!void {
|
||||
.ret_ptr,
|
||||
.breakpoint,
|
||||
.dbg_stmt,
|
||||
.dbg_empty_stmt,
|
||||
.ret_addr,
|
||||
.frame_addr,
|
||||
.wasm_memory_size,
|
||||
|
10
src/Sema.zig
10
src/Sema.zig
@ -1355,6 +1355,11 @@ fn analyzeBodyInner(
|
||||
.field_parent_ptr => try sema.zirFieldParentPtr(block, extended),
|
||||
.builtin_value => try sema.zirBuiltinValue(block, extended),
|
||||
.inplace_arith_result_ty => try sema.zirInplaceArithResultTy(extended),
|
||||
.dbg_empty_stmt => {
|
||||
try sema.zirDbgEmptyStmt(block, inst);
|
||||
i += 1;
|
||||
continue;
|
||||
},
|
||||
};
|
||||
},
|
||||
|
||||
@ -6671,6 +6676,11 @@ fn zirDbgStmt(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!voi
|
||||
});
|
||||
}
|
||||
|
||||
fn zirDbgEmptyStmt(_: *Sema, block: *Block, _: Zir.Inst.Index) CompileError!void {
|
||||
if (block.is_comptime or block.ownerModule().strip) return;
|
||||
_ = try block.addNoOp(.dbg_empty_stmt);
|
||||
}
|
||||
|
||||
fn zirDbgVar(
|
||||
sema: *Sema,
|
||||
block: *Block,
|
||||
|
@ -800,6 +800,7 @@ fn genBody(self: *Self, body: []const Air.Inst.Index) InnerError!void {
|
||||
.try_ptr_cold => try self.airTryPtr(inst),
|
||||
|
||||
.dbg_stmt => try self.airDbgStmt(inst),
|
||||
.dbg_empty_stmt => self.finishAirBookkeeping(),
|
||||
.dbg_inline_block => try self.airDbgInlineBlock(inst),
|
||||
.dbg_var_ptr,
|
||||
.dbg_var_val,
|
||||
|
@ -787,6 +787,7 @@ fn genBody(self: *Self, body: []const Air.Inst.Index) InnerError!void {
|
||||
.try_ptr_cold => try self.airTryPtr(inst),
|
||||
|
||||
.dbg_stmt => try self.airDbgStmt(inst),
|
||||
.dbg_empty_stmt => self.finishAirBookkeeping(),
|
||||
.dbg_inline_block => try self.airDbgInlineBlock(inst),
|
||||
.dbg_var_ptr,
|
||||
.dbg_var_val,
|
||||
|
@ -1593,6 +1593,7 @@ fn genBody(func: *Func, body: []const Air.Inst.Index) InnerError!void {
|
||||
.frame_addr => try func.airFrameAddress(inst),
|
||||
.cond_br => try func.airCondBr(inst),
|
||||
.dbg_stmt => try func.airDbgStmt(inst),
|
||||
.dbg_empty_stmt => func.finishAirBookkeeping(),
|
||||
.fptrunc => try func.airFptrunc(inst),
|
||||
.fpext => try func.airFpext(inst),
|
||||
.intcast => try func.airIntCast(inst),
|
||||
|
@ -642,6 +642,7 @@ fn genBody(self: *Self, body: []const Air.Inst.Index) InnerError!void {
|
||||
.try_ptr_cold => @panic("TODO try self.airTryPtrCold(inst)"),
|
||||
|
||||
.dbg_stmt => try self.airDbgStmt(inst),
|
||||
.dbg_empty_stmt => self.finishAirBookkeeping(),
|
||||
.dbg_inline_block => try self.airDbgInlineBlock(inst),
|
||||
.dbg_var_ptr,
|
||||
.dbg_var_val,
|
||||
|
@ -1924,6 +1924,7 @@ fn genInst(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
|
||||
.try_ptr_cold => func.airTryPtr(inst),
|
||||
|
||||
.dbg_stmt => func.airDbgStmt(inst),
|
||||
.dbg_empty_stmt => try func.finishAir(inst, .none, &.{}),
|
||||
.dbg_inline_block => func.airDbgInlineBlock(inst),
|
||||
.dbg_var_ptr => func.airDbgVar(inst, .local_var, true),
|
||||
.dbg_var_val => func.airDbgVar(inst, .local_var, false),
|
||||
|
@ -961,9 +961,16 @@ pub fn generate(
|
||||
},
|
||||
.debug_output = debug_output,
|
||||
.code = code,
|
||||
.prev_di_loc = .{
|
||||
.line = func.lbrace_line,
|
||||
.column = func.lbrace_column,
|
||||
.is_stmt = switch (debug_output) {
|
||||
.dwarf => |dwarf| dwarf.dwarf.debug_line.header.default_is_stmt,
|
||||
.plan9 => undefined,
|
||||
.none => undefined,
|
||||
},
|
||||
},
|
||||
.prev_di_pc = 0,
|
||||
.prev_di_line = func.lbrace_line,
|
||||
.prev_di_column = func.lbrace_column,
|
||||
};
|
||||
defer emit.deinit();
|
||||
emit.emitMir() catch |err| switch (err) {
|
||||
@ -1066,9 +1073,8 @@ pub fn generateLazy(
|
||||
},
|
||||
.debug_output = debug_output,
|
||||
.code = code,
|
||||
.prev_di_loc = undefined, // no debug info yet
|
||||
.prev_di_pc = undefined, // no debug info yet
|
||||
.prev_di_line = undefined, // no debug info yet
|
||||
.prev_di_column = undefined, // no debug info yet
|
||||
};
|
||||
defer emit.deinit();
|
||||
emit.emitMir() catch |err| switch (err) {
|
||||
@ -1194,13 +1200,16 @@ fn formatWipMir(
|
||||
switch (mir_inst.ops) {
|
||||
else => unreachable,
|
||||
.pseudo_dbg_prologue_end_none,
|
||||
.pseudo_dbg_line_line_column,
|
||||
.pseudo_dbg_epilogue_begin_none,
|
||||
.pseudo_dbg_enter_block_none,
|
||||
.pseudo_dbg_leave_block_none,
|
||||
.pseudo_dbg_var_args_none,
|
||||
.pseudo_dead_none,
|
||||
=> {},
|
||||
.pseudo_dbg_line_stmt_line_column, .pseudo_dbg_line_line_column => try writer.print(
|
||||
" {[line]d}, {[column]d}",
|
||||
mir_inst.data.line_column,
|
||||
),
|
||||
.pseudo_dbg_enter_inline_func, .pseudo_dbg_leave_inline_func => try writer.print(" {}", .{
|
||||
ip.getNav(ip.indexToKey(mir_inst.data.func).func.owner_nav).name.fmt(ip),
|
||||
}),
|
||||
@ -1281,14 +1290,7 @@ fn addInst(self: *Self, inst: Mir.Inst) error{OutOfMemory}!Mir.Inst.Index {
|
||||
try self.mir_instructions.ensureUnusedCapacity(gpa, 1);
|
||||
const result_index: Mir.Inst.Index = @intCast(self.mir_instructions.len);
|
||||
self.mir_instructions.appendAssumeCapacity(inst);
|
||||
if (inst.tag != .pseudo or switch (inst.ops) {
|
||||
else => true,
|
||||
.pseudo_dbg_prologue_end_none,
|
||||
.pseudo_dbg_line_line_column,
|
||||
.pseudo_dbg_epilogue_begin_none,
|
||||
.pseudo_dead_none,
|
||||
=> false,
|
||||
}) wip_mir_log.debug("{}", .{self.fmtWipMir(result_index)});
|
||||
wip_mir_log.debug("{}", .{self.fmtWipMir(result_index)});
|
||||
return result_index;
|
||||
}
|
||||
|
||||
@ -2218,7 +2220,7 @@ fn gen(self: *Self) InnerError!void {
|
||||
// Drop them off at the rbrace.
|
||||
_ = try self.addInst(.{
|
||||
.tag = .pseudo,
|
||||
.ops = .pseudo_dbg_line_line_column,
|
||||
.ops = .pseudo_dbg_line_stmt_line_column,
|
||||
.data = .{ .line_column = .{
|
||||
.line = self.end_di_line,
|
||||
.column = self.end_di_column,
|
||||
@ -2426,6 +2428,7 @@ fn genBody(self: *Self, body: []const Air.Inst.Index) InnerError!void {
|
||||
.try_ptr_cold => try self.airTryPtr(inst), // TODO
|
||||
|
||||
.dbg_stmt => try self.airDbgStmt(inst),
|
||||
.dbg_empty_stmt => try self.airDbgEmptyStmt(),
|
||||
.dbg_inline_block => try self.airDbgInlineBlock(inst),
|
||||
.dbg_var_ptr,
|
||||
.dbg_var_val,
|
||||
@ -13281,7 +13284,7 @@ fn airDbgStmt(self: *Self, inst: Air.Inst.Index) !void {
|
||||
const dbg_stmt = self.air.instructions.items(.data)[@intFromEnum(inst)].dbg_stmt;
|
||||
_ = try self.addInst(.{
|
||||
.tag = .pseudo,
|
||||
.ops = .pseudo_dbg_line_line_column,
|
||||
.ops = .pseudo_dbg_line_stmt_line_column,
|
||||
.data = .{ .line_column = .{
|
||||
.line = dbg_stmt.line,
|
||||
.column = dbg_stmt.column,
|
||||
@ -13290,6 +13293,14 @@ fn airDbgStmt(self: *Self, inst: Air.Inst.Index) !void {
|
||||
self.finishAirBookkeeping();
|
||||
}
|
||||
|
||||
fn airDbgEmptyStmt(self: *Self) !void {
|
||||
if (self.mir_instructions.len > 0 and
|
||||
self.mir_instructions.items(.ops)[self.mir_instructions.len - 1] == .pseudo_dbg_line_stmt_line_column)
|
||||
self.mir_instructions.items(.ops)[self.mir_instructions.len - 1] = .pseudo_dbg_line_line_column;
|
||||
try self.asmOpOnly(.{ ._, .nop });
|
||||
self.finishAirBookkeeping();
|
||||
}
|
||||
|
||||
fn airDbgInlineBlock(self: *Self, inst: Air.Inst.Index) !void {
|
||||
const ty_pl = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl;
|
||||
const extra = self.air.extraData(Air.DbgInlineBlock, ty_pl.payload);
|
||||
|
@ -6,8 +6,7 @@ atom_index: u32,
|
||||
debug_output: link.File.DebugInfoOutput,
|
||||
code: *std.ArrayList(u8),
|
||||
|
||||
prev_di_line: u32,
|
||||
prev_di_column: u32,
|
||||
prev_di_loc: Loc,
|
||||
/// Relative to the beginning of `code`.
|
||||
prev_di_pc: usize,
|
||||
|
||||
@ -263,77 +262,71 @@ pub fn emitMir(emit: *Emit) Error!void {
|
||||
else => unreachable,
|
||||
.pseudo => switch (mir_inst.ops) {
|
||||
else => unreachable,
|
||||
.pseudo_dbg_prologue_end_none => {
|
||||
switch (emit.debug_output) {
|
||||
.dwarf => |dw| try dw.setPrologueEnd(),
|
||||
.plan9 => {},
|
||||
.none => {},
|
||||
}
|
||||
.pseudo_dbg_prologue_end_none => switch (emit.debug_output) {
|
||||
.dwarf => |dwarf| try dwarf.setPrologueEnd(),
|
||||
.plan9 => {},
|
||||
.none => {},
|
||||
},
|
||||
.pseudo_dbg_line_line_column => try emit.dbgAdvancePCAndLine(
|
||||
mir_inst.data.line_column.line,
|
||||
mir_inst.data.line_column.column,
|
||||
),
|
||||
.pseudo_dbg_epilogue_begin_none => {
|
||||
switch (emit.debug_output) {
|
||||
.dwarf => |dw| {
|
||||
try dw.setEpilogueBegin();
|
||||
log.debug("mirDbgEpilogueBegin (line={d}, col={d})", .{
|
||||
emit.prev_di_line, emit.prev_di_column,
|
||||
});
|
||||
try emit.dbgAdvancePCAndLine(emit.prev_di_line, emit.prev_di_column);
|
||||
},
|
||||
.plan9 => {},
|
||||
.none => {},
|
||||
}
|
||||
.pseudo_dbg_line_stmt_line_column => try emit.dbgAdvancePCAndLine(.{
|
||||
.line = mir_inst.data.line_column.line,
|
||||
.column = mir_inst.data.line_column.column,
|
||||
.is_stmt = true,
|
||||
}),
|
||||
.pseudo_dbg_line_line_column => try emit.dbgAdvancePCAndLine(.{
|
||||
.line = mir_inst.data.line_column.line,
|
||||
.column = mir_inst.data.line_column.column,
|
||||
.is_stmt = false,
|
||||
}),
|
||||
.pseudo_dbg_epilogue_begin_none => switch (emit.debug_output) {
|
||||
.dwarf => |dwarf| {
|
||||
try dwarf.setEpilogueBegin();
|
||||
log.debug("mirDbgEpilogueBegin (line={d}, col={d})", .{
|
||||
emit.prev_di_loc.line, emit.prev_di_loc.column,
|
||||
});
|
||||
try emit.dbgAdvancePCAndLine(emit.prev_di_loc);
|
||||
},
|
||||
.plan9 => {},
|
||||
.none => {},
|
||||
},
|
||||
.pseudo_dbg_enter_block_none => {
|
||||
switch (emit.debug_output) {
|
||||
.dwarf => |dw| {
|
||||
log.debug("mirDbgEnterBlock (line={d}, col={d})", .{
|
||||
emit.prev_di_line, emit.prev_di_column,
|
||||
});
|
||||
try dw.enterBlock(emit.code.items.len);
|
||||
},
|
||||
.plan9 => {},
|
||||
.none => {},
|
||||
}
|
||||
.pseudo_dbg_enter_block_none => switch (emit.debug_output) {
|
||||
.dwarf => |dwarf| {
|
||||
log.debug("mirDbgEnterBlock (line={d}, col={d})", .{
|
||||
emit.prev_di_loc.line, emit.prev_di_loc.column,
|
||||
});
|
||||
try dwarf.enterBlock(emit.code.items.len);
|
||||
},
|
||||
.plan9 => {},
|
||||
.none => {},
|
||||
},
|
||||
.pseudo_dbg_leave_block_none => {
|
||||
switch (emit.debug_output) {
|
||||
.dwarf => |dw| {
|
||||
log.debug("mirDbgLeaveBlock (line={d}, col={d})", .{
|
||||
emit.prev_di_line, emit.prev_di_column,
|
||||
});
|
||||
try dw.leaveBlock(emit.code.items.len);
|
||||
},
|
||||
.plan9 => {},
|
||||
.none => {},
|
||||
}
|
||||
.pseudo_dbg_leave_block_none => switch (emit.debug_output) {
|
||||
.dwarf => |dwarf| {
|
||||
log.debug("mirDbgLeaveBlock (line={d}, col={d})", .{
|
||||
emit.prev_di_loc.line, emit.prev_di_loc.column,
|
||||
});
|
||||
try dwarf.leaveBlock(emit.code.items.len);
|
||||
},
|
||||
.plan9 => {},
|
||||
.none => {},
|
||||
},
|
||||
.pseudo_dbg_enter_inline_func => {
|
||||
switch (emit.debug_output) {
|
||||
.dwarf => |dw| {
|
||||
log.debug("mirDbgEnterInline (line={d}, col={d})", .{
|
||||
emit.prev_di_line, emit.prev_di_column,
|
||||
});
|
||||
try dw.enterInlineFunc(mir_inst.data.func, emit.code.items.len, emit.prev_di_line, emit.prev_di_column);
|
||||
},
|
||||
.plan9 => {},
|
||||
.none => {},
|
||||
}
|
||||
.pseudo_dbg_enter_inline_func => switch (emit.debug_output) {
|
||||
.dwarf => |dwarf| {
|
||||
log.debug("mirDbgEnterInline (line={d}, col={d})", .{
|
||||
emit.prev_di_loc.line, emit.prev_di_loc.column,
|
||||
});
|
||||
try dwarf.enterInlineFunc(mir_inst.data.func, emit.code.items.len, emit.prev_di_loc.line, emit.prev_di_loc.column);
|
||||
},
|
||||
.plan9 => {},
|
||||
.none => {},
|
||||
},
|
||||
.pseudo_dbg_leave_inline_func => {
|
||||
switch (emit.debug_output) {
|
||||
.dwarf => |dw| {
|
||||
log.debug("mirDbgLeaveInline (line={d}, col={d})", .{
|
||||
emit.prev_di_line, emit.prev_di_column,
|
||||
});
|
||||
try dw.leaveInlineFunc(mir_inst.data.func, emit.code.items.len);
|
||||
},
|
||||
.plan9 => {},
|
||||
.none => {},
|
||||
}
|
||||
.pseudo_dbg_leave_inline_func => switch (emit.debug_output) {
|
||||
.dwarf => |dwarf| {
|
||||
log.debug("mirDbgLeaveInline (line={d}, col={d})", .{
|
||||
emit.prev_di_loc.line, emit.prev_di_loc.column,
|
||||
});
|
||||
try dwarf.leaveInlineFunc(mir_inst.data.func, emit.code.items.len);
|
||||
},
|
||||
.plan9 => {},
|
||||
.none => {},
|
||||
},
|
||||
.pseudo_dbg_local_a,
|
||||
.pseudo_dbg_local_ai_s,
|
||||
@ -344,129 +337,125 @@ pub fn emitMir(emit: *Emit) Error!void {
|
||||
.pseudo_dbg_local_aro,
|
||||
.pseudo_dbg_local_af,
|
||||
.pseudo_dbg_local_am,
|
||||
=> {
|
||||
switch (emit.debug_output) {
|
||||
.dwarf => |dw| {
|
||||
var loc_buf: [2]link.File.Dwarf.Loc = undefined;
|
||||
const air_inst_index, const loc: link.File.Dwarf.Loc = switch (mir_inst.ops) {
|
||||
=> switch (emit.debug_output) {
|
||||
.dwarf => |dwarf| {
|
||||
var loc_buf: [2]link.File.Dwarf.Loc = undefined;
|
||||
const air_inst_index, const loc: link.File.Dwarf.Loc = switch (mir_inst.ops) {
|
||||
else => unreachable,
|
||||
.pseudo_dbg_local_a => .{ mir_inst.data.a.air_inst, .empty },
|
||||
.pseudo_dbg_local_ai_s,
|
||||
.pseudo_dbg_local_ai_u,
|
||||
.pseudo_dbg_local_ai_64,
|
||||
=> .{ mir_inst.data.ai.air_inst, .{ .stack_value = stack_value: {
|
||||
loc_buf[0] = switch (emit.lower.imm(mir_inst.ops, mir_inst.data.ai.i)) {
|
||||
.signed => |s| .{ .consts = s },
|
||||
.unsigned => |u| .{ .constu = u },
|
||||
};
|
||||
break :stack_value &loc_buf[0];
|
||||
} } },
|
||||
.pseudo_dbg_local_as => .{ mir_inst.data.as.air_inst, .{ .addr = .{
|
||||
.sym = mir_inst.data.as.sym_index,
|
||||
} } },
|
||||
.pseudo_dbg_local_aso => loc: {
|
||||
const sym_off = emit.lower.mir.extraData(
|
||||
bits.SymbolOffset,
|
||||
mir_inst.data.ax.payload,
|
||||
).data;
|
||||
break :loc .{ mir_inst.data.ax.air_inst, .{ .plus = .{
|
||||
sym: {
|
||||
loc_buf[0] = .{ .addr = .{ .sym = sym_off.sym_index } };
|
||||
break :sym &loc_buf[0];
|
||||
},
|
||||
off: {
|
||||
loc_buf[1] = .{ .consts = sym_off.off };
|
||||
break :off &loc_buf[1];
|
||||
},
|
||||
} } };
|
||||
},
|
||||
.pseudo_dbg_local_aro => loc: {
|
||||
const air_off = emit.lower.mir.extraData(
|
||||
Mir.AirOffset,
|
||||
mir_inst.data.rx.payload,
|
||||
).data;
|
||||
break :loc .{ air_off.air_inst, .{ .plus = .{
|
||||
reg: {
|
||||
loc_buf[0] = .{ .breg = mir_inst.data.rx.r1.dwarfNum() };
|
||||
break :reg &loc_buf[0];
|
||||
},
|
||||
off: {
|
||||
loc_buf[1] = .{ .consts = air_off.off };
|
||||
break :off &loc_buf[1];
|
||||
},
|
||||
} } };
|
||||
},
|
||||
.pseudo_dbg_local_af => loc: {
|
||||
const reg_off = emit.lower.mir.resolveFrameAddr(emit.lower.mir.extraData(
|
||||
bits.FrameAddr,
|
||||
mir_inst.data.ax.payload,
|
||||
).data);
|
||||
break :loc .{ mir_inst.data.ax.air_inst, .{ .plus = .{
|
||||
reg: {
|
||||
loc_buf[0] = .{ .breg = reg_off.reg.dwarfNum() };
|
||||
break :reg &loc_buf[0];
|
||||
},
|
||||
off: {
|
||||
loc_buf[1] = .{ .consts = reg_off.off };
|
||||
break :off &loc_buf[1];
|
||||
},
|
||||
} } };
|
||||
},
|
||||
.pseudo_dbg_local_am => loc: {
|
||||
const mem = emit.lower.mem(mir_inst.data.ax.payload);
|
||||
break :loc .{ mir_inst.data.ax.air_inst, .{ .plus = .{
|
||||
base: {
|
||||
loc_buf[0] = switch (mem.base()) {
|
||||
.none => .{ .constu = 0 },
|
||||
.reg => |reg| .{ .breg = reg.dwarfNum() },
|
||||
.frame => unreachable,
|
||||
.reloc => |sym_index| .{ .addr = .{ .sym = sym_index } },
|
||||
};
|
||||
break :base &loc_buf[0];
|
||||
},
|
||||
disp: {
|
||||
loc_buf[1] = switch (mem.disp()) {
|
||||
.signed => |s| .{ .consts = s },
|
||||
.unsigned => |u| .{ .constu = u },
|
||||
};
|
||||
break :disp &loc_buf[1];
|
||||
},
|
||||
} } };
|
||||
},
|
||||
};
|
||||
const ip = &emit.lower.bin_file.comp.zcu.?.intern_pool;
|
||||
const air_inst = emit.air.instructions.get(@intFromEnum(air_inst_index));
|
||||
const name: Air.NullTerminatedString = switch (air_inst.tag) {
|
||||
else => unreachable,
|
||||
.arg => air_inst.data.arg.name,
|
||||
.dbg_var_ptr, .dbg_var_val, .dbg_arg_inline => @enumFromInt(air_inst.data.pl_op.payload),
|
||||
};
|
||||
try dwarf.genLocalDebugInfo(
|
||||
switch (air_inst.tag) {
|
||||
else => unreachable,
|
||||
.pseudo_dbg_local_a => .{ mir_inst.data.a.air_inst, .empty },
|
||||
.pseudo_dbg_local_ai_s,
|
||||
.pseudo_dbg_local_ai_u,
|
||||
.pseudo_dbg_local_ai_64,
|
||||
=> .{ mir_inst.data.ai.air_inst, .{ .stack_value = stack_value: {
|
||||
loc_buf[0] = switch (emit.lower.imm(mir_inst.ops, mir_inst.data.ai.i)) {
|
||||
.signed => |s| .{ .consts = s },
|
||||
.unsigned => |u| .{ .constu = u },
|
||||
};
|
||||
break :stack_value &loc_buf[0];
|
||||
} } },
|
||||
.pseudo_dbg_local_as => .{ mir_inst.data.as.air_inst, .{ .addr = .{
|
||||
.sym = mir_inst.data.as.sym_index,
|
||||
} } },
|
||||
.pseudo_dbg_local_aso => loc: {
|
||||
const sym_off = emit.lower.mir.extraData(
|
||||
bits.SymbolOffset,
|
||||
mir_inst.data.ax.payload,
|
||||
).data;
|
||||
break :loc .{ mir_inst.data.ax.air_inst, .{ .plus = .{
|
||||
sym: {
|
||||
loc_buf[0] = .{ .addr = .{ .sym = sym_off.sym_index } };
|
||||
break :sym &loc_buf[0];
|
||||
},
|
||||
off: {
|
||||
loc_buf[1] = .{ .consts = sym_off.off };
|
||||
break :off &loc_buf[1];
|
||||
},
|
||||
} } };
|
||||
},
|
||||
.pseudo_dbg_local_aro => loc: {
|
||||
const air_off = emit.lower.mir.extraData(
|
||||
Mir.AirOffset,
|
||||
mir_inst.data.rx.payload,
|
||||
).data;
|
||||
break :loc .{ air_off.air_inst, .{ .plus = .{
|
||||
reg: {
|
||||
loc_buf[0] = .{ .breg = mir_inst.data.rx.r1.dwarfNum() };
|
||||
break :reg &loc_buf[0];
|
||||
},
|
||||
off: {
|
||||
loc_buf[1] = .{ .consts = air_off.off };
|
||||
break :off &loc_buf[1];
|
||||
},
|
||||
} } };
|
||||
},
|
||||
.pseudo_dbg_local_af => loc: {
|
||||
const reg_off = emit.lower.mir.resolveFrameAddr(emit.lower.mir.extraData(
|
||||
bits.FrameAddr,
|
||||
mir_inst.data.ax.payload,
|
||||
).data);
|
||||
break :loc .{ mir_inst.data.ax.air_inst, .{ .plus = .{
|
||||
reg: {
|
||||
loc_buf[0] = .{ .breg = reg_off.reg.dwarfNum() };
|
||||
break :reg &loc_buf[0];
|
||||
},
|
||||
off: {
|
||||
loc_buf[1] = .{ .consts = reg_off.off };
|
||||
break :off &loc_buf[1];
|
||||
},
|
||||
} } };
|
||||
},
|
||||
.pseudo_dbg_local_am => loc: {
|
||||
const mem = emit.lower.mem(mir_inst.data.ax.payload);
|
||||
break :loc .{ mir_inst.data.ax.air_inst, .{ .plus = .{
|
||||
base: {
|
||||
loc_buf[0] = switch (mem.base()) {
|
||||
.none => .{ .constu = 0 },
|
||||
.reg => |reg| .{ .breg = reg.dwarfNum() },
|
||||
.frame => unreachable,
|
||||
.reloc => |sym_index| .{ .addr = .{ .sym = sym_index } },
|
||||
};
|
||||
break :base &loc_buf[0];
|
||||
},
|
||||
disp: {
|
||||
loc_buf[1] = switch (mem.disp()) {
|
||||
.signed => |s| .{ .consts = s },
|
||||
.unsigned => |u| .{ .constu = u },
|
||||
};
|
||||
break :disp &loc_buf[1];
|
||||
},
|
||||
} } };
|
||||
},
|
||||
};
|
||||
const ip = &emit.lower.bin_file.comp.zcu.?.intern_pool;
|
||||
const air_inst = emit.air.instructions.get(@intFromEnum(air_inst_index));
|
||||
const name: Air.NullTerminatedString = switch (air_inst.tag) {
|
||||
.arg, .dbg_arg_inline => .local_arg,
|
||||
.dbg_var_ptr, .dbg_var_val => .local_var,
|
||||
},
|
||||
name.toSlice(emit.air),
|
||||
switch (air_inst.tag) {
|
||||
else => unreachable,
|
||||
.arg => air_inst.data.arg.name,
|
||||
.dbg_var_ptr, .dbg_var_val, .dbg_arg_inline => @enumFromInt(air_inst.data.pl_op.payload),
|
||||
};
|
||||
try dw.genLocalDebugInfo(
|
||||
switch (air_inst.tag) {
|
||||
else => unreachable,
|
||||
.arg, .dbg_arg_inline => .local_arg,
|
||||
.dbg_var_ptr, .dbg_var_val => .local_var,
|
||||
},
|
||||
name.toSlice(emit.air),
|
||||
switch (air_inst.tag) {
|
||||
else => unreachable,
|
||||
.arg => emit.air.typeOfIndex(air_inst_index, ip),
|
||||
.dbg_var_ptr => emit.air.typeOf(air_inst.data.pl_op.operand, ip).childTypeIp(ip),
|
||||
.dbg_var_val, .dbg_arg_inline => emit.air.typeOf(air_inst.data.pl_op.operand, ip),
|
||||
},
|
||||
loc,
|
||||
);
|
||||
},
|
||||
.plan9 => {},
|
||||
.none => {},
|
||||
}
|
||||
.arg => emit.air.typeOfIndex(air_inst_index, ip),
|
||||
.dbg_var_ptr => emit.air.typeOf(air_inst.data.pl_op.operand, ip).childTypeIp(ip),
|
||||
.dbg_var_val, .dbg_arg_inline => emit.air.typeOf(air_inst.data.pl_op.operand, ip),
|
||||
},
|
||||
loc,
|
||||
);
|
||||
},
|
||||
.plan9 => {},
|
||||
.none => {},
|
||||
},
|
||||
.pseudo_dbg_var_args_none => {
|
||||
switch (emit.debug_output) {
|
||||
.dwarf => |dw| try dw.genVarArgsDebugInfo(),
|
||||
.plan9 => {},
|
||||
.none => {},
|
||||
}
|
||||
.pseudo_dbg_var_args_none => switch (emit.debug_output) {
|
||||
.dwarf => |dwarf| try dwarf.genVarArgsDebugInfo(),
|
||||
.plan9 => {},
|
||||
.none => {},
|
||||
},
|
||||
.pseudo_dead_none => {},
|
||||
},
|
||||
@ -515,16 +504,22 @@ fn fixupRelocs(emit: *Emit) Error!void {
|
||||
}
|
||||
}
|
||||
|
||||
fn dbgAdvancePCAndLine(emit: *Emit, line: u32, column: u32) Error!void {
|
||||
const delta_line = @as(i33, line) - @as(i33, emit.prev_di_line);
|
||||
const Loc = struct {
|
||||
line: u32,
|
||||
column: u32,
|
||||
is_stmt: bool,
|
||||
};
|
||||
|
||||
fn dbgAdvancePCAndLine(emit: *Emit, loc: Loc) Error!void {
|
||||
const delta_line = @as(i33, loc.line) - @as(i33, emit.prev_di_loc.line);
|
||||
const delta_pc: usize = emit.code.items.len - emit.prev_di_pc;
|
||||
log.debug(" (advance pc={d} and line={d})", .{ delta_pc, delta_line });
|
||||
switch (emit.debug_output) {
|
||||
.dwarf => |dw| {
|
||||
if (column != emit.prev_di_column) try dw.setColumn(column);
|
||||
try dw.advancePCAndLine(delta_line, delta_pc);
|
||||
emit.prev_di_line = line;
|
||||
emit.prev_di_column = column;
|
||||
.dwarf => |dwarf| {
|
||||
if (loc.is_stmt != emit.prev_di_loc.is_stmt) try dwarf.negateStmt();
|
||||
if (loc.column != emit.prev_di_loc.column) try dwarf.setColumn(loc.column);
|
||||
try dwarf.advancePCAndLine(delta_line, delta_pc);
|
||||
emit.prev_di_loc = loc;
|
||||
emit.prev_di_pc = emit.code.items.len;
|
||||
},
|
||||
.plan9 => |dbg_out| {
|
||||
@ -553,11 +548,10 @@ fn dbgAdvancePCAndLine(emit: *Emit, line: u32, column: u32) Error!void {
|
||||
// we don't need to do anything, because adding the pc quanta does it for us
|
||||
} else unreachable;
|
||||
if (dbg_out.start_line == null)
|
||||
dbg_out.start_line = emit.prev_di_line;
|
||||
dbg_out.end_line = line;
|
||||
dbg_out.start_line = emit.prev_di_loc.line;
|
||||
dbg_out.end_line = loc.line;
|
||||
// only do this if the pc changed
|
||||
emit.prev_di_line = line;
|
||||
emit.prev_di_column = column;
|
||||
emit.prev_di_loc = loc;
|
||||
emit.prev_di_pc = emit.code.items.len;
|
||||
},
|
||||
.none => {},
|
||||
|
@ -310,6 +310,7 @@ pub fn lowerMir(lower: *Lower, index: Mir.Inst.Index) Error!struct {
|
||||
}),
|
||||
|
||||
.pseudo_dbg_prologue_end_none,
|
||||
.pseudo_dbg_line_stmt_line_column,
|
||||
.pseudo_dbg_line_line_column,
|
||||
.pseudo_dbg_epilogue_begin_none,
|
||||
.pseudo_dbg_enter_block_none,
|
||||
|
@ -930,7 +930,10 @@ pub const Inst = struct {
|
||||
|
||||
/// End of prologue
|
||||
pseudo_dbg_prologue_end_none,
|
||||
/// Update debug line
|
||||
/// Update debug line with is_stmt register set
|
||||
/// Uses `line_column` payload.
|
||||
pseudo_dbg_line_stmt_line_column,
|
||||
/// Update debug line with is_stmt register clear
|
||||
/// Uses `line_column` payload.
|
||||
pseudo_dbg_line_line_column,
|
||||
/// Start of epilogue
|
||||
|
@ -3289,6 +3289,7 @@ fn genBodyInner(f: *Function, body: []const Air.Inst.Index) error{ AnalysisFail,
|
||||
.try_ptr_cold => try airTryPtr(f, inst),
|
||||
|
||||
.dbg_stmt => try airDbgStmt(f, inst),
|
||||
.dbg_empty_stmt => try airDbgEmptyStmt(f, inst),
|
||||
.dbg_var_ptr, .dbg_var_val, .dbg_arg_inline => try airDbgVar(f, inst),
|
||||
|
||||
.float_from_int,
|
||||
@ -4601,6 +4602,11 @@ fn airDbgStmt(f: *Function, inst: Air.Inst.Index) !CValue {
|
||||
return .none;
|
||||
}
|
||||
|
||||
fn airDbgEmptyStmt(f: *Function, _: Air.Inst.Index) !CValue {
|
||||
try f.object.writer().writeAll("(void)0;\n");
|
||||
return .none;
|
||||
}
|
||||
|
||||
fn airDbgInlineBlock(f: *Function, inst: Air.Inst.Index) !CValue {
|
||||
const pt = f.object.dg.pt;
|
||||
const zcu = pt.zcu;
|
||||
|
@ -5391,6 +5391,7 @@ pub const FuncGen = struct {
|
||||
.inferred_alloc, .inferred_alloc_comptime => unreachable,
|
||||
|
||||
.dbg_stmt => try self.airDbgStmt(inst),
|
||||
.dbg_empty_stmt => try self.airDbgEmptyStmt(inst),
|
||||
.dbg_var_ptr => try self.airDbgVarPtr(inst),
|
||||
.dbg_var_val => try self.airDbgVarVal(inst, false),
|
||||
.dbg_arg_inline => try self.airDbgVarVal(inst, true),
|
||||
@ -7433,6 +7434,12 @@ pub const FuncGen = struct {
|
||||
return .none;
|
||||
}
|
||||
|
||||
fn airDbgEmptyStmt(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value {
|
||||
_ = self;
|
||||
_ = inst;
|
||||
return .none;
|
||||
}
|
||||
|
||||
fn airDbgInlineBlock(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value {
|
||||
const ty_pl = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl;
|
||||
const extra = self.air.extraData(Air.DbgInlineBlock, ty_pl.payload);
|
||||
|
@ -81,6 +81,7 @@ pub const Env = enum {
|
||||
=> true,
|
||||
.cc_command,
|
||||
.translate_c_command,
|
||||
.fmt_command,
|
||||
.jit_command,
|
||||
.fetch_command,
|
||||
.init_command,
|
||||
@ -168,6 +169,7 @@ pub const Feature = enum {
|
||||
clang_command,
|
||||
cc_command,
|
||||
translate_c_command,
|
||||
fmt_command,
|
||||
jit_command,
|
||||
fetch_command,
|
||||
init_command,
|
||||
|
@ -1474,6 +1474,11 @@ pub const WipNav = struct {
|
||||
try uleb128(dlw, column + 1);
|
||||
}
|
||||
|
||||
pub fn negateStmt(wip_nav: *WipNav) error{OutOfMemory}!void {
|
||||
const dlw = wip_nav.debug_line.writer(wip_nav.dwarf.gpa);
|
||||
try dlw.writeByte(DW.LNS.negate_stmt);
|
||||
}
|
||||
|
||||
pub fn setPrologueEnd(wip_nav: *WipNav) error{OutOfMemory}!void {
|
||||
const dlw = wip_nav.debug_line.writer(wip_nav.dwarf.gpa);
|
||||
try dlw.writeByte(DW.LNS.set_prologue_end);
|
||||
|
@ -1496,7 +1496,7 @@ pub fn updateFunc(
|
||||
});
|
||||
defer gpa.free(name);
|
||||
const osec = if (self.text_index) |sect_sym_index|
|
||||
self.symbol(sect_sym_index).output_section_index
|
||||
self.symbol(sect_sym_index).outputShndx(elf_file).?
|
||||
else osec: {
|
||||
const osec = try elf_file.addSection(.{
|
||||
.name = try elf_file.insertShString(".text"),
|
||||
|
@ -309,6 +309,7 @@ fn mainArgs(gpa: Allocator, arena: Allocator, args: []const []const u8) !void {
|
||||
.server = use_server,
|
||||
});
|
||||
} else if (mem.eql(u8, cmd, "fmt")) {
|
||||
dev.check(.fmt_command);
|
||||
return @import("fmt.zig").run(gpa, arena, cmd_args);
|
||||
} else if (mem.eql(u8, cmd, "objcopy")) {
|
||||
return jitCmd(gpa, arena, cmd_args, .{
|
||||
|
@ -202,6 +202,7 @@ const Writer = struct {
|
||||
|
||||
.trap,
|
||||
.breakpoint,
|
||||
.dbg_empty_stmt,
|
||||
.unreach,
|
||||
.ret_addr,
|
||||
.frame_addr,
|
||||
|
@ -621,6 +621,8 @@ const Writer = struct {
|
||||
.field_parent_ptr => try self.writeFieldParentPtr(stream, extended),
|
||||
.builtin_value => try self.writeBuiltinValue(stream, extended),
|
||||
.inplace_arith_result_ty => try self.writeInplaceArithResultTy(stream, extended),
|
||||
|
||||
.dbg_empty_stmt => try stream.writeAll("))"),
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -808,6 +808,424 @@ pub fn addTestsForTarget(db: *Debugger, target: Target) void {
|
||||
\\1 breakpoints deleted; 0 breakpoint locations disabled.
|
||||
},
|
||||
);
|
||||
db.addLldbTest(
|
||||
"step_single_stmt_loops",
|
||||
target,
|
||||
&.{
|
||||
.{
|
||||
.path = "step_single_stmt_loops.zig",
|
||||
.source =
|
||||
\\pub fn main() void {
|
||||
\\ var x: u32 = 0;
|
||||
\\ for (0..3) |_| {
|
||||
\\ x +%= 1;
|
||||
\\ }
|
||||
\\ {
|
||||
\\ var i: u32 = 0;
|
||||
\\ while (i < 3) : (i +%= 1) {
|
||||
\\ x +%= 1;
|
||||
\\ }
|
||||
\\ }
|
||||
\\ {
|
||||
\\ var i: u32 = 0;
|
||||
\\ while (i < 3) {
|
||||
\\ i +%= 1;
|
||||
\\ }
|
||||
\\ }
|
||||
\\ inline for (0..3) |_| {
|
||||
\\ x +%= 1;
|
||||
\\ }
|
||||
\\ {
|
||||
\\ comptime var i: u32 = 0;
|
||||
\\ inline while (i < 3) : (i +%= 1) {
|
||||
\\ x +%= 1;
|
||||
\\ }
|
||||
\\ }
|
||||
\\ {
|
||||
\\ comptime var i: u32 = 0;
|
||||
\\ inline while (i < 3) {
|
||||
\\ i +%= 1;
|
||||
\\ }
|
||||
\\ }
|
||||
\\ x +%= 1;
|
||||
\\}
|
||||
\\
|
||||
,
|
||||
},
|
||||
},
|
||||
\\breakpoint set --name step_single_stmt_loops.main
|
||||
\\process launch
|
||||
\\thread step-in
|
||||
\\#00
|
||||
\\frame variable x
|
||||
\\thread step-in
|
||||
\\#01
|
||||
\\frame variable x
|
||||
\\thread step-in
|
||||
\\#02
|
||||
\\frame variable x
|
||||
\\thread step-in
|
||||
\\#03
|
||||
\\frame variable x
|
||||
\\thread step-in
|
||||
\\#04
|
||||
\\frame variable x
|
||||
\\thread step-in
|
||||
\\#05
|
||||
\\frame variable x
|
||||
\\thread step-in
|
||||
\\#06
|
||||
\\frame variable x
|
||||
\\thread step-in
|
||||
\\#07
|
||||
\\frame variable x
|
||||
\\thread step-in
|
||||
\\#08
|
||||
\\frame variable x
|
||||
\\thread step-in
|
||||
\\#09
|
||||
\\frame variable x
|
||||
\\thread step-in
|
||||
\\#10
|
||||
\\frame variable x
|
||||
\\thread step-in
|
||||
\\#11
|
||||
\\frame variable x
|
||||
\\thread step-in
|
||||
\\#12
|
||||
\\frame variable x
|
||||
\\thread step-in
|
||||
\\#13
|
||||
\\frame variable x
|
||||
\\thread step-in
|
||||
\\#14
|
||||
\\frame variable x
|
||||
\\thread step-in
|
||||
\\#15
|
||||
\\frame variable x
|
||||
\\thread step-in
|
||||
\\#16
|
||||
\\frame variable x
|
||||
\\thread step-in
|
||||
\\#17
|
||||
\\frame variable x
|
||||
\\thread step-in
|
||||
\\#18
|
||||
\\frame variable x
|
||||
\\thread step-in
|
||||
\\#19
|
||||
\\frame variable x
|
||||
\\thread step-in
|
||||
\\#20
|
||||
\\frame variable x
|
||||
\\thread step-in
|
||||
\\#21
|
||||
\\frame variable x
|
||||
\\thread step-in
|
||||
\\#22
|
||||
\\frame variable x
|
||||
\\thread step-in
|
||||
\\#23
|
||||
\\frame variable x
|
||||
\\thread step-in
|
||||
\\#24
|
||||
\\frame variable x
|
||||
\\thread step-in
|
||||
\\#25
|
||||
\\frame variable x
|
||||
\\thread step-in
|
||||
\\#26
|
||||
\\frame variable x
|
||||
\\thread step-in
|
||||
\\#27
|
||||
\\frame variable x
|
||||
\\thread step-in
|
||||
\\#28
|
||||
\\frame variable x
|
||||
\\thread step-in
|
||||
\\#29
|
||||
\\frame variable x
|
||||
\\thread step-in
|
||||
\\#30
|
||||
\\frame variable x
|
||||
\\thread step-in
|
||||
\\#31
|
||||
\\frame variable x
|
||||
\\thread step-in
|
||||
\\#32
|
||||
\\frame variable x
|
||||
\\thread step-in
|
||||
\\#33
|
||||
\\frame variable x
|
||||
\\thread step-in
|
||||
\\#34
|
||||
\\frame variable x
|
||||
\\thread step-in
|
||||
\\#35
|
||||
\\frame variable x
|
||||
\\thread step-in
|
||||
\\#36
|
||||
\\frame variable x
|
||||
\\thread step-in
|
||||
\\#37
|
||||
\\frame variable x
|
||||
\\thread step-in
|
||||
\\#38
|
||||
\\frame variable x
|
||||
\\thread step-in
|
||||
\\#39
|
||||
\\frame variable x
|
||||
\\thread step-in
|
||||
\\#40
|
||||
\\frame variable x
|
||||
\\thread step-in
|
||||
\\#41
|
||||
\\frame variable x
|
||||
\\thread step-in
|
||||
\\#42
|
||||
\\frame variable x
|
||||
\\thread step-in
|
||||
\\#43
|
||||
\\frame variable x
|
||||
\\thread step-in
|
||||
\\#44
|
||||
\\frame variable x
|
||||
\\thread step-in
|
||||
\\#45
|
||||
\\frame variable x
|
||||
\\
|
||||
,
|
||||
&.{
|
||||
\\(lldb) #00
|
||||
\\(lldb) frame variable x
|
||||
\\(u32) x = 0
|
||||
\\(lldb) thread step-in
|
||||
,
|
||||
\\(lldb) #01
|
||||
\\(lldb) frame variable x
|
||||
\\(u32) x = 0
|
||||
\\(lldb) thread step-in
|
||||
,
|
||||
\\(lldb) #02
|
||||
\\(lldb) frame variable x
|
||||
\\(u32) x = 1
|
||||
\\(lldb) thread step-in
|
||||
,
|
||||
\\(lldb) #03
|
||||
\\(lldb) frame variable x
|
||||
\\(u32) x = 1
|
||||
\\(lldb) thread step-in
|
||||
,
|
||||
\\(lldb) #04
|
||||
\\(lldb) frame variable x
|
||||
\\(u32) x = 1
|
||||
\\(lldb) thread step-in
|
||||
,
|
||||
\\(lldb) #05
|
||||
\\(lldb) frame variable x
|
||||
\\(u32) x = 2
|
||||
\\(lldb) thread step-in
|
||||
,
|
||||
\\(lldb) #06
|
||||
\\(lldb) frame variable x
|
||||
\\(u32) x = 2
|
||||
\\(lldb) thread step-in
|
||||
,
|
||||
\\(lldb) #07
|
||||
\\(lldb) frame variable x
|
||||
\\(u32) x = 2
|
||||
\\(lldb) thread step-in
|
||||
,
|
||||
\\(lldb) #08
|
||||
\\(lldb) frame variable x
|
||||
\\(u32) x = 3
|
||||
\\(lldb) thread step-in
|
||||
,
|
||||
\\(lldb) #09
|
||||
\\(lldb) frame variable x
|
||||
\\(u32) x = 3
|
||||
\\(lldb) thread step-in
|
||||
,
|
||||
\\(lldb) #10
|
||||
\\(lldb) frame variable x
|
||||
\\(u32) x = 3
|
||||
\\(lldb) thread step-in
|
||||
,
|
||||
\\(lldb) #11
|
||||
\\(lldb) frame variable x
|
||||
\\(u32) x = 3
|
||||
\\(lldb) thread step-in
|
||||
,
|
||||
\\(lldb) #12
|
||||
\\(lldb) frame variable x
|
||||
\\(u32) x = 3
|
||||
\\(lldb) thread step-in
|
||||
,
|
||||
\\(lldb) #13
|
||||
\\(lldb) frame variable x
|
||||
\\(u32) x = 4
|
||||
\\(lldb) thread step-in
|
||||
,
|
||||
\\(lldb) #14
|
||||
\\(lldb) frame variable x
|
||||
\\(u32) x = 4
|
||||
\\(lldb) thread step-in
|
||||
,
|
||||
\\(lldb) #15
|
||||
\\(lldb) frame variable x
|
||||
\\(u32) x = 4
|
||||
\\(lldb) thread step-in
|
||||
,
|
||||
\\(lldb) #16
|
||||
\\(lldb) frame variable x
|
||||
\\(u32) x = 5
|
||||
\\(lldb) thread step-in
|
||||
,
|
||||
\\(lldb) #17
|
||||
\\(lldb) frame variable x
|
||||
\\(u32) x = 5
|
||||
\\(lldb) thread step-in
|
||||
,
|
||||
\\(lldb) #18
|
||||
\\(lldb) frame variable x
|
||||
\\(u32) x = 5
|
||||
\\(lldb) thread step-in
|
||||
,
|
||||
\\(lldb) #19
|
||||
\\(lldb) frame variable x
|
||||
\\(u32) x = 6
|
||||
\\(lldb) thread step-in
|
||||
,
|
||||
\\(lldb) #20
|
||||
\\(lldb) frame variable x
|
||||
\\(u32) x = 6
|
||||
\\(lldb) thread step-in
|
||||
,
|
||||
\\(lldb) #21
|
||||
\\(lldb) frame variable x
|
||||
\\(u32) x = 6
|
||||
\\(lldb) thread step-in
|
||||
,
|
||||
\\(lldb) #22
|
||||
\\(lldb) frame variable x
|
||||
\\(u32) x = 6
|
||||
\\(lldb) thread step-in
|
||||
,
|
||||
\\(lldb) #23
|
||||
\\(lldb) frame variable x
|
||||
\\(u32) x = 6
|
||||
\\(lldb) thread step-in
|
||||
,
|
||||
\\(lldb) #24
|
||||
\\(lldb) frame variable x
|
||||
\\(u32) x = 6
|
||||
\\(lldb) thread step-in
|
||||
,
|
||||
\\(lldb) #25
|
||||
\\(lldb) frame variable x
|
||||
\\(u32) x = 6
|
||||
\\(lldb) thread step-in
|
||||
,
|
||||
\\(lldb) #26
|
||||
\\(lldb) frame variable x
|
||||
\\(u32) x = 6
|
||||
\\(lldb) thread step-in
|
||||
,
|
||||
\\(lldb) #27
|
||||
\\(lldb) frame variable x
|
||||
\\(u32) x = 6
|
||||
\\(lldb) thread step-in
|
||||
,
|
||||
\\(lldb) #28
|
||||
\\(lldb) frame variable x
|
||||
\\(u32) x = 6
|
||||
\\(lldb) thread step-in
|
||||
,
|
||||
\\(lldb) #29
|
||||
\\(lldb) frame variable x
|
||||
\\(u32) x = 6
|
||||
\\(lldb) thread step-in
|
||||
,
|
||||
\\(lldb) #30
|
||||
\\(lldb) frame variable x
|
||||
\\(u32) x = 6
|
||||
\\(lldb) thread step-in
|
||||
,
|
||||
\\(lldb) #31
|
||||
\\(lldb) frame variable x
|
||||
\\(u32) x = 6
|
||||
\\(lldb) thread step-in
|
||||
,
|
||||
\\(lldb) #32
|
||||
\\(lldb) frame variable x
|
||||
\\(u32) x = 6
|
||||
\\(lldb) thread step-in
|
||||
,
|
||||
\\(lldb) #33
|
||||
\\(lldb) frame variable x
|
||||
\\(u32) x = 7
|
||||
\\(lldb) thread step-in
|
||||
,
|
||||
\\(lldb) #34
|
||||
\\(lldb) frame variable x
|
||||
\\(u32) x = 7
|
||||
\\(lldb) thread step-in
|
||||
,
|
||||
\\(lldb) #35
|
||||
\\(lldb) frame variable x
|
||||
\\(u32) x = 8
|
||||
\\(lldb) thread step-in
|
||||
,
|
||||
\\(lldb) #36
|
||||
\\(lldb) frame variable x
|
||||
\\(u32) x = 8
|
||||
\\(lldb) thread step-in
|
||||
,
|
||||
\\(lldb) #37
|
||||
\\(lldb) frame variable x
|
||||
\\(u32) x = 9
|
||||
\\(lldb) thread step-in
|
||||
,
|
||||
\\(lldb) #38
|
||||
\\(lldb) frame variable x
|
||||
\\(u32) x = 9
|
||||
\\(lldb) thread step-in
|
||||
,
|
||||
\\(lldb) #39
|
||||
\\(lldb) frame variable x
|
||||
\\(u32) x = 10
|
||||
\\(lldb) thread step-in
|
||||
,
|
||||
\\(lldb) #40
|
||||
\\(lldb) frame variable x
|
||||
\\(u32) x = 10
|
||||
\\(lldb) thread step-in
|
||||
,
|
||||
\\(lldb) #41
|
||||
\\(lldb) frame variable x
|
||||
\\(u32) x = 11
|
||||
\\(lldb) thread step-in
|
||||
,
|
||||
\\(lldb) #42
|
||||
\\(lldb) frame variable x
|
||||
\\(u32) x = 11
|
||||
\\(lldb) thread step-in
|
||||
,
|
||||
\\(lldb) #43
|
||||
\\(lldb) frame variable x
|
||||
\\(u32) x = 12
|
||||
\\(lldb) thread step-in
|
||||
,
|
||||
\\(lldb) #44
|
||||
\\(lldb) frame variable x
|
||||
\\(u32) x = 12
|
||||
\\(lldb) thread step-in
|
||||
,
|
||||
\\(lldb) #45
|
||||
\\(lldb) frame variable x
|
||||
\\(u32) x = 12
|
||||
},
|
||||
);
|
||||
db.addLldbTest(
|
||||
"inline_call",
|
||||
target,
|
||||
|
Loading…
Reference in New Issue
Block a user