1 // https://github.com/llvm/llvm-project/issues/60678
4 // DFSAN_OPTIONS=no_huge_pages_for_shadow=false RUN: %clang_dfsan %s -o %t && %run %t
5 // DFSAN_OPTIONS=no_huge_pages_for_shadow=true RUN: %clang_dfsan %s -o %t && %run %t
6 // DFSAN_OPTIONS=no_huge_pages_for_shadow=false RUN: %clang_dfsan %s -DORIGIN_TRACKING -mllvm -dfsan-track-origins=1 -o %t && %run %t
7 // DFSAN_OPTIONS=no_huge_pages_for_shadow=true RUN: %clang_dfsan %s -DORIGIN_TRACKING -mllvm -dfsan-track-origins=1 -o %t && %run %t
10 #include <sanitizer/dfsan_interface.h>
22 sprintf(fname
, "/proc/%ld/task/%ld/smaps", (long)pid
, (long)pid
);
23 FILE *f
= fopen(fname
, "r");
27 while (fgets(buf
, sizeof(buf
), f
) != NULL
) {
29 if (sscanf(buf
, "Rss: %ld kB", &rss
) == 1)
38 int main(int argc
, char **argv
) {
39 const size_t map_size
= 100 << 20;
40 size_t before
= get_rss_kb();
42 // mmap and touch all addresses. The overhead is 1x.
43 char *p
= mmap(NULL
, map_size
, PROT_READ
| PROT_WRITE
,
44 MAP_PRIVATE
| MAP_ANONYMOUS
, -1, 0);
45 memset(p
, 0xff, map_size
);
46 size_t after_mmap
= get_rss_kb();
48 // store labels to all addresses. The overhead is 2x.
49 const dfsan_label label
= 8;
51 dfsan_set_label(label
, &val
, sizeof(val
));
52 memset(p
, val
, map_size
);
53 size_t after_mmap_and_set_label
= get_rss_kb();
55 // fixed-mmap the same address. OS recyles pages and reinitializes data at the
56 // address. This should be the same to calling munmap.
57 p
= mmap(p
, map_size
, PROT_READ
| PROT_WRITE
,
58 MAP_PRIVATE
| MAP_ANONYMOUS
| MAP_FIXED
, -1, 0);
59 size_t after_fixed_mmap
= get_rss_kb();
61 // store labels to all addresses.
62 memset(p
, val
, map_size
);
63 size_t after_mmap_and_set_label2
= get_rss_kb();
65 // munmap the addresses.
67 size_t after_munmap
= get_rss_kb();
71 "RSS at start: %zu, after mmap: %zu, after mmap+set label: %zu, after "
72 "fixed map: %zu, after another mmap+set label: %zu, after munmap: %zu\n",
73 before
, after_mmap
, after_mmap_and_set_label
, after_fixed_mmap
,
74 after_mmap_and_set_label2
, after_munmap
);
76 const size_t mmap_cost_kb
= map_size
>> 10;
77 // Shadow space (1:1 with application memory)
78 const size_t mmap_shadow_cost_kb
= sizeof(dfsan_label
) * mmap_cost_kb
;
79 #ifdef ORIGIN_TRACKING
80 // Origin space (1:1 with application memory)
81 const size_t mmap_origin_cost_kb
= mmap_cost_kb
;
83 const size_t mmap_origin_cost_kb
= 0;
85 assert(after_mmap
>= before
+ mmap_cost_kb
);
86 assert(after_mmap_and_set_label
>=
87 after_mmap
+ mmap_shadow_cost_kb
+ mmap_origin_cost_kb
);
88 assert(after_mmap_and_set_label2
>=
89 before
+ mmap_cost_kb
+ mmap_shadow_cost_kb
+ mmap_origin_cost_kb
);
91 #ifdef ORIGIN_TRACKING
92 // This value is chosen based on observed difference.
93 const size_t mmap_origin_chain_kb
= 4000;
95 const size_t mmap_origin_chain_kb
= 0;
98 // RSS may not change memory amount after munmap to the same level as the
99 // start of the program. The assert checks the memory up to a delta.
100 const size_t delta
= 5000;
101 // Origin chains are not freed, even when the origin space which refers to
102 // them is freed, so mmap_origin_chain_kb is added to account for this.
103 assert(after_fixed_mmap
<= before
+ delta
+ mmap_origin_chain_kb
);
104 assert(after_munmap
<= before
+ delta
+ mmap_origin_chain_kb
);