Bug Summary

File:jdk/src/hotspot/share/services/mallocTracker.cpp
Warning:line 255, column 3
Value stored to 'header' is never read

Annotated Source Code

Press '?' to see keyboard shortcuts

clang -cc1 -triple x86_64-pc-linux-gnu -analyze -disable-free -disable-llvm-verifier -discard-value-names -main-file-name mallocTracker.cpp -analyzer-store=region -analyzer-opt-analyze-nested-blocks -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=cplusplus -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -setup-static-analyzer -mrelocation-model pic -pic-level 2 -mthread-model posix -fno-delete-null-pointer-checks -mframe-pointer=all -relaxed-aliasing -fmath-errno -fno-rounding-math -masm-verbose -mconstructor-aliases -munwind-tables -target-cpu x86-64 -dwarf-column-info -fno-split-dwarf-inlining -debugger-tuning=gdb -resource-dir /usr/lib/llvm-10/lib/clang/10.0.0 -I /home/daniel/Projects/java/jdk/build/linux-x86_64-server-fastdebug/hotspot/variant-server/libjvm/objs/precompiled -D __STDC_FORMAT_MACROS -D __STDC_LIMIT_MACROS -D __STDC_CONSTANT_MACROS -D _GNU_SOURCE -D _REENTRANT -D LIBC=gnu -D LINUX -D VM_LITTLE_ENDIAN -D _LP64=1 -D ASSERT -D CHECK_UNHANDLED_OOPS -D TARGET_ARCH_x86 -D INCLUDE_SUFFIX_OS=_linux -D INCLUDE_SUFFIX_CPU=_x86 -D INCLUDE_SUFFIX_COMPILER=_gcc -D TARGET_COMPILER_gcc -D AMD64 -D HOTSPOT_LIB_ARCH="amd64" -D COMPILER1 -D COMPILER2 -I /home/daniel/Projects/java/jdk/build/linux-x86_64-server-fastdebug/hotspot/variant-server/gensrc/adfiles -I /home/daniel/Projects/java/jdk/src/hotspot/share -I /home/daniel/Projects/java/jdk/src/hotspot/os/linux -I /home/daniel/Projects/java/jdk/src/hotspot/os/posix -I /home/daniel/Projects/java/jdk/src/hotspot/cpu/x86 -I /home/daniel/Projects/java/jdk/src/hotspot/os_cpu/linux_x86 -I /home/daniel/Projects/java/jdk/build/linux-x86_64-server-fastdebug/hotspot/variant-server/gensrc -I /home/daniel/Projects/java/jdk/src/hotspot/share/precompiled -I /home/daniel/Projects/java/jdk/src/hotspot/share/include -I /home/daniel/Projects/java/jdk/src/hotspot/os/posix/include -I /home/daniel/Projects/java/jdk/build/linux-x86_64-server-fastdebug/support/modules_include/java.base -I /home/daniel/Projects/java/jdk/build/linux-x86_64-server-fastdebug/support/modules_include/java.base/linux -I /home/daniel/Projects/java/jdk/src/java.base/share/native/libjimage -I /home/daniel/Projects/java/jdk/build/linux-x86_64-server-fastdebug/hotspot/variant-server/gensrc/adfiles -I /home/daniel/Projects/java/jdk/src/hotspot/share -I /home/daniel/Projects/java/jdk/src/hotspot/os/linux -I /home/daniel/Projects/java/jdk/src/hotspot/os/posix -I /home/daniel/Projects/java/jdk/src/hotspot/cpu/x86 -I /home/daniel/Projects/java/jdk/src/hotspot/os_cpu/linux_x86 -I /home/daniel/Projects/java/jdk/build/linux-x86_64-server-fastdebug/hotspot/variant-server/gensrc -D _FORTIFY_SOURCE=2 -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/7.5.0/../../../../include/c++/7.5.0 -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/7.5.0/../../../../include/x86_64-linux-gnu/c++/7.5.0 -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/7.5.0/../../../../include/x86_64-linux-gnu/c++/7.5.0 -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/7.5.0/../../../../include/c++/7.5.0/backward -internal-isystem /usr/local/include -internal-isystem /usr/lib/llvm-10/lib/clang/10.0.0/include -internal-externc-isystem /usr/include/x86_64-linux-gnu -internal-externc-isystem /include -internal-externc-isystem /usr/include -O3 -Wno-format-zero-length -Wno-unused-parameter -Wno-unused -Wno-parentheses -Wno-comment -Wno-unknown-pragmas -Wno-address -Wno-delete-non-virtual-dtor -Wno-char-subscripts -Wno-array-bounds -Wno-int-in-bool-context -Wno-ignored-qualifiers -Wno-missing-field-initializers -Wno-implicit-fallthrough -Wno-empty-body -Wno-strict-overflow -Wno-sequence-point -Wno-maybe-uninitialized -Wno-misleading-indentation -Wno-cast-function-type -Wno-shift-negative-value -std=c++14 -fdeprecated-macro -fdebug-compilation-dir /home/daniel/Projects/java/jdk/make/hotspot -ferror-limit 19 -fmessage-length 0 -fvisibility hidden -stack-protector 1 -fno-rtti -fgnuc-version=4.2.1 -fobjc-runtime=gcc -fdiagnostics-show-option -vectorize-loops -vectorize-slp -analyzer-output=html -faddrsig -o /home/daniel/Projects/java/scan/2021-12-21-193737-8510-1 -x c++ /home/daniel/Projects/java/jdk/src/hotspot/share/services/mallocTracker.cpp
1/*
2 * Copyright (c) 2014, 2021, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation.
8 *
9 * This code is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
12 * version 2 for more details (a copy is included in the LICENSE file that
13 * accompanied this code).
14 *
15 * You should have received a copy of the GNU General Public License version
16 * 2 along with this work; if not, write to the Free Software Foundation,
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18 *
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20 * or visit www.oracle.com if you need additional information or have any
21 * questions.
22 *
23 */
24#include "precompiled.hpp"
25
26#include "runtime/os.hpp"
27#include "services/mallocSiteTable.hpp"
28#include "services/mallocTracker.hpp"
29#include "services/mallocTracker.inline.hpp"
30#include "services/memTracker.hpp"
31#include "utilities/debug.hpp"
32#include "utilities/ostream.hpp"
33
34size_t MallocMemorySummary::_snapshot[CALC_OBJ_SIZE_IN_TYPE(MallocMemorySnapshot, size_t)(align_up(sizeof(MallocMemorySnapshot), sizeof(size_t))/sizeof
(size_t))
];
35
36#ifdef ASSERT1
37void MemoryCounter::update_peak_count(size_t count) {
38 size_t peak_cnt = peak_count();
39 while (peak_cnt < count) {
40 size_t old_cnt = Atomic::cmpxchg(&_peak_count, peak_cnt, count, memory_order_relaxed);
41 if (old_cnt != peak_cnt) {
42 peak_cnt = old_cnt;
43 }
44 }
45}
46
47void MemoryCounter::update_peak_size(size_t sz) {
48 size_t peak_sz = peak_size();
49 while (peak_sz < sz) {
50 size_t old_sz = Atomic::cmpxchg(&_peak_size, peak_sz, sz, memory_order_relaxed);
51 if (old_sz != peak_sz) {
52 peak_sz = old_sz;
53 }
54 }
55}
56
57size_t MemoryCounter::peak_count() const {
58 return Atomic::load(&_peak_count);
59}
60
61size_t MemoryCounter::peak_size() const {
62 return Atomic::load(&_peak_size);
63}
64#endif
65
66// Total malloc invocation count
67size_t MallocMemorySnapshot::total_count() const {
68 size_t amount = 0;
69 for (int index = 0; index < mt_number_of_types; index ++) {
70 amount += _malloc[index].malloc_count();
71 }
72 return amount;
73}
74
75// Total malloc'd memory amount
76size_t MallocMemorySnapshot::total() const {
77 size_t amount = 0;
78 for (int index = 0; index < mt_number_of_types; index ++) {
79 amount += _malloc[index].malloc_size();
80 }
81 amount += _tracking_header.size() + total_arena();
82 return amount;
83}
84
85// Total malloc'd memory used by arenas
86size_t MallocMemorySnapshot::total_arena() const {
87 size_t amount = 0;
88 for (int index = 0; index < mt_number_of_types; index ++) {
89 amount += _malloc[index].arena_size();
90 }
91 return amount;
92}
93
94// Make adjustment by subtracting chunks used by arenas
95// from total chunks to get total free chunk size
96void MallocMemorySnapshot::make_adjustment() {
97 size_t arena_size = total_arena();
98 int chunk_idx = NMTUtil::flag_to_index(mtChunk);
99 _malloc[chunk_idx].record_free(arena_size);
100}
101
102
103void MallocMemorySummary::initialize() {
104 assert(sizeof(_snapshot) >= sizeof(MallocMemorySnapshot), "Sanity Check")do { if (!(sizeof(_snapshot) >= sizeof(MallocMemorySnapshot
))) { (*g_assert_poison) = 'X';; report_vm_error("/home/daniel/Projects/java/jdk/src/hotspot/share/services/mallocTracker.cpp"
, 104, "assert(" "sizeof(_snapshot) >= sizeof(MallocMemorySnapshot)"
") failed", "Sanity Check"); ::breakpoint(); } } while (0)
;
105 // Uses placement new operator to initialize static area.
106 ::new ((void*)_snapshot)MallocMemorySnapshot();
107}
108
109void MallocHeader::mark_block_as_dead() {
110 _canary = _header_canary_dead_mark;
111 NOT_LP64(_alt_canary = _header_alt_canary_dead_mark);
112 set_footer(_footer_canary_dead_mark);
113}
114
115void MallocHeader::release() {
116 assert(MemTracker::enabled(), "Sanity")do { if (!(MemTracker::enabled())) { (*g_assert_poison) = 'X'
;; report_vm_error("/home/daniel/Projects/java/jdk/src/hotspot/share/services/mallocTracker.cpp"
, 116, "assert(" "MemTracker::enabled()" ") failed", "Sanity"
); ::breakpoint(); } } while (0)
;
117
118 check_block_integrity();
119
120 MallocMemorySummary::record_free(size(), flags());
121 MallocMemorySummary::record_free_malloc_header(sizeof(MallocHeader));
122 if (MemTracker::tracking_level() == NMT_detail) {
123 MallocSiteTable::deallocation_at(size(), _bucket_idx, _pos_idx);
124 }
125
126 mark_block_as_dead();
127}
128
129void MallocHeader::print_block_on_error(outputStream* st, address bad_address) const {
130 assert(bad_address >= (address)this, "sanity")do { if (!(bad_address >= (address)this)) { (*g_assert_poison
) = 'X';; report_vm_error("/home/daniel/Projects/java/jdk/src/hotspot/share/services/mallocTracker.cpp"
, 130, "assert(" "bad_address >= (address)this" ") failed"
, "sanity"); ::breakpoint(); } } while (0)
;
131
132 // This function prints block information, including hex dump, in case of a detected
133 // corruption. The hex dump should show both block header and corruption site
134 // (which may or may not be close together or identical). Plus some surrounding area.
135 //
136 // Note that we use os::print_hex_dump(), which is able to cope with unmapped
137 // memory (it uses SafeFetch).
138
139 st->print_cr("NMT Block at " PTR_FORMAT"0x%016" "l" "x" ", corruption at: " PTR_FORMAT"0x%016" "l" "x" ": ",
140 p2i(this), p2i(bad_address));
141 static const size_t min_dump_length = 256;
142 address from1 = align_down((address)this, sizeof(void*)) - (min_dump_length / 2);
143 address to1 = from1 + min_dump_length;
144 address from2 = align_down(bad_address, sizeof(void*)) - (min_dump_length / 2);
145 address to2 = from2 + min_dump_length;
146 if (from2 > to1) {
147 // Dump gets too large, split up in two sections.
148 os::print_hex_dump(st, from1, to1, 1);
149 st->print_cr("...");
150 os::print_hex_dump(st, from2, to2, 1);
151 } else {
152 // print one hex dump
153 os::print_hex_dump(st, from1, to2, 1);
154 }
155}
156
157// Check block integrity. If block is broken, print out a report
158// to tty (optionally with hex dump surrounding the broken block),
159// then trigger a fatal error.
160void MallocHeader::check_block_integrity() const {
161
162#define PREFIX "NMT corruption: "
163 // Note: if you modify the error messages here, make sure you
164 // adapt the associated gtests too.
165
166 // Weed out obviously wrong block addresses of NULL or very low
167 // values. Note that we should not call this for ::free(NULL),
168 // which should be handled by os::free() above us.
169 if (((size_t)p2i(this)) < K) {
170 fatal(PREFIX "Block at " PTR_FORMAT ": invalid block address", p2i(this))do { (*g_assert_poison) = 'X';; report_fatal(INTERNAL_ERROR, "/home/daniel/Projects/java/jdk/src/hotspot/share/services/mallocTracker.cpp"
, 170, PREFIX "Block at " "0x%016" "l" "x" ": invalid block address"
, p2i(this)); ::breakpoint(); } while (0)
;
171 }
172
173 // From here on we assume the block pointer to be valid. We could
174 // use SafeFetch but since this is a hot path we don't. If we are
175 // wrong, we will crash when accessing the canary, which hopefully
176 // generates distinct crash report.
177
178 // Weed out obviously unaligned addresses. NMT blocks, being the result of
179 // malloc calls, should adhere to malloc() alignment. Malloc alignment is
180 // specified by the standard by this requirement:
181 // "malloc returns a pointer which is suitably aligned for any built-in type"
182 // For us it means that it is *at least* 64-bit on all of our 32-bit and
183 // 64-bit platforms since we have native 64-bit types. It very probably is
184 // larger than that, since there exist scalar types larger than 64bit. Here,
185 // we test the smallest alignment we know.
186 // Should we ever start using std::max_align_t, this would be one place to
187 // fix up.
188 if (!is_aligned(this, sizeof(uint64_t))) {
189 print_block_on_error(tty, (address)this);
190 fatal(PREFIX "Block at " PTR_FORMAT ": block address is unaligned", p2i(this))do { (*g_assert_poison) = 'X';; report_fatal(INTERNAL_ERROR, "/home/daniel/Projects/java/jdk/src/hotspot/share/services/mallocTracker.cpp"
, 190, PREFIX "Block at " "0x%016" "l" "x" ": block address is unaligned"
, p2i(this)); ::breakpoint(); } while (0)
;
191 }
192
193 // Check header canary
194 if (_canary != _header_canary_life_mark) {
195 print_block_on_error(tty, (address)this);
196 fatal(PREFIX "Block at " PTR_FORMAT ": header canary broken.", p2i(this))do { (*g_assert_poison) = 'X';; report_fatal(INTERNAL_ERROR, "/home/daniel/Projects/java/jdk/src/hotspot/share/services/mallocTracker.cpp"
, 196, PREFIX "Block at " "0x%016" "l" "x" ": header canary broken."
, p2i(this)); ::breakpoint(); } while (0)
;
197 }
198
199#ifndef _LP641
200 // On 32-bit we have a second canary, check that one too.
201 if (_alt_canary != _header_alt_canary_life_mark) {
202 print_block_on_error(tty, (address)this);
203 fatal(PREFIX "Block at " PTR_FORMAT ": header alternate canary broken.", p2i(this))do { (*g_assert_poison) = 'X';; report_fatal(INTERNAL_ERROR, "/home/daniel/Projects/java/jdk/src/hotspot/share/services/mallocTracker.cpp"
, 203, PREFIX "Block at " "0x%016" "l" "x" ": header alternate canary broken."
, p2i(this)); ::breakpoint(); } while (0)
;
204 }
205#endif
206
207 // Does block size seems reasonable?
208 if (_size >= max_reasonable_malloc_size) {
209 print_block_on_error(tty, (address)this);
210 fatal(PREFIX "Block at " PTR_FORMAT ": header looks invalid (weirdly large block size)", p2i(this))do { (*g_assert_poison) = 'X';; report_fatal(INTERNAL_ERROR, "/home/daniel/Projects/java/jdk/src/hotspot/share/services/mallocTracker.cpp"
, 210, PREFIX "Block at " "0x%016" "l" "x" ": header looks invalid (weirdly large block size)"
, p2i(this)); ::breakpoint(); } while (0)
;
211 }
212
213 // Check footer canary
214 if (get_footer() != _footer_canary_life_mark) {
215 print_block_on_error(tty, footer_address());
216 fatal(PREFIX "Block at " PTR_FORMAT ": footer canary broken at " PTR_FORMAT " (buffer overflow?)",do { (*g_assert_poison) = 'X';; report_fatal(INTERNAL_ERROR, "/home/daniel/Projects/java/jdk/src/hotspot/share/services/mallocTracker.cpp"
, 217, PREFIX "Block at " "0x%016" "l" "x" ": footer canary broken at "
"0x%016" "l" "x" " (buffer overflow?)", p2i(this), p2i(footer_address
())); ::breakpoint(); } while (0)
217 p2i(this), p2i(footer_address()))do { (*g_assert_poison) = 'X';; report_fatal(INTERNAL_ERROR, "/home/daniel/Projects/java/jdk/src/hotspot/share/services/mallocTracker.cpp"
, 217, PREFIX "Block at " "0x%016" "l" "x" ": footer canary broken at "
"0x%016" "l" "x" " (buffer overflow?)", p2i(this), p2i(footer_address
())); ::breakpoint(); } while (0)
;
218 }
219#undef PREFIX
220}
221
222bool MallocHeader::record_malloc_site(const NativeCallStack& stack, size_t size,
223 size_t* bucket_idx, size_t* pos_idx, MEMFLAGS flags) const {
224 return MallocSiteTable::allocation_at(stack, size, bucket_idx, pos_idx, flags);
225}
226
227bool MallocHeader::get_stack(NativeCallStack& stack) const {
228 return MallocSiteTable::access_stack(stack, _bucket_idx, _pos_idx);
229}
230
231bool MallocTracker::initialize(NMT_TrackingLevel level) {
232 if (level >= NMT_summary) {
233 MallocMemorySummary::initialize();
234 }
235
236 if (level == NMT_detail) {
237 return MallocSiteTable::initialize();
238 }
239 return true;
240}
241
242// Record a malloc memory allocation
243void* MallocTracker::record_malloc(void* malloc_base, size_t size, MEMFLAGS flags,
244 const NativeCallStack& stack, NMT_TrackingLevel level) {
245 assert(level != NMT_off, "precondition")do { if (!(level != NMT_off)) { (*g_assert_poison) = 'X';; report_vm_error
("/home/daniel/Projects/java/jdk/src/hotspot/share/services/mallocTracker.cpp"
, 245, "assert(" "level != NMT_off" ") failed", "precondition"
); ::breakpoint(); } } while (0)
;
246 void* memblock; // the address for user data
247 MallocHeader* header = NULL__null;
248
249 if (malloc_base == NULL__null) {
250 return NULL__null;
251 }
252
253 // Uses placement global new operator to initialize malloc header
254
255 header = ::new (malloc_base)MallocHeader(size, flags, stack, level);
Value stored to 'header' is never read
256 memblock = (void*)((char*)malloc_base + sizeof(MallocHeader));
257
258 // The alignment check: 8 bytes alignment for 32 bit systems.
259 // 16 bytes alignment for 64-bit systems.
260 assert(((size_t)memblock & (sizeof(size_t) * 2 - 1)) == 0, "Alignment check")do { if (!(((size_t)memblock & (sizeof(size_t) * 2 - 1)) ==
0)) { (*g_assert_poison) = 'X';; report_vm_error("/home/daniel/Projects/java/jdk/src/hotspot/share/services/mallocTracker.cpp"
, 260, "assert(" "((size_t)memblock & (sizeof(size_t) * 2 - 1)) == 0"
") failed", "Alignment check"); ::breakpoint(); } } while (0
)
;
261
262#ifdef ASSERT1
263 if (level > NMT_off) {
264 // Read back
265 assert(get_size(memblock) == size, "Wrong size")do { if (!(get_size(memblock) == size)) { (*g_assert_poison) =
'X';; report_vm_error("/home/daniel/Projects/java/jdk/src/hotspot/share/services/mallocTracker.cpp"
, 265, "assert(" "get_size(memblock) == size" ") failed", "Wrong size"
); ::breakpoint(); } } while (0)
;
266 assert(get_flags(memblock) == flags, "Wrong flags")do { if (!(get_flags(memblock) == flags)) { (*g_assert_poison
) = 'X';; report_vm_error("/home/daniel/Projects/java/jdk/src/hotspot/share/services/mallocTracker.cpp"
, 266, "assert(" "get_flags(memblock) == flags" ") failed", "Wrong flags"
); ::breakpoint(); } } while (0)
;
267 }
268#endif
269
270 return memblock;
271}
272
273void* MallocTracker::record_free(void* memblock) {
274 assert(MemTracker::tracking_level() != NMT_off && memblock != NULL, "precondition")do { if (!(MemTracker::tracking_level() != NMT_off &&
memblock != __null)) { (*g_assert_poison) = 'X';; report_vm_error
("/home/daniel/Projects/java/jdk/src/hotspot/share/services/mallocTracker.cpp"
, 274, "assert(" "MemTracker::tracking_level() != NMT_off && memblock != __null"
") failed", "precondition"); ::breakpoint(); } } while (0)
;
275 MallocHeader* header = malloc_header(memblock);
276 header->release();
277 return (void*)header;
278}