aboutsummaryrefslogtreecommitdiff
path: root/lib/std/debug.zig
diff options
context:
space:
mode:
authorJohn Schmidt <john.schmidt.h@gmail.com>2022-01-22 22:52:27 +0100
committerJakub Konka <kubkon@jakubkonka.com>2022-01-31 23:55:19 +0100
commit8e497eb32c90fdb40ea31bc968b3f4de02f91c1b (patch)
tree65c7aeb03f3d39608f30901b4633162114ab3892 /lib/std/debug.zig
parent2913950ca9deea6cbbbfea6f4592db366961c428 (diff)
downloadzig-8e497eb32c90fdb40ea31bc968b3f4de02f91c1b.tar.gz
zig-8e497eb32c90fdb40ea31bc968b3f4de02f91c1b.zip
debug: fix edge cases in macOS debug symbol lookup
This commit fixes two related things: 1. If the loop goes all the way through the slice without a match, on the last iteration `mid == symbols.len - 1` which causes `&symbols[mid + 1]` to be out of bounds. End one step before that instead. 2. If the address we're looking for is greater than the address of the last symbol in the slice, we now match it to that symbol. Previously, we would miss this case since we only matched if the address was _in between_ the address of two symbols.
Diffstat (limited to 'lib/std/debug.zig')
-rw-r--r--lib/std/debug.zig30
1 files changed, 29 insertions, 1 deletions
diff --git a/lib/std/debug.zig b/lib/std/debug.zig
index b25dabbc06..a7bfda1cd2 100644
--- a/lib/std/debug.zig
+++ b/lib/std/debug.zig
@@ -6,6 +6,7 @@ const io = std.io;
const os = std.os;
const fs = std.fs;
const process = std.process;
+const testing = std.testing;
const elf = std.elf;
const DW = std.dwarf;
const macho = std.macho;
@@ -568,7 +569,7 @@ pub const TTY = struct {
fn machoSearchSymbols(symbols: []const MachoSymbol, address: usize) ?*const MachoSymbol {
var min: usize = 0;
- var max: usize = symbols.len;
+ var max: usize = symbols.len - 1;
while (min < max) {
const mid = min + (max - min) / 2;
const curr = &symbols[mid];
@@ -581,9 +582,36 @@ fn machoSearchSymbols(symbols: []const MachoSymbol, address: usize) ?*const Mach
return curr;
}
}
+
+ const max_sym = &symbols[symbols.len - 1];
+ if (address >= max_sym.address())
+ return max_sym;
+
return null;
}
+test "machoSearchSymbols" {
+ const symbols = [_]MachoSymbol{
+ .{ .addr = 100, .strx = undefined, .size = undefined, .ofile = undefined },
+ .{ .addr = 200, .strx = undefined, .size = undefined, .ofile = undefined },
+ .{ .addr = 300, .strx = undefined, .size = undefined, .ofile = undefined },
+ };
+
+ try testing.expectEqual(@as(?*const MachoSymbol, null), machoSearchSymbols(&symbols, 0));
+ try testing.expectEqual(@as(?*const MachoSymbol, null), machoSearchSymbols(&symbols, 99));
+ try testing.expectEqual(&symbols[0], machoSearchSymbols(&symbols, 100).?);
+ try testing.expectEqual(&symbols[0], machoSearchSymbols(&symbols, 150).?);
+ try testing.expectEqual(&symbols[0], machoSearchSymbols(&symbols, 199).?);
+
+ try testing.expectEqual(&symbols[1], machoSearchSymbols(&symbols, 200).?);
+ try testing.expectEqual(&symbols[1], machoSearchSymbols(&symbols, 250).?);
+ try testing.expectEqual(&symbols[1], machoSearchSymbols(&symbols, 299).?);
+
+ try testing.expectEqual(&symbols[2], machoSearchSymbols(&symbols, 300).?);
+ try testing.expectEqual(&symbols[2], machoSearchSymbols(&symbols, 301).?);
+ try testing.expectEqual(&symbols[2], machoSearchSymbols(&symbols, 5000).?);
+}
+
/// TODO resources https://github.com/ziglang/zig/issues/4353
pub fn printSourceAtAddress(debug_info: *DebugInfo, out_stream: anytype, address: usize, tty_config: TTY.Config) !void {
const module = debug_info.getModuleForAddress(address) catch |err| switch (err) {