I am working on this project, developing on one machine, deploying it to another. Out of curiosity I wanted to run some tests on the deployment server. These tests are dependent on outside factors (eth RPC), and by accident I ran them without them properly configured. This resulted in a test failing, and leaking memory on the server.
FAILED
/root/.cache/zig/p/zabi-0.16.1-UB4phl86SABdBvFceyCgBARQTki8rNko7MLouY-TeGVQ/src/clients/IPC.zig:223:13: 0x167e744 in connect (test)
return error.FailedToConnect;
^
/root/.cache/zig/p/zabi-0.16.1-UB4phl86SABdBvFceyCgBARQTki8rNko7MLouY-TeGVQ/src/clients/IPC.zig:183:30: 0x167de09 in init (test)
self.ipc_reader.stream = try self.connect(opts.network_config.endpoint.path);
^
/root/my-project/test/modules/TokenModule.test.zig:14:18: 0x167d6e8 in test.Init, load data, and deinit (test)
var client = try IpcClient.init(.{
^
error(gpa): memory address 0x74ddd9901000 leaked:
/root/.cache/zig/p/zabi-0.16.1-UB4phl86SABdBvFceyCgBARQTki8rNko7MLouY-TeGVQ/src/clients/IPC.zig:174:43: 0x167db20 in init (test)
.buffer = try opts.allocator.alloc(u8, opts.growth_rate orelse std.math.maxInt(u16)),
^
/root/my-project/test/modules/TokenModule.test.zig:14:36: 0x167d6c3 in test.Init, load data, and deinit (test)
var client = try IpcClient.init(.{
^
/root/my-project/build/test_runner.zig:159:29: 0x128c820 in main (test)
if (test_runner.func()) |_| try runner.writeSuccess() else |err| switch (err) {
^
/root/.zvm/0.14.1/lib/std/start.zig:660:37: 0x128f667 in main (test)
const result = root.main() catch |err| {
^
LEAKED
Tests: 6 passed
Tests: 1 failed
Tests: 0 skipped
Tests: 1 leaked
Okay, I guess there is an errdefer
missing somewhere. But when I tried to recreate the same state on my development machine, I get the same error, but not a mem leak:
FAILED
/home/nixos/.cache/zig/p/zabi-0.16.1-UB4phl86SABdBvFceyCgBARQTki8rNko7MLouY-TeGVQ/src/clients/IPC.zig:226:13: 0x1673454 in connect (test)
return error.FailedToConnect;
^
/home/nixos/.cache/zig/p/zabi-0.16.1-UB4phl86SABdBvFceyCgBARQTki8rNko7MLouY-TeGVQ/src/clients/IPC.zig:186:30: 0x1672aef in init (test)
self.ipc_reader.stream = try self.connect(opts.network_config.endpoint.path);
^
/home/nixos/code/my-project/test/modules/TokenModule.test.zig:14:18: 0x16723a8 in test.Init, load data, and deinit (test)
var client = try IpcClient.init(.{
^
Tests: 6 passed
Tests: 1 failed
Tests: 0 skipped
Tests: 0 leaked
Across the two machines, I am using the same:
- Zig version - 0.14.1
- Git repo and branch
Since the leak is occuring in a third party library, it makes sense to check out it’s versioning, but it appears to be the same:
server:
zabi-0.16.1-UB4phl86SABdBvFceyCgBARQTki8rNko7MLouY-TeGVQ
development:
zabi-0.16.1-UB4phl86SABdBvFceyCgBARQTki8rNko7MLouY-TeGVQ
But for some reason, I do not understand, the Zig compiler is referring to the same lines of code apparently in different places on the two machines:
server:
.../IPC.zig:183:30: 0x167de09 in init (test) self.ipc_reader.stream = try self.connect(opts.network_config.endpoint.path);
development:
...IPC.zig:186:30: 0x1672aef in init (test) self.ipc_reader.stream = try self.connect(opts.network_config.endpoint.path);
What am I missing here?
Edit:
I have checked the sha256sums of the two files, and they aren’t matching. When I checked for diffs, I got this:
+++ b/root/.cache/zig/p/zabi-0.16.1-UB4phl86SABdBvFceyCgBARQTki8rNko7MLouY-TeGVQ/src/clients/IPC.zig
@@ -169,12 +169,9 @@ pub fn init(opts: InitOptions) InitErrors!*IPC {
self.sub_channel.deinit();
}
- const buffer = try opts.allocator.alloc(u8, opts.growth_rate orelse std.math.maxInt(u16));
- errdefer opts.allocator.free(buffer);
-
self.ipc_reader = .{
.allocator = opts.allocator,
- .buffer = buffer,
+ .buffer = try opts.allocator.alloc(u8, opts.growth_rate orelse std.math.maxInt(u16)),
.growth_rate = opts.growth_rate orelse std.math.maxInt(u16),
.stream = undefined,
.closed = false,
Okay so it’s not the same code? I am completely lost.