mirror of
https://github.com/ziglang/zig.git
synced 2025-12-06 06:13:07 +00:00
dwarf: fix the unwinder using the incorrect row from the FDE in certain cases
This commit is contained in:
parent
1a2bb70956
commit
d99b40d38b
@ -1740,8 +1740,20 @@ pub const DwarfInfo = struct {
|
|||||||
context.reg_context.eh_frame = cie.version != 4;
|
context.reg_context.eh_frame = cie.version != 4;
|
||||||
context.reg_context.is_macho = di.is_macho;
|
context.reg_context.is_macho = di.is_macho;
|
||||||
|
|
||||||
_ = try context.vm.runToNative(context.allocator, context.pc, cie, fde);
|
if (comptime builtin.target.isDarwin()) {
|
||||||
const row = &context.vm.current_row;
|
std.debug.print(" state before:\n", .{});
|
||||||
|
std.debug.print(" cfa {?x}:\n", .{context.cfa});
|
||||||
|
for (context.thread_context.mcontext.ss.regs, 0..) |reg, i| {
|
||||||
|
std.debug.print(" {}:0x{x}\n", .{i, reg});
|
||||||
|
}
|
||||||
|
std.debug.print(" fp:0x{x}\n", .{context.thread_context.mcontext.ss.fp});
|
||||||
|
std.debug.print(" lr:0x{x}\n", .{context.thread_context.mcontext.ss.lr});
|
||||||
|
std.debug.print(" sp:0x{x}\n", .{context.thread_context.mcontext.ss.sp});
|
||||||
|
std.debug.print(" pc:0x{x}\n", .{context.thread_context.mcontext.ss.pc});
|
||||||
|
}
|
||||||
|
|
||||||
|
const row = try context.vm.runToNative(context.allocator, context.pc, cie, fde);
|
||||||
|
std.debug.print(" ran to 0x{x}\n", .{row.offset + fde.pc_begin});
|
||||||
|
|
||||||
context.cfa = switch (row.cfa.rule) {
|
context.cfa = switch (row.cfa.rule) {
|
||||||
.val_offset => |offset| blk: {
|
.val_offset => |offset| blk: {
|
||||||
@ -1785,7 +1797,7 @@ pub const DwarfInfo = struct {
|
|||||||
|
|
||||||
var update_tail: ?*RegisterUpdate = null;
|
var update_tail: ?*RegisterUpdate = null;
|
||||||
var has_next_ip = false;
|
var has_next_ip = false;
|
||||||
for (context.vm.rowColumns(row.*)) |column| {
|
for (context.vm.rowColumns(row)) |column| {
|
||||||
if (column.register) |register| {
|
if (column.register) |register| {
|
||||||
if (register == cie.return_address_register) {
|
if (register == cie.return_address_register) {
|
||||||
has_next_ip = column.rule != .undefined;
|
has_next_ip = column.rule != .undefined;
|
||||||
|
|||||||
@ -395,9 +395,7 @@ pub const VirtualMachine = struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Runs the CIE instructions, then the FDE instructions. Execution halts
|
/// Runs the CIE instructions, then the FDE instructions. Execution halts
|
||||||
/// once the row that corresponds to `pc` is known (and set as `current_row`).
|
/// once the row that corresponds to `pc` is known, and the row is returned.
|
||||||
///
|
|
||||||
/// The state of the row prior to the last execution step is returned.
|
|
||||||
pub fn runTo(
|
pub fn runTo(
|
||||||
self: *VirtualMachine,
|
self: *VirtualMachine,
|
||||||
allocator: std.mem.Allocator,
|
allocator: std.mem.Allocator,
|
||||||
@ -419,17 +417,15 @@ pub const VirtualMachine = struct {
|
|||||||
&fde_stream,
|
&fde_stream,
|
||||||
};
|
};
|
||||||
|
|
||||||
outer: for (&streams, 0..) |stream, i| {
|
for (&streams, 0..) |stream, i| {
|
||||||
while (stream.pos < stream.buffer.len) {
|
while (stream.pos < stream.buffer.len) {
|
||||||
const instruction = try dwarf.call_frame.Instruction.read(stream, addr_size_bytes, endian);
|
const instruction = try dwarf.call_frame.Instruction.read(stream, addr_size_bytes, endian);
|
||||||
prev_row = try self.step(allocator, cie, i == 0, instruction);
|
prev_row = try self.step(allocator, cie, i == 0, instruction);
|
||||||
if (pc < fde.pc_begin + self.current_row.offset) {
|
if (pc < fde.pc_begin + self.current_row.offset) return prev_row;
|
||||||
break :outer;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return prev_row;
|
return self.current_row;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn runToNative(
|
pub fn runToNative(
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user