authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2019-11-17 22:29:17+00:00
committergravatar for noreply@github.comGitHub <noreply@github.com> 2019-11-17 22:29:17+00:00
log8e3370367bbbcae43670380cb4ca841a9e5ada33
tree5ba2f971ef4c209c97d23742e667eb6afe28156f
parent924dd674e2e584bbef5e7650f481e49829c8fe28
parentd870a68e680242d130dcecef1f1ccc0969f326c0
signaturebadge-question-mark Signed by PGP key 4AEE18F83AFDEB23

Merge pull request #3705 from daurnimator/fix-std.valgrind

std: fix outdated valgrind module

3 files changed, 111 insertions(+), 62 deletions(-)

lib/std/valgrind.zig+44-34
......@@ -1,5 +1,6 @@
11const builtin = @import("builtin");
2const math = @import("index.zig").math;
2const std = @import("std.zig");
3const math = std.math;
34
45pub fn doClientRequest(default: usize, request: usize, a1: usize, a2: usize, a3: usize, a4: usize, a5: usize) usize {
56 if (!builtin.valgrind_support) {
......@@ -13,7 +14,7 @@ pub fn doClientRequest(default: usize, request: usize, a1: usize, a2: usize, a3:
1314 \\ roll $29, %%edi ; roll $19, %%edi
1415 \\ xchgl %%ebx,%%ebx
1516 : [_] "={edx}" (-> usize)
16 : [_] "{eax}" (&[]usize{ request, a1, a2, a3, a4, a5 }),
17 : [_] "{eax}" (&[_]usize{ request, a1, a2, a3, a4, a5 }),
1718 [_] "0" (default)
1819 : "cc", "memory"
1920 );
......@@ -24,7 +25,7 @@ pub fn doClientRequest(default: usize, request: usize, a1: usize, a2: usize, a3:
2425 \\ rolq $61, %%rdi ; rolq $51, %%rdi
2526 \\ xchgq %%rbx,%%rbx
2627 : [_] "={rdx}" (-> usize)
27 : [_] "{rax}" (&[]usize{ request, a1, a2, a3, a4, a5 }),
28 : [_] "{rax}" (&[_]usize{ request, a1, a2, a3, a4, a5 }),
2829 [_] "0" (default)
2930 : "cc", "memory"
3031 );
......@@ -95,48 +96,52 @@ fn doClientRequestStmt(request: ClientRequest, a1: usize, a2: usize, a3: usize,
9596/// running under Valgrind which is running under another Valgrind,
9697/// etc.
9798pub fn runningOnValgrind() usize {
98 return doClientRequestExpr(0, ClientRequest.RunningOnValgrind, 0, 0, 0, 0, 0);
99 return doClientRequestExpr(0, .RunningOnValgrind, 0, 0, 0, 0, 0);
100}
101
102test "works whether running on valgrind or not" {
103 _ = runningOnValgrind();
99104}
100105
101106/// Discard translation of code in the slice qzz. Useful if you are debugging
102107/// a JITter or some such, since it provides a way to make sure valgrind will
103108/// retranslate the invalidated area. Returns no value.
104109pub fn discardTranslations(qzz: []const u8) void {
105 doClientRequestStmt(ClientRequest.DiscardTranslations, @ptrToInt(qzz.ptr), qzz.len, 0, 0, 0);
110 doClientRequestStmt(.DiscardTranslations, @ptrToInt(qzz.ptr), qzz.len, 0, 0, 0);
106111}
107112
108113pub fn innerThreads(qzz: [*]u8) void {
109 doClientRequestStmt(ClientRequest.InnerThreads, qzz, 0, 0, 0, 0);
114 doClientRequestStmt(.InnerThreads, qzz, 0, 0, 0, 0);
110115}
111116
112117//pub fn printf(format: [*]const u8, args: ...) usize {
113118// return doClientRequestExpr(0,
114// ClientRequest.PrintfValistByRef,
119// .PrintfValistByRef,
115120// @ptrToInt(format), @ptrToInt(args),
116121// 0, 0, 0);
117122//}
118123
119124//pub fn printfBacktrace(format: [*]const u8, args: ...) usize {
120125// return doClientRequestExpr(0,
121// ClientRequest.PrintfBacktraceValistByRef,
126// .PrintfBacktraceValistByRef,
122127// @ptrToInt(format), @ptrToInt(args),
123128// 0, 0, 0);
124129//}
125130
126131pub fn nonSIMDCall0(func: fn (usize) usize) usize {
127 return doClientRequestExpr(0, ClientRequest.ClientCall0, @ptrToInt(func), 0, 0, 0, 0);
132 return doClientRequestExpr(0, .ClientCall0, @ptrToInt(func), 0, 0, 0, 0);
128133}
129134
130135pub fn nonSIMDCall1(func: fn (usize, usize) usize, a1: usize) usize {
131 return doClientRequestExpr(0, ClientRequest.ClientCall1, @ptrToInt(func), a1, 0, 0, 0);
136 return doClientRequestExpr(0, .ClientCall1, @ptrToInt(func), a1, 0, 0, 0);
132137}
133138
134139pub fn nonSIMDCall2(func: fn (usize, usize, usize) usize, a1: usize, a2: usize) usize {
135 return doClientRequestExpr(0, ClientRequest.ClientCall2, @ptrToInt(func), a1, a2, 0, 0);
140 return doClientRequestExpr(0, .ClientCall2, @ptrToInt(func), a1, a2, 0, 0);
136141}
137142
138143pub fn nonSIMDCall3(func: fn (usize, usize, usize, usize) usize, a1: usize, a2: usize, a3: usize) usize {
139 return doClientRequestExpr(0, ClientRequest.ClientCall3, @ptrToInt(func), a1, a2, a3, 0);
144 return doClientRequestExpr(0, .ClientCall3, @ptrToInt(func), a1, a2, a3, 0);
140145}
141146
142147/// Counts the number of errors that have been recorded by a tool. Nb:
......@@ -144,19 +149,19 @@ pub fn nonSIMDCall3(func: fn (usize, usize, usize, usize) usize, a1: usize, a2:
144149/// VG_(unique_error)() for them to be counted.
145150pub fn countErrors() usize {
146151 return doClientRequestExpr(0, // default return
147 ClientRequest.CountErrors, 0, 0, 0, 0, 0);
152 .CountErrors, 0, 0, 0, 0, 0);
148153}
149154
150155pub fn mallocLikeBlock(mem: []u8, rzB: usize, is_zeroed: bool) void {
151 doClientRequestStmt(ClientRequest.MalloclikeBlock, @ptrToInt(mem.ptr), mem.len, rzB, @boolToInt(is_zeroed), 0);
156 doClientRequestStmt(.MalloclikeBlock, @ptrToInt(mem.ptr), mem.len, rzB, @boolToInt(is_zeroed), 0);
152157}
153158
154159pub fn resizeInPlaceBlock(oldmem: []u8, newsize: usize, rzB: usize) void {
155 doClientRequestStmt(ClientRequest.ResizeinplaceBlock, @ptrToInt(oldmem.ptr), oldmem.len, newsize, rzB, 0);
160 doClientRequestStmt(.ResizeinplaceBlock, @ptrToInt(oldmem.ptr), oldmem.len, newsize, rzB, 0);
156161}
157162
158163pub fn freeLikeBlock(addr: [*]u8, rzB: usize) void {
159 doClientRequestStmt(ClientRequest.FreelikeBlock, @ptrToInt(addr), rzB, 0, 0, 0);
164 doClientRequestStmt(.FreelikeBlock, @ptrToInt(addr), rzB, 0, 0, 0);
160165}
161166
162167/// Create a memory pool.
......@@ -165,66 +170,66 @@ pub const MempoolFlags = extern enum {
165170 MetaPool = 2,
166171};
167172pub fn createMempool(pool: [*]u8, rzB: usize, is_zeroed: bool, flags: usize) void {
168 doClientRequestStmt(ClientRequest.CreateMempool, @ptrToInt(pool), rzB, @boolToInt(is_zeroed), flags, 0);
173 doClientRequestStmt(.CreateMempool, @ptrToInt(pool), rzB, @boolToInt(is_zeroed), flags, 0);
169174}
170175
171176/// Destroy a memory pool.
172177pub fn destroyMempool(pool: [*]u8) void {
173 doClientRequestStmt(ClientRequest.DestroyMempool, pool, 0, 0, 0, 0);
178 doClientRequestStmt(.DestroyMempool, pool, 0, 0, 0, 0);
174179}
175180
176181/// Associate a piece of memory with a memory pool.
177182pub fn mempoolAlloc(pool: [*]u8, mem: []u8) void {
178 doClientRequestStmt(ClientRequest.MempoolAlloc, @ptrToInt(pool), @ptrToInt(mem.ptr), mem.len, 0, 0);
183 doClientRequestStmt(.MempoolAlloc, @ptrToInt(pool), @ptrToInt(mem.ptr), mem.len, 0, 0);
179184}
180185
181186/// Disassociate a piece of memory from a memory pool.
182187pub fn mempoolFree(pool: [*]u8, addr: [*]u8) void {
183 doClientRequestStmt(ClientRequest.MempoolFree, @ptrToInt(pool), @ptrToInt(addr), 0, 0, 0);
188 doClientRequestStmt(.MempoolFree, @ptrToInt(pool), @ptrToInt(addr), 0, 0, 0);
184189}
185190
186191/// Disassociate any pieces outside a particular range.
187192pub fn mempoolTrim(pool: [*]u8, mem: []u8) void {
188 doClientRequestStmt(ClientRequest.MempoolTrim, @ptrToInt(pool), @ptrToInt(mem.ptr), mem.len, 0, 0);
193 doClientRequestStmt(.MempoolTrim, @ptrToInt(pool), @ptrToInt(mem.ptr), mem.len, 0, 0);
189194}
190195
191196/// Resize and/or move a piece associated with a memory pool.
192197pub fn moveMempool(poolA: [*]u8, poolB: [*]u8) void {
193 doClientRequestStmt(ClientRequest.MoveMempool, @ptrToInt(poolA), @ptrToInt(poolB), 0, 0, 0);
198 doClientRequestStmt(.MoveMempool, @ptrToInt(poolA), @ptrToInt(poolB), 0, 0, 0);
194199}
195200
196201/// Resize and/or move a piece associated with a memory pool.
197202pub fn mempoolChange(pool: [*]u8, addrA: [*]u8, mem: []u8) void {
198 doClientRequestStmt(ClientRequest.MempoolChange, @ptrToInt(pool), @ptrToInt(addrA), @ptrToInt(mem.ptr), mem.len, 0);
203 doClientRequestStmt(.MempoolChange, @ptrToInt(pool), @ptrToInt(addrA), @ptrToInt(mem.ptr), mem.len, 0);
199204}
200205
201206/// Return if a mempool exists.
202207pub fn mempoolExists(pool: [*]u8) bool {
203 return doClientRequestExpr(0, ClientRequest.MempoolExists, @ptrToInt(pool), 0, 0, 0, 0) != 0;
208 return doClientRequestExpr(0, .MempoolExists, @ptrToInt(pool), 0, 0, 0, 0) != 0;
204209}
205210
206211/// Mark a piece of memory as being a stack. Returns a stack id.
207212/// start is the lowest addressable stack byte, end is the highest
208213/// addressable stack byte.
209214pub fn stackRegister(stack: []u8) usize {
210 return doClientRequestExpr(0, ClientRequest.StackRegister, @ptrToInt(stack.ptr), @ptrToInt(stack.ptr) + stack.len, 0, 0, 0);
215 return doClientRequestExpr(0, .StackRegister, @ptrToInt(stack.ptr), @ptrToInt(stack.ptr) + stack.len, 0, 0, 0);
211216}
212217
213218/// Unmark the piece of memory associated with a stack id as being a stack.
214219pub fn stackDeregister(id: usize) void {
215 doClientRequestStmt(ClientRequest.StackDeregister, id, 0, 0, 0, 0);
220 doClientRequestStmt(.StackDeregister, id, 0, 0, 0, 0);
216221}
217222
218223/// Change the start and end address of the stack id.
219224/// start is the new lowest addressable stack byte, end is the new highest
220225/// addressable stack byte.
221226pub fn stackChange(id: usize, newstack: []u8) void {
222 doClientRequestStmt(ClientRequest.StackChange, id, @ptrToInt(newstack.ptr), @ptrToInt(newstack.ptr) + newstack.len, 0, 0);
227 doClientRequestStmt(.StackChange, id, @ptrToInt(newstack.ptr), @ptrToInt(newstack.ptr) + newstack.len, 0, 0);
223228}
224229
225230// Load PDB debug info for Wine PE image_map.
226231// pub fn loadPdbDebuginfo(fd, ptr, total_size, delta) void {
227// doClientRequestStmt(ClientRequest.LoadPdbDebuginfo,
232// doClientRequestStmt(.LoadPdbDebuginfo,
228233// fd, ptr, total_size, delta,
229234// 0);
230235// }
......@@ -234,7 +239,7 @@ pub fn stackChange(id: usize, newstack: []u8) void {
234239/// result will be dumped in there and is guaranteed to be zero
235240/// terminated. If no info is found, the first byte is set to zero.
236241pub fn mapIpToSrcloc(addr: *const u8, buf64: [64]u8) usize {
237 return doClientRequestExpr(0, ClientRequest.MapIpToSrcloc, @ptrToInt(addr), @ptrToInt(&buf64[0]), 0, 0, 0);
242 return doClientRequestExpr(0, .MapIpToSrcloc, @ptrToInt(addr), @ptrToInt(&buf64[0]), 0, 0, 0);
238243}
239244
240245/// Disable error reporting for this thread. Behaves in a stack like
......@@ -246,12 +251,12 @@ pub fn mapIpToSrcloc(addr: *const u8, buf64: [64]u8) usize {
246251/// reporting. Child threads do not inherit this setting from their
247252/// parents -- they are always created with reporting enabled.
248253pub fn disableErrorReporting() void {
249 doClientRequestStmt(ClientRequest.ChangeErrDisablement, 1, 0, 0, 0, 0);
254 doClientRequestStmt(.ChangeErrDisablement, 1, 0, 0, 0, 0);
250255}
251256
252257/// Re-enable error reporting, (see disableErrorReporting())
253258pub fn enableErrorReporting() void {
254 doClientRequestStmt(ClientRequest.ChangeErrDisablement, math.maxInt(usize), 0, 0, 0, 0);
259 doClientRequestStmt(.ChangeErrDisablement, math.maxInt(usize), 0, 0, 0, 0);
255260}
256261
257262/// Execute a monitor command from the client program.
......@@ -260,8 +265,13 @@ pub fn enableErrorReporting() void {
260265/// If no connection is opened, output will go to the log output.
261266/// Returns 1 if command not recognised, 0 otherwise.
262267pub fn monitorCommand(command: [*]u8) bool {
263 return doClientRequestExpr(0, ClientRequest.GdbMonitorCommand, @ptrToInt(command.ptr), 0, 0, 0, 0) != 0;
268 return doClientRequestExpr(0, .GdbMonitorCommand, @ptrToInt(command.ptr), 0, 0, 0, 0) != 0;
264269}
265270
266pub const memcheck = @import("memcheck.zig");
267pub const callgrind = @import("callgrind.zig");
271pub const memcheck = @import("valgrind/memcheck.zig");
272pub const callgrind = @import("valgrind/callgrind.zig");
273
274test "" {
275 _ = @import("valgrind/memcheck.zig");
276 _ = @import("valgrind/callgrind.zig");
277}
lib/std/valgrind/callgrind.zig+7-7
......@@ -1,4 +1,4 @@
1const std = @import("../index.zig");
1const std = @import("../std.zig");
22const valgrind = std.valgrind;
33
44pub const CallgrindClientRequest = extern enum {
......@@ -20,7 +20,7 @@ fn doCallgrindClientRequestStmt(request: CallgrindClientRequest, a1: usize, a2:
2020
2121/// Dump current state of cost centers, and zero them afterwards
2222pub fn dumpStats() void {
23 doCallgrindClientRequestStmt(CallgrindClientRequest.DumpStats, 0, 0, 0, 0, 0);
23 doCallgrindClientRequestStmt(.DumpStats, 0, 0, 0, 0, 0);
2424}
2525
2626/// Dump current state of cost centers, and zero them afterwards.
......@@ -28,12 +28,12 @@ pub fn dumpStats() void {
2828/// the dump. This string is written as a description field into the
2929/// profile data dump.
3030pub fn dumpStatsAt(pos_str: [*]u8) void {
31 doCallgrindClientRequestStmt(CallgrindClientRequest.DumpStatsAt, @ptrToInt(pos_str), 0, 0, 0, 0);
31 doCallgrindClientRequestStmt(.DumpStatsAt, @ptrToInt(pos_str), 0, 0, 0, 0);
3232}
3333
3434/// Zero cost centers
3535pub fn zeroStats() void {
36 doCallgrindClientRequestStmt(CallgrindClientRequest.ZeroStats, 0, 0, 0, 0, 0);
36 doCallgrindClientRequestStmt(.ZeroStats, 0, 0, 0, 0, 0);
3737}
3838
3939/// Toggles collection state.
......@@ -41,7 +41,7 @@ pub fn zeroStats() void {
4141/// should be noted or if they are to be ignored. Events are noted
4242/// by increment of counters in a cost center
4343pub fn toggleCollect() void {
44 doCallgrindClientRequestStmt(CallgrindClientRequest.ToggleCollect, 0, 0, 0, 0, 0);
44 doCallgrindClientRequestStmt(.ToggleCollect, 0, 0, 0, 0, 0);
4545}
4646
4747/// Start full callgrind instrumentation if not already switched on.
......@@ -49,7 +49,7 @@ pub fn toggleCollect() void {
4949/// this will lead to an artificial cache warmup phase afterwards with
5050/// cache misses which would not have happened in reality.
5151pub fn startInstrumentation() void {
52 doCallgrindClientRequestStmt(CallgrindClientRequest.StartInstrumentation, 0, 0, 0, 0, 0);
52 doCallgrindClientRequestStmt(.StartInstrumentation, 0, 0, 0, 0, 0);
5353}
5454
5555/// Stop full callgrind instrumentation if not already switched off.
......@@ -60,5 +60,5 @@ pub fn startInstrumentation() void {
6060/// To start Callgrind in this mode to ignore the setup phase, use
6161/// the option "--instr-atstart=no".
6262pub fn stopInstrumentation() void {
63 doCallgrindClientRequestStmt(CallgrindClientRequest.StopInstrumentation, 0, 0, 0, 0, 0);
63 doCallgrindClientRequestStmt(.StopInstrumentation, 0, 0, 0, 0, 0);
6464}
lib/std/valgrind/memcheck.zig+60-21
......@@ -1,4 +1,5 @@
1const std = @import("../index.zig");
1const std = @import("../std.zig");
2const testing = std.testing;
23const valgrind = std.valgrind;
34
45pub const MemCheckClientRequest = extern enum {
......@@ -31,7 +32,7 @@ fn doMemCheckClientRequestStmt(request: MemCheckClientRequest, a1: usize, a2: us
3132/// This returns -1 when run on Valgrind and 0 otherwise.
3233pub fn makeMemNoAccess(qzz: []u8) i1 {
3334 return @intCast(i1, doMemCheckClientRequestExpr(0, // default return
34 MemCheckClientRequest.MakeMemNoAccess, @ptrToInt(qzz.ptr), qzz.len, 0, 0, 0));
35 .MakeMemNoAccess, @ptrToInt(qzz.ptr), qzz.len, 0, 0, 0));
3536}
3637
3738/// Similarly, mark memory at qzz.ptr as addressable but undefined
......@@ -39,7 +40,7 @@ pub fn makeMemNoAccess(qzz: []u8) i1 {
3940/// This returns -1 when run on Valgrind and 0 otherwise.
4041pub fn makeMemUndefined(qzz: []u8) i1 {
4142 return @intCast(i1, doMemCheckClientRequestExpr(0, // default return
42 MemCheckClientRequest.MakeMemUndefined, @ptrToInt(qzz.ptr), qzz.len, 0, 0, 0));
43 .MakeMemUndefined, @ptrToInt(qzz.ptr), qzz.len, 0, 0, 0));
4344}
4445
4546/// Similarly, mark memory at qzz.ptr as addressable and defined
......@@ -47,7 +48,7 @@ pub fn makeMemUndefined(qzz: []u8) i1 {
4748pub fn makeMemDefined(qzz: []u8) i1 {
4849 // This returns -1 when run on Valgrind and 0 otherwise.
4950 return @intCast(i1, doMemCheckClientRequestExpr(0, // default return
50 MemCheckClientRequest.MakeMemDefined, @ptrToInt(qzz.ptr), qzz.len, 0, 0, 0));
51 .MakeMemDefined, @ptrToInt(qzz.ptr), qzz.len, 0, 0, 0));
5152}
5253
5354/// Similar to makeMemDefined except that addressability is
......@@ -56,7 +57,7 @@ pub fn makeMemDefined(qzz: []u8) i1 {
5657/// This returns -1 when run on Valgrind and 0 otherwise.
5758pub fn makeMemDefinedIfAddressable(qzz: []u8) i1 {
5859 return @intCast(i1, doMemCheckClientRequestExpr(0, // default return
59 MemCheckClientRequest.MakeMemDefinedIfAddressable, @ptrToInt(qzz.ptr), qzz.len, 0, 0, 0));
60 .MakeMemDefinedIfAddressable, @ptrToInt(qzz.ptr), qzz.len, 0, 0, 0));
6061}
6162
6263/// Create a block-description handle. The description is an ascii
......@@ -65,14 +66,14 @@ pub fn makeMemDefinedIfAddressable(qzz: []u8) i1 {
6566/// properties of the memory range.
6667pub fn createBlock(qzz: []u8, desc: [*]u8) usize {
6768 return doMemCheckClientRequestExpr(0, // default return
68 MemCheckClientRequest.CreateBlock, @ptrToInt(qzz.ptr), qzz.len, @ptrToInt(desc), 0, 0);
69 .CreateBlock, @ptrToInt(qzz.ptr), qzz.len, @ptrToInt(desc), 0, 0);
6970}
7071
7172/// Discard a block-description-handle. Returns 1 for an
7273/// invalid handle, 0 for a valid handle.
7374pub fn discard(blkindex) bool {
7475 return doMemCheckClientRequestExpr(0, // default return
75 MemCheckClientRequest.Discard, 0, blkindex, 0, 0, 0) != 0;
76 .Discard, 0, blkindex, 0, 0, 0) != 0;
7677}
7778
7879/// Check that memory at qzz.ptr is addressable for qzz.len bytes.
......@@ -80,7 +81,7 @@ pub fn discard(blkindex) bool {
8081/// error message and returns the address of the first offending byte.
8182/// Otherwise it returns zero.
8283pub fn checkMemIsAddressable(qzz: []u8) usize {
83 return doMemCheckClientRequestExpr(0, MemCheckClientRequest.CheckMemIsAddressable, @ptrToInt(qzz.ptr), qzz.len, 0, 0, 0);
84 return doMemCheckClientRequestExpr(0, .CheckMemIsAddressable, @ptrToInt(qzz.ptr), qzz.len, 0, 0, 0);
8485}
8586
8687/// Check that memory at qzz.ptr is addressable and defined for
......@@ -88,31 +89,31 @@ pub fn checkMemIsAddressable(qzz: []u8) usize {
8889/// established, Valgrind prints an error message and returns the
8990/// address of the first offending byte. Otherwise it returns zero.
9091pub fn checkMemIsDefined(qzz: []u8) usize {
91 return doMemCheckClientRequestExpr(0, MemCheckClientRequest.CheckMemIsDefined, @ptrToInt(qzz.ptr), qzz.len, 0, 0, 0);
92 return doMemCheckClientRequestExpr(0, .CheckMemIsDefined, @ptrToInt(qzz.ptr), qzz.len, 0, 0, 0);
9293}
9394
9495/// Do a full memory leak check (like --leak-check=full) mid-execution.
9596pub fn doLeakCheck() void {
96 doMemCheckClientRequestStmt(MemCheckClientRequest.DO_LEAK_CHECK, 0, 0, 0, 0, 0);
97 doMemCheckClientRequestStmt(.DO_LEAK_CHECK, 0, 0, 0, 0, 0);
9798}
9899
99100/// Same as doLeakCheck() but only showing the entries for
100101/// which there was an increase in leaked bytes or leaked nr of blocks
101102/// since the previous leak search.
102103pub fn doAddedLeakCheck() void {
103 doMemCheckClientRequestStmt(MemCheckClientRequest.DO_LEAK_CHECK, 0, 1, 0, 0, 0);
104 doMemCheckClientRequestStmt(.DO_LEAK_CHECK, 0, 1, 0, 0, 0);
104105}
105106
106107/// Same as doAddedLeakCheck() but showing entries with
107108/// increased or decreased leaked bytes/blocks since previous leak
108109/// search.
109110pub fn doChangedLeakCheck() void {
110 doMemCheckClientRequestStmt(MemCheckClientRequest.DO_LEAK_CHECK, 0, 2, 0, 0, 0);
111 doMemCheckClientRequestStmt(.DO_LEAK_CHECK, 0, 2, 0, 0, 0);
111112}
112113
113114/// Do a summary memory leak check (like --leak-check=summary) mid-execution.
114115pub fn doQuickLeakCheck() void {
115 doMemCheckClientRequestStmt(MemCheckClientRequest.DO_LEAK_CHECK, 1, 0, 0, 0, 0);
116 doMemCheckClientRequestStmt(.DO_LEAK_CHECK, 1, 0, 0, 0, 0);
116117}
117118
118119/// Return number of leaked, dubious, reachable and suppressed bytes found by
......@@ -125,27 +126,65 @@ const CountResult = struct {
125126};
126127
127128pub fn countLeaks() CountResult {
128 var res = CountResult{
129 var res: CountResult = .{
129130 .leaked = 0,
130131 .dubious = 0,
131132 .reachable = 0,
132133 .suppressed = 0,
133134 };
134 doMemCheckClientRequestStmt(MemCheckClientRequest.CountLeaks, &res.leaked, &res.dubious, &res.reachable, &res.suppressed, 0);
135 doMemCheckClientRequestStmt(
136 .CountLeaks,
137 @ptrToInt(&res.leaked),
138 @ptrToInt(&res.dubious),
139 @ptrToInt(&res.reachable),
140 @ptrToInt(&res.suppressed),
141 0,
142 );
135143 return res;
136144}
137145
146test "countLeaks" {
147 testing.expectEqual(
148 @as(CountResult, .{
149 .leaked = 0,
150 .dubious = 0,
151 .reachable = 0,
152 .suppressed = 0,
153 }),
154 countLeaks(),
155 );
156}
157
138158pub fn countLeakBlocks() CountResult {
139 var res = CountResult{
159 var res: CountResult = .{
140160 .leaked = 0,
141161 .dubious = 0,
142162 .reachable = 0,
143163 .suppressed = 0,
144164 };
145 doMemCheckClientRequestStmt(MemCheckClientRequest.CountLeakBlocks, &res.leaked, &res.dubious, &res.reachable, &res.suppressed, 0);
165 doMemCheckClientRequestStmt(
166 .CountLeakBlocks,
167 @ptrToInt(&res.leaked),
168 @ptrToInt(&res.dubious),
169 @ptrToInt(&res.reachable),
170 @ptrToInt(&res.suppressed),
171 0,
172 );
146173 return res;
147174}
148175
176test "countLeakBlocks" {
177 testing.expectEqual(
178 @as(CountResult, .{
179 .leaked = 0,
180 .dubious = 0,
181 .reachable = 0,
182 .suppressed = 0,
183 }),
184 countLeakBlocks(),
185 );
186}
187
149188/// Get the validity data for addresses zza and copy it
150189/// into the provided zzvbits array. Return values:
151190/// 0 if not running on valgrind
......@@ -156,7 +195,7 @@ pub fn countLeakBlocks() CountResult {
156195/// impossible to segfault your system by using this call.
157196pub fn getVbits(zza: []u8, zzvbits: []u8) u2 {
158197 std.debug.assert(zzvbits.len >= zza.len / 8);
159 return @intCast(u2, doMemCheckClientRequestExpr(0, MemCheckClientRequest.GetVbits, @ptrToInt(zza.ptr), @ptrToInt(zzvbits), zza.len, 0, 0));
198 return @intCast(u2, doMemCheckClientRequestExpr(0, .GetVbits, @ptrToInt(zza.ptr), @ptrToInt(zzvbits), zza.len, 0, 0));
160199}
161200
162201/// Set the validity data for addresses zza, copying it
......@@ -169,17 +208,17 @@ pub fn getVbits(zza: []u8, zzvbits: []u8) u2 {
169208/// impossible to segfault your system by using this call.
170209pub fn setVbits(zzvbits: []u8, zza: []u8) u2 {
171210 std.debug.assert(zzvbits.len >= zza.len / 8);
172 return @intCast(u2, doMemCheckClientRequestExpr(0, MemCheckClientRequest.SetVbits, @ptrToInt(zza.ptr), @ptrToInt(zzvbits), zza.len, 0, 0));
211 return @intCast(u2, doMemCheckClientRequestExpr(0, .SetVbits, @ptrToInt(zza.ptr), @ptrToInt(zzvbits), zza.len, 0, 0));
173212}
174213
175214/// Disable and re-enable reporting of addressing errors in the
176215/// specified address range.
177216pub fn disableAddrErrorReportingInRange(qzz: []u8) usize {
178217 return doMemCheckClientRequestExpr(0, // default return
179 MemCheckClientRequest.DisableAddrErrorReportingInRange, @ptrToInt(qzz.ptr), qzz.len, 0, 0, 0);
218 .DisableAddrErrorReportingInRange, @ptrToInt(qzz.ptr), qzz.len, 0, 0, 0);
180219}
181220
182221pub fn enableAddrErrorReportingInRange(qzz: []u8) usize {
183222 return doMemCheckClientRequestExpr(0, // default return
184 MemCheckClientRequest.EnableAddrErrorReportingInRange, @ptrToInt(qzz.ptr), qzz.len, 0, 0, 0);
223 .EnableAddrErrorReportingInRange, @ptrToInt(qzz.ptr), qzz.len, 0, 0, 0);
185224}