#Test runner causes undefined behaviour, segfault as null pointer

1 messages · Page 1 of 1 (latest)

slate glen
#

Hey! I'm using the following test runner -> https://gist.github.com/karlseguin/c6bea5b35e4e8d26af6f81c22cb5d76b

the following test works perfectly fine, no segfault issues:

test "deinitialize db tests" {
    const db = @import("../db.zig");
    const dotenv = @import("../util/dotenv.zig").dotenv;
    const allocator = std.testing.allocator;

    var env = try dotenv.init(allocator, ".testing.env");
    defer env.deinit();
    ...
}

however what it does doesn't do is wait for the other tests to finish, which is why I decided to add tests:afterAll to the test name, which results in the following stack trace

Gist

Custom Zig Test Runner, better ouput, timing display, and support for special "tests:beforeAll" and "tests:afterAll" tests - test_runner.zig

#
Segmentation fault at address 0xffffffffffffffff
path\to\zig\std\mem\Allocator.zig:269:35: 0x7ff6ecc11044 in allocBytesWithAlignment__anon_19575 (test.exe.obj)
    const byte_ptr = self.rawAlloc(byte_count, .fromByteUnits(alignment), return_address) orelse return Error.OutOfMemory;
                                  ^
path\to\zig\std\mem\Allocator.zig:260:40: 0x7ff6ecbec8d1 in allocWithSizeAndAlignment__anon_9188 (test.exe.obj)
    return self.allocBytesWithAlignment(alignment, byte_count, return_address);
                                       ^
path\to\zig\std\mem\Allocator.zig:242:41: 0x7ff6ecc1f054 in alignedAlloc__anon_22612 (test.exe.obj)
    return self.allocAdvancedWithRetAddr(T, alignment, n, @returnAddress());
                                        ^
path\to\zig\std\array_list.zig:474:67: 0x7ff6ecc24636 in ensureTotalCapacityPrecise (test.exe.obj)
                const new_memory = try self.allocator.alignedAlloc(T, alignment, new_capacity);
                                                                  ^
path\to\zig\std\array_list.zig:66:48: 0x7ff6ecc0a0b2 in initCapacity (test.exe.obj)
            try self.ensureTotalCapacityPrecise(num);
                                               ^
path\to\zig\std\unicode.zig:1784:52: 0x7ff6ecbe60b8 in wtf16LeToWtf8Alloc (test.exe.obj)
    var result = try std.ArrayList(u8).initCapacity(allocator, wtf16le.len);
                                                   ^
path\to\zig\std\process.zig:303:55: 0x7ff6ecbc24b5 in getEnvMap (test.exe.obj)
            const key = try unicode.wtf16LeToWtf8Alloc(allocator, key_w);
                                                      ^
0x7ff6ecbc19b4 in init (test.exe.obj)
        var map = try std.process.getEnvMap(allocator);
                                           ^
0x7ff6ecf3f927 in test.deinitialize db tests:afterAll (test.exe.obj)
    var env = try dotenv.init(allocator, ".testing.env");
#

the dotenv struct looks like

pub const dotenv = struct {
    map: std.process.EnvMap = undefined,
    pub fn init(allocator: Allocator, filename: ?[]const u8) !dotenv {
        var map = try std.process.getEnvMap(allocator);
        ...
      return .{.map=map}
  }
  pub fn deinit(self: *dotenv) void {
        self.map.deinit();
    }

but i dont see why its really trying to use a null pointer upon initialization, only when the test is ran in afterAll mode

#

chanigng the allocator to smp_allocator has fixed it... but why? does this segment deinitialize every testing allocator everywhere and prevent future ones from being initialized?

Gist

Custom Zig Test Runner, better ouput, timing display, and support for special "tests:beforeAll" and "tests:afterAll" tests - test_runner.zig