/dhat/tests/empty
/dhat/tests/sig
/dhat/tests/single
+/dhat/tests/user_histo1
# /docs/
/docs/FAQ.txt
460356 s390: Sqrt32Fx4 -- cannot reduce tree
462830 WARNING: unhandled amd64-freebsd syscall: 474
463027 broken check for MPX instruction support in assembler
+464103 Enhancement: add a client request to DHAT to mark memory to be histogrammed
464476 Firefox fails to start under Valgrind
464609 Valgrind memcheck should support Linux pidfd_open
464680 Show issues caused by memory policies like selinux deny_execmem
#include "dhat.h"
#define HISTOGRAM_SIZE_LIMIT 1024
+#define USER_HISTOGRAM_SIZE_LIMIT 25*HISTOGRAM_SIZE_LIMIT
//------------------------------------------------------------//
//--- Globals ---//
return True;
}
+ case VG_USERREQ__DHAT_HISTOGRAM_MEMORY: {
+ Addr address = (Addr)arg[1];
+ UWord initial_count = arg[2];
+
+ Block* bk = find_Block_containing( address );
+ // bogus address
+ if (!bk) {
+ VG_(message)(
+ Vg_UserMsg,
+ "Warning: address for user histogram request not found %llx\n", (ULong)address
+ );
+ return False;
+ }
+
+ // already histogrammed
+ if (bk->req_szB <= HISTOGRAM_SIZE_LIMIT) {
+ VG_(message)(
+ Vg_UserMsg,
+ "Warning: request for user histogram of size %lu is smaller than the normal histogram limit, request ignored\n",
+ bk->req_szB
+ );
+ return False;
+ }
+
+ // already histogrammed
+ if (bk->req_szB > USER_HISTOGRAM_SIZE_LIMIT) {
+ VG_(message)(
+ Vg_UserMsg,
+ "Warning: request for user histogram of size %lu is larger than the maximum user request limit, request ignored\n",
+ bk->req_szB
+ );
+ return False;
+ }
+
+
+ bk->histoW = VG_(malloc)("dh.new_block.3", bk->req_szB * sizeof(UShort));
+ if (initial_count == 0U) {
+ VG_(memset)(bk->histoW, 0, bk->req_szB * sizeof(UShort));
+ } else {
+ for (SizeT i = 0U; i < bk->req_szB; ++i) {
+ bk->histoW[i] = 1U;
+ }
+ }
+ return True;
+ }
+
case _VG_USERREQ__DHAT_COPY: {
SizeT len = (SizeT)arg[1];
----------------------------------------------------------------
*/
+#if !defined(VALGRIND_DHAT_H)
+#define VALGRIND_DHAT_H
+
#include "valgrind.h"
typedef
enum {
VG_USERREQ__DHAT_AD_HOC_EVENT = VG_USERREQ_TOOL_BASE('D', 'H'),
+ VG_USERREQ__DHAT_HISTOGRAM_MEMORY,
+ VG_USERREQ__DHAT_HISTOGRAM_ARRAY,
// This is just for DHAT's internal use. Don't use it.
_VG_USERREQ__DHAT_COPY = VG_USERREQ_TOOL_BASE('D','H') + 256
VALGRIND_DO_CLIENT_REQUEST_STMT(VG_USERREQ__DHAT_AD_HOC_EVENT, \
(_qzz_weight), 0, 0, 0, 0)
+// for limited histograms of memory larger than 1k
+#define DHAT_HISTOGRAM_MEMORY(_qzz_address, _qzz_initial_count) \
+ VALGRIND_DO_CLIENT_REQUEST_STMT(VG_USERREQ__DHAT_HISTOGRAM_MEMORY, \
+ (_qzz_address), (_qzz_initial_count), 0, 0, 0)
+
+// convenience macro for DHAT_HISTOGRAM_MEMORY
+// for initialized memory (calloc, std::vector with initialization)
+#define DHAT_HISTOGRAM_MEMORY_INIT(_qzz_address) \
+ DHAT_HISTOGRAM_MEMORY(_qzz_address, 1U)
+
+// convenience macro for DHAT_HISTOGRAM_MEMORY
+// for uninitialized memory (malloc, std::vector without initialization)
+#define DHAT_HISTOGRAM_MEMORY_UNINIT(_qzz_address) \
+ DHAT_HISTOGRAM_MEMORY(_qzz_address, 0U)
+
+
+#endif
+
probably have four separate byte-sized fields, followed by a four-byte field,
and so on.</para>
+<para>The size of the blocks that measure and display access counts is limited
+to 1024 bytes. This is done to limit the performance overhead and also to keep
+the size of the generated output reasonable. However, it is possible to override
+this limit using client requests. The use-case for this is to first run DHAT
+normally, and then identify any large blocks that you would like to further
+investigate with access histograms. The client requests are declared in
+<filename>dhat/dhat.h</filename>. There are two versions, <computeroutput>DHAT_HISTOGRAM_MEMORY_INIT</computeroutput> and
+<computeroutput>DHAT_HISTOGRAM_MEMORY_UNINIT</computeroutput>. The
+UNINIT version should be used with allocators that return uninitialized
+memory (like <computeroutput>malloc</computeroutput> and <computeroutput>new</computeroutput>
+without a constructor). The INIT version should be used with allocators
+that initialize memory (like <computeroutput>calloc</computeroutput> and <computeroutput>new</computeroutput>
+with a constructor). The macros should be placed immediately after the
+call to the allocator, and use the pointer returned by the allocator.</para>
+
+<programlisting><![CDATA[
+// LargeStruct bigger than 1024 bytes
+struct LargeStruct* ls = malloc(sizeof(struct LargeStruct));
+DHAT_HISTOGRAM_MEMORY_INIT(ls);
+]]></programlisting>
+
+<para>The memory that can be profiled in this way with user requests
+has a further upper limit of 25kbytes.</para>
+
<para>Access counts can be useful for identifying data alignment holes or other
layout inefficiencies.</para>
copy.stderr.exp copy.vgtest \
empty.stderr.exp empty.vgtest \
sig.stderr.exp sig.vgtest \
- single.stderr.exp single.vgtest
+ single.stderr.exp single.vgtest \
+ user_histo1.stderr.exp user_histo1.vgtest
check_PROGRAMS = \
acc \
copy \
empty \
sig \
- single
+ single \
+ user_histo1
AM_CFLAGS += $(AM_FLAG_M3264_PRI)
AM_CXXFLAGS += $(AM_FLAG_M3264_PRI)
# Prevent the copying functions from being inlined
copy_CFLAGS = $(AM_CFLAGS) -fno-builtin
+
+user_histo1_SOURCES = user_histo1.cpp
--- /dev/null
+#include <vector>
+#include <cstdint>
+#include <iostream>
+#include <random>
+#include "dhat/dhat.h"
+
+int main()
+{
+ std::vector<uint8_t> vec(2000, 0);
+ DHAT_HISTOGRAM_MEMORY_INIT(vec.data());
+ std::mt19937 gen(42);;
+ std::uniform_int_distribution<> index_distrib(0, 1999);
+ std::uniform_int_distribution<> val_distrib(0, 255);
+
+ for (int i = 0; i < 20; ++i)
+ {
+ int index = index_distrib(gen);
+ int val = val_distrib(gen);
+ vec[index] = val;
+ //std::cout << "wrote " << val << " to index " << index << "\n";
+ }
+
+ // try to generate some warnings
+ vec.resize(500);
+ vec.shrink_to_fit();
+ DHAT_HISTOGRAM_MEMORY_UNINIT(vec.data());
+
+ auto old = vec.data();
+ vec.resize(100000);
+ // old should have been deleted
+ DHAT_HISTOGRAM_MEMORY_UNINIT(old);
+ // and this is too big
+ DHAT_HISTOGRAM_MEMORY_UNINIT(vec.data());
+}
--- /dev/null
+Warning: request for user histogram of size 500 is smaller than the normal histogram limit, request ignored
+Warning: address for user histogram request not found 55b2820
+Warning: request for user histogram of size 100000 is larger than the maximum user request limit, request ignored
+Total: 102,500 bytes in 3 blocks
+At t-gmax: 100,500 bytes in 2 blocks
+At t-end: 0 bytes in 0 blocks
+Reads: 1,000 bytes
+Writes: 102,520 bytes
--- /dev/null
+prog: user_histo1
+vgopts: --dhat-out-file=dhat.out
+cleanup: rm dhat.out