Skip to content

Instantly share code, notes, and snippets.

@zambonin
Created July 23, 2025 19:36
Show Gist options
  • Select an option

  • Save zambonin/6b84e03bd03b6bef0f82dadbb3ce02f6 to your computer and use it in GitHub Desktop.

Select an option

Save zambonin/6b84e03bd03b6bef0f82dadbb3ce02f6 to your computer and use it in GitHub Desktop.
Patch to allow Valgrind's DHAT to track larger chunks of memory.
# Starting from Valgrind 3.21.0 (cf. bug 464103), a client request was added to
# mark memory to be histogrammed in DHAT [1]. However, the maximum size of this
# marked memory is hardcoded as
#
# #define USER_HISTOGRAM_SIZE_LIMIT 25*HISTOGRAM_SIZE_LIMIT
#
# in `dhat/dh_main.c` at the time of writing. The attached patch (1) extends
# this size limit and (2) also allows memory access counts to exceed 2^16.
#
# If (2) is not needed, one can edit the DHAT binary directly. We see that
# `USER_HISTOGRAM_SIZE_LIMIT` is only using in a single conditional in
# `dh_handle_client_request`:
#
# if (bk->req_szB > USER_HISTOGRAM_SIZE_LIMIT) {
# ...
# }
#
# Because `bk->req_szB` is unsigned, it suffices to replace the size limit by
# -1 to make the conditional always evaluate to false. Search for 0x6400 (25 in
# hexadecimal) in the DHAT binary, for instance with the command below.
#
# $ objdump --disassemble=dh_handle_client_request /usr/lib/valgrind/dhat-amd64-linux | grep "$0x6400"
# 5800f539: 48 81 fa 00 64 00 00 cmp $0x6400,%rdx
#
# We see that the only instruction found matches the conditional above. The
# command below edits the DHAT binary to replace 0x6400 by 0xfffffff.
#
# # perl -pi.bak -e 's/\x48\x81\xfa\x00\x64\x00\x00/\x48\x81\xfa\xff\xff\xff\xff/g' /usr/lib/valgrind/dhat-amd64-linux
#
# The commands may be a bit different if the architecture is not x86-64. Of
# course, it is better if this is done in a local copy of Valgrind, but then
# again one can just apply the patch. :-)
#
# [1] https://accu.org/journals/overload/33/185/floyd/
diff --git a/dhat/dh_main.c b/dhat/dh_main.c
index 9e6ec1c06..6f4a7b89c 100644
--- a/dhat/dh_main.c
+++ b/dhat/dh_main.c
@@ -48 +48 @@
-#define USER_HISTOGRAM_SIZE_LIMIT 25*HISTOGRAM_SIZE_LIMIT
+#define USER_HISTOGRAM_SIZE_LIMIT 2500*HISTOGRAM_SIZE_LIMIT
@@ -133 +133 @@ typedef
- UShort* histoW; /* [0 .. req_szB-1] */
+ ULong* histoW; /* [0 .. req_szB-1] */
@@ -613,2 +613,2 @@ void* new_block ( ThreadId tid, void* p, SizeT req_szB, SizeT req_alignB,
- bk->histoW = VG_(malloc)("dh.new_block.2", req_szB * sizeof(UShort));
- VG_(memset)(bk->histoW, 0, req_szB * sizeof(UShort));
+ bk->histoW = VG_(malloc)("dh.new_block.2", req_szB * sizeof(ULong));
+ VG_(memset)(bk->histoW, 0, req_szB * sizeof(ULong));
@@ -856,3 +856 @@ void inc_histo_for_block ( Block* bk, Addr addr, UWord szB )
- UShort n = bk->histoW[i];
- if (n < 0xFFFF) n++;
- bk->histoW[i] = n;
+ bk->histoW[i]++;
@@ -1270,2 +1268,2 @@ static Bool dh_handle_client_request(ThreadId tid, UWord* arg, UWord* ret)
- bk->histoW = VG_(malloc)("dh.new_block.3", bk->req_szB * sizeof(UShort));
- VG_(memset)(bk->histoW, 0, bk->req_szB * sizeof(UShort));
+ bk->histoW = VG_(malloc)("dh.new_block.3", bk->req_szB * sizeof(ULong));
+ VG_(memset)(bk->histoW, 0, bk->req_szB * sizeof(ULong));
@@ -1574 +1572 @@ static void write_PPInfo(PPInfo* ppi, Bool is_first)
- UShort repval = 0;
+ ULong repval = 0;
@@ -1577 +1575 @@ static void write_PPInfo(PPInfo* ppi, Bool is_first)
- UShort h = ppi->histo[i];
+ ULong h = ppi->histo[i];
@@ -1584 +1582 @@ static void write_PPInfo(PPInfo* ppi, Bool is_first)
- FP("%u,", repval);
+ FP("%llu,", repval);
@@ -1586 +1584 @@ static void write_PPInfo(PPInfo* ppi, Bool is_first)
- FP("-%d,%u,", reps, repval);
+ FP("-%d,%llu,", reps, repval);
@@ -1594 +1592 @@ static void write_PPInfo(PPInfo* ppi, Bool is_first)
- FP("%u", repval);
+ FP("%llu", repval);
@@ -1596 +1594 @@ static void write_PPInfo(PPInfo* ppi, Bool is_first)
- FP("-%d,%u", reps, repval);
+ FP("-%d,%llu", reps, repval);
diff --git a/dhat/dh_view.js b/dhat/dh_view.js
index ffdea9303..eea08ce7d 100644
--- a/dhat/dh_view.js
+++ b/dhat/dh_view.js
@@ -511,7 +511 @@ function normalizeAccess(aAcc) {
- if (aAcc < 0xffff) {
- return aAcc;
- }
- if (aAcc === 0xffff) {
- return Infinity;
- }
- assert(false, "too-large access value");
+ return aAcc;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment