Does zig support address sanitizer?

What the title says.

I cannot find any information on this topic so can someone enlighten me?

Address Sanitizers from c can do more as far as I know, but the std.heap.GeneralPurposeAllocator can detect memory leaks and at least in my small test case did crash upon trying to free the memory twice, although that happened mostly because it just tried to memset memory it no longer owns to 0, so I dont know if this works reliably in every case. It does not, however, detect things such as use after free.

Tools like valgrind do however work on zig, although in my experience not always on debug builds (meaning you might have to use a ReleaseSafe build)

pub fn main() !void {
    var alloc_impl: std.heap.GeneralPurposeAllocator(.{}) = .init;
    defer _ = alloc_impl.deinit();
    const allocator = alloc_impl.allocator();

    const memory = try allocator.alloc(u8, 8);
    allocator.free(memory);
    _ = memory[4];
    allocator.free(memory);
}

const std = @import("std");
Segmentation fault at address 0x7f3f622ac000
/home/markus/.local/share/zigup/0.14.0-dev.2577+271452d22/files/lib/compiler_rt/memset.zig:19:14: 0x10f18a0 in memset (compiler_rt)
            d[0] = c;
             ^
/home/markus/.local/share/zigup/0.14.0-dev.2577+271452d22/files/lib/std/mem/Allocator.zig:314:26: 0x103b5a3 in free__anon_2160 (main)
    @memset(non_const_ptr[0..bytes_len], undefined);
                         ^
/home/markus/main.zig:9:19: 0x103b140 in main (main)
    allocator.free(memory);
                  ^
/home/markus/.local/share/zigup/0.14.0-dev.2577+271452d22/files/lib/std/start.zig:656:37: 0x103af92 in posixCallMainAndExit (main)
            const result = root.main() catch |err| {
                                    ^
/home/markus/.local/share/zigup/0.14.0-dev.2577+271452d22/files/lib/std/start.zig:271:5: 0x103ab7d in _start (main)
    asm volatile (switch (native_arch) {
    ^
???:?:?: 0x0 in ??? (???)
[1]    11609 IOT instruction  zig run main.zig

I hope that this information is helpful

1 Like

Thanks. But I think its not always possible to use GeneralPurposeAllocator if you are linking to and using C libraries. It seems like valgrind is the only option then.

If you’re using Zig to compile the C, then this should work (to instrument the C code, that is):

  • If using zig build-exe, then add -cflags -fsanitize=address --
  • If using zig cc, then just -fsanitize=address
  • If using build.zig, then add "-fsanitize=address" to the flags field of the addCSourceFiles options.
  • If the C code is in a dependency, then the dependency might need to expose an option

(I’ve not tested to confirm, though)

3 Likes

In my experience, -fsanitize=address does not work with zig or at least build.zig because the api provides no way to communicate this flag to the linker which leads to compilation to fail. Maybe OP can get it working though. This is the closest issue I could find to my problems.