static Int moans = 3;
/* Overload memcheck client reqs */
- if (!VG_IS_SKIN_USERREQ('M','C',arg[0]))
+ if (!VG_IS_SKIN_USERREQ('M','C',arg[0])
+ && VG_USERREQ__MALLOCLIKE_BLOCK != arg[0]
+ && VG_USERREQ__FREELIKE_BLOCK != arg[0])
return False;
switch (arg[0]) {
Memcheck, but for Cachegrind it will always return zero because
Cachegrind doesn't report errors.
<p>
+<li><code>VALGRIND_MALLOCLIKE_BLOCK</code>: If your program manages its own
+ memory instead of using the standard
+ <code>malloc()</code>/<code>new</code>/<code>new[]</code>, skins that track
+ information about heap blocks will not do nearly as good a
+ job. For example, Memcheck won't detect nearly as many errors, and the
+ error messages won't be as informative. To improve this situation, use
+ this macro just after your custom allocator allocates some new memory. See
+ the comments in <code>valgrind.h</code> for information on how to use it.
+<p>
+<li><code>VALGRIND_FREELIKE_BLOCK</code>: This should be used in conjunction
+ with <code>VALGRIND_MALLOCLIKE_BLOCK</code>. Again, see
+ <code>memcheck/memcheck.h</code> for information on how to use it.
+<p>
<li><code>VALGRIND_NON_SIMD_CALL[0123]</code>: executes a function of 0, 1, 2
or 3 args in the client program on the <i>real</i> CPU, not the virtual
CPU that Valgrind normally runs code on. These are used in various ways
static Bool whined = False;
if (!whined) {
+ // Allow for requests in core, but defined by skins, which
+ // have 0 and 0 in their two high bytes.
+ Char c1 = (arg[0] >> 24) & 0xff;
+ Char c2 = (arg[0] >> 16) & 0xff;
+ if (c1 == 0) c1 = '_';
+ if (c2 == 0) c2 = '_';
VG_(message)(Vg_UserMsg, "Warning:\n"
- " unhandled client request: 0x%x (%c%c+%d). Perhaps\n"
- " VG_(needs).client_requests should be set?\n",
- arg[0], (arg[0] >> 24) & 0xff, (arg[0] >> 16) & 0xff,
- arg[0] & 0xffff);
+ " unhandled client request: 0x%x (%c%c+0x%x). Perhaps\n"
+ " VG_(needs).client_requests should be set?\n",
+ arg[0], c1, c2, arg[0] & 0xffff);
whined = True;
}
}
/* Some request codes. There are many more of these, but most are not
exposed to end-user view. These are the public ones, all of the
form 0x1000 + small_number.
+
+ Core ones are in the range 0x00000000--0x0000ffff. The non-public ones
+ start at 0x2000.
*/
#define VG_USERREQ_SKIN_BASE(a,b) \
Valgrind's output to /dev/null and still count errors. */
VG_USERREQ__COUNT_ERRORS = 0x1201,
- VG_USERREQ__FINAL_DUMMY_CLIENT_REQUEST
+ /* These are useful and can be interpreted by any skin that tracks
+ malloc() et al, by using vg_replace_malloc.c. */
+ VG_USERREQ__MALLOCLIKE_BLOCK = 0x1301,
+ VG_USERREQ__FREELIKE_BLOCK = 0x1302,
+
} Vg_ClientRequest;
_qyy_res; \
})
+/* Mark a block of memory as having been allocated by a malloc()-like
+ function. `addr' is the start of the usable block (ie. after any
+ redzone) `rzB' is redzone size if the allocator can apply redzones;
+ use '0' if not. Adding redzones makes it more likely Valgrind will spot
+ block overruns. `is_zeroed' indicates if the memory is zeroed, as it is
+ for calloc(). Put it immediately after the point where a block is
+ allocated.
+
+ If you're allocating memory via superblocks, and then handing out small
+ chunks of each superblock, if you don't have redzones on your small
+ blocks, it's worth marking the superblock with VALGRIND_MAKE_NOACCESS
+ when it's created, so that block overruns are detected. But if you can
+ put redzones on, it's probably better to not do this, so that messages
+ for small overruns are described in terms of the small block rather than
+ the superblock (but if you have a big overrun that skips over a redzone,
+ you could miss an error this way). See memcheck/tests/custom_alloc.c
+ for an example.
+
+ Nb: block must be freed via a free()-like function specified
+ with VALGRIND_FREELIKE_BLOCK or mismatch errors will occur. */
+#define VALGRIND_MALLOCLIKE_BLOCK(addr, sizeB, rzB, is_zeroed) \
+ {unsigned int _qzz_res; \
+ VALGRIND_MAGIC_SEQUENCE(_qzz_res, 0, \
+ VG_USERREQ__MALLOCLIKE_BLOCK, \
+ addr, sizeB, rzB, is_zeroed); \
+ }
+
+/* Mark a block of memory as having been freed by a free()-like function.
+ `rzB' is redzone size; it must match that given to
+ VALGRIND_MALLOCLIKE_BLOCK. Memory not freed will be detected by the leak
+ checker. Put it immediately after the point where the block is freed. */
+#define VALGRIND_FREELIKE_BLOCK(addr, rzB) \
+ {unsigned int _qzz_res; \
+ VALGRIND_MAGIC_SEQUENCE(_qzz_res, 0, \
+ VG_USERREQ__FREELIKE_BLOCK, \
+ addr, rzB, 0, 0); \
+ }
+
#endif /* __VALGRIND_H */
be leaked, dubious, reachable and suppressed. Again, useful in
test harness code, after calling <code>VALGRIND_DO_LEAK_CHECK</code>.
<p>
-<li><code>VALGRIND_MALLOCLIKE_BLOCK</code>: If your program manages its own
- memory instead of using the standard
- <code>malloc()</code>/<code>new</code>/<code>new[]</code>, Memcheck will
- not detect nearly as many errors, and the error messages won't be as
- informative. To improve this situation, use this macro just after your
- custom allocator allocates some new memory. See the comments in
- <code>memcheck/memcheck.h</code> for information on how to use it.
-<p>
-<li><code>VALGRIND_FREELIKE_BLOCK</code>: This should be used in conjunction
- with <code>VALGRIND_MALLOCLIKE_BLOCK</code>. Again, see
- <code>memcheck/memcheck.h</code> for information on how to use it.
-<p>
<li><code>VALGRIND_GET_VBITS</code> and
<code>VALGRIND_SET_VBITS</code>: allow you to get and set the V (validity)
bits for an address range. You should probably only set V bits that you
Bool MAC_(handle_common_client_requests)(ThreadId tid, UInt* arg, UInt* ret )
{
- UInt* argv = (UInt*)arg;
+ Char* err =
+ "The client requests VALGRIND_MALLOCLIKE_BLOCK and\n"
+ " VALGRIND_FREELIKE_BLOCK have moved. Please recompile your\n"
+ " program to incorporate the updates in the Valgrind header files.\n"
+ " You shouldn't need to change the text of your program at all.\n"
+ " Everything should then work as before. Sorry for the bother.\n";
// Not using 'tid' here because MAC_(new_block)() and MAC_(handle_free)()
// grab it themselves. But what they grab should match 'tid', check
*ret = 0;
return True;
}
+ case VG_USERREQ__MALLOCLIKE_BLOCK__OLD_DO_NOT_USE:
+ case VG_USERREQ__FREELIKE_BLOCK__OLD_DO_NOT_USE:
+ VG_(skin_panic)(err);
+
case VG_USERREQ__MALLOCLIKE_BLOCK: {
- Addr p = (Addr)argv[1];
- UInt sizeB = argv[2];
- UInt rzB = argv[3];
- Bool is_zeroed = (Bool)argv[4];
+ Addr p = (Addr)arg[1];
+ UInt sizeB = arg[2];
+ UInt rzB = arg[3];
+ Bool is_zeroed = (Bool)arg[4];
MAC_(new_block) ( p, sizeB, rzB, is_zeroed, MAC_AllocCustom );
return True;
}
case VG_USERREQ__FREELIKE_BLOCK: {
- Addr p = (Addr)argv[1];
- UInt rzB = argv[2];
+ Addr p = (Addr)arg[1];
+ UInt rzB = arg[2];
MAC_(handle_free) ( p, rzB, MAC_AllocCustom );
return True;
}
+
default:
return False;
}
Bool ok;
Addr bad_addr;
- if (!VG_IS_SKIN_USERREQ('M','C',arg[0]))
+ if (!VG_IS_SKIN_USERREQ('M','C',arg[0])
+ && VG_USERREQ__MALLOCLIKE_BLOCK != arg[0]
+ && VG_USERREQ__FREELIKE_BLOCK != arg[0])
return False;
switch (arg[0]) {
VG_USERREQ__CHECK_READABLE,
VG_USERREQ__DO_LEAK_CHECK,
VG_USERREQ__COUNT_LEAKS,
- VG_USERREQ__MALLOCLIKE_BLOCK,
- VG_USERREQ__FREELIKE_BLOCK,
+
+ /* These two have been moved into core, because they are useful for
+ any skin that tracks heap blocks. Hence the suffix. But they're
+ still here for backwards compatibility, although Valgrind will
+ abort with an explanatory message if you use them. */
+ VG_USERREQ__MALLOCLIKE_BLOCK__OLD_DO_NOT_USE,
+ VG_USERREQ__FREELIKE_BLOCK__OLD_DO_NOT_USE,
+
VG_USERREQ__GET_VBITS,
VG_USERREQ__SET_VBITS
} Vg_MemCheckClientRequest;
&leaked, &dubious, &reachable, &suppressed);\
}
-#endif
-
-/* Mark a block of memory as having been allocated by a malloc()-like
- function. `addr' is the start of the usable block (ie. after any
- redzone) `rzB' is redzone size if the allocator can apply redzones;
- use '0' if not. Adding redzones makes it more likely Valgrind will spot
- block overruns. `is_zeroed' indicates if the memory is zeroed, as it is
- for calloc(). Put it immediately after the point where a block is
- allocated.
-
- If you're allocating memory via superblocks, and then handing out small
- chunks of each superblock, if you don't have redzones on your small
- blocks, it's worth marking the superblock with VALGRIND_MAKE_NOACCESS
- when it's created, so that block overruns are detected. But if you can
- put redzones on, it's probably better to not do this, so that messages
- for small overruns are described in terms of the small block rather than
- the superblock (but if you have a big overrun that skips over a redzone,
- you could miss an error this way). See memcheck/tests/custom_alloc.c
- for an example.
-
- Nb: block must be freed via a free()-like function specified
- with VALGRIND_FREELIKE_BLOCK or mismatch errors will occur. */
-#define VALGRIND_MALLOCLIKE_BLOCK(addr, sizeB, rzB, is_zeroed) \
+/* These two have been moved to valgrind.h; still here so that a warning can
+ be printed out for any programs using the old ones. */
+#define VALGRIND_MALLOCLIKE_BLOCK__OLD_DO_NOT_USE(addr, sizeB, rzB, is_zeroed)\
{unsigned int _qzz_res; \
VALGRIND_MAGIC_SEQUENCE(_qzz_res, 0, \
VG_USERREQ__MALLOCLIKE_BLOCK, \
addr, sizeB, rzB, is_zeroed); \
}
-
-/* Mark a block of memory as having been freed by a free()-like function.
- `rzB' is redzone size; it must match that given to
- VALGRIND_MALLOCLIKE_BLOCK. Memory not freed will be detected by the leak
- checker. Put it immediately after the point where the block is freed. */
-#define VALGRIND_FREELIKE_BLOCK(addr, rzB) \
+#define VALGRIND_FREELIKE_BLOCK__OLD_DO_NOT_USE(addr, rzB) \
{unsigned int _qzz_res; \
VALGRIND_MAGIC_SEQUENCE(_qzz_res, 0, \
VG_USERREQ__FREELIKE_BLOCK, \
addr, rzB, 0, 0); \
}
+
/* Get in zzvbits the validity data for the zznbytes starting at
zzsrc. Return values:
0 if not running on valgrind
czzdst, czzvbits, zznbytes,0 ); \
_qzz_res; \
}))
+
+#endif
+