| 1 | const std = @import("std"); |
| 2 | const fatal = std.process.fatal; |
| 3 | |
| 4 | extern fn add(a: u32, b: u32, addr: *usize) u32; |
| 5 | |
| 6 | pub fn main(init: std.process.Init) void { |
| 7 | const io = init.io; |
| 8 | |
| 9 | var di: std.debug.SelfInfo = .init; |
| 10 | defer di.deinit(io); |
| 11 | |
| 12 | var add_addr: usize = undefined; |
| 13 | _ = add(1, 2, &add_addr); |
| 14 | |
| 15 | const debug_gpa = std.debug.getDebugInfoAllocator(); |
| 16 | const symbol_allocator = debug_gpa; |
| 17 | |
| 18 | var symbols: std.ArrayList(std.debug.Symbol) = .empty; |
| 19 | defer symbols.deinit(symbol_allocator); |
| 20 | |
| 21 | var text_arena: std.heap.ArenaAllocator = .init(debug_gpa); |
| 22 | defer text_arena.deinit(); |
| 23 | |
| 24 | di.getSymbols( |
| 25 | io, |
| 26 | symbol_allocator, |
| 27 | text_arena.allocator(), |
| 28 | add_addr, |
| 29 | false, |
| 30 | &symbols, |
| 31 | ) catch |err| fatal("failed to get symbol: {t}", .{err}); |
| 32 | |
| 33 | if (symbols.items.len != 1) fatal("expected 1 symbol, found {}", .{symbols.items.len}); |
| 34 | const symbol = symbols.items[0]; |
| 35 | |
| 36 | if (symbol.name == null) fatal("failed to resolve symbol name", .{}); |
| 37 | if (symbol.compile_unit_name == null) fatal("failed to resolve compile unit", .{}); |
| 38 | if (symbol.source_location == null) fatal("failed to resolve source location", .{}); |
| 39 | |
| 40 | if (!std.mem.eql(u8, symbol.name.?, "add")) { |
| 41 | fatal("incorrect symbol name '{s}'", .{symbol.name.?}); |
| 42 | } |
| 43 | const sl = &symbol.source_location.?; |
| 44 | if (!std.mem.eql(u8, std.fs.path.basename(sl.file_name), "shared_lib.c")) { |
| 45 | fatal("incorrect file name '{s}'", .{sl.file_name}); |
| 46 | } |
| 47 | if (sl.line != 3 or sl.column != 0) { |
| 48 | fatal("incorrect line/column :{d}:{d}", .{ sl.line, sl.column }); |
| 49 | } |
| 50 | } |