Bug Summary

File:jdk/src/jdk.hotspot.agent/share/native/libsaproc/ps_core_common.c
Warning:line 361, column 12
Although the value stored to 'n' is used in the enclosing expression, the value is never actually read from 'n'

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 ps_core_common.c -analyzer-store=region -analyzer-opt-analyze-nested-blocks -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -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/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/libjava -I /home/daniel/Projects/java/jdk/src/java.base/unix/native/libjava -I /home/daniel/Projects/java/jdk/src/hotspot/share/include -I /home/daniel/Projects/java/jdk/src/hotspot/os/posix/include -D LIBC=gnu -D _GNU_SOURCE -D _REENTRANT -D _LARGEFILE64_SOURCE -D LINUX -D DEBUG -D _LITTLE_ENDIAN -D ARCH="amd64" -D amd64 -D _LP64=1 -D _FILE_OFFSET_BITS=64 -I /home/daniel/Projects/java/jdk/src/jdk.hotspot.agent/linux/native/libsaproc -I /home/daniel/Projects/java/jdk/src/jdk.hotspot.agent/share/native/libsaproc -I /home/daniel/Projects/java/jdk/build/linux-x86_64-server-fastdebug/support/headers/jdk.hotspot.agent -D _FORTIFY_SOURCE=2 -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 -O2 -Wno-unused-parameter -Wno-unused -Wno-sign-compare -Wno-pointer-arith -std=c99 -fdebug-compilation-dir /home/daniel/Projects/java/jdk/make -ferror-limit 19 -fmessage-length 0 -fvisibility hidden -stack-protector 1 -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/jdk.hotspot.agent/share/native/libsaproc/ps_core_common.c
1/*
2 * Copyright (c) 2019, 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
25#if defined(LINUX1) || defined(__APPLE__)
26#include <unistd.h>
27#include <fcntl.h>
28#include <string.h>
29#include <stdlib.h>
30#include <stddef.h>
31#ifdef LINUX1
32#include <elf.h>
33#include <link.h>
34#include "proc_service.h"
35#include "salibelf.h"
36#endif
37#include "libproc_impl.h"
38#include "cds.h"
39
40#ifdef __APPLE__
41#include "sun_jvm_hotspot_debugger_amd64_AMD64ThreadContext.h"
42#endif
43
44// Define a segment permission flag allowing read if there is a read flag. Otherwise use 0.
45#ifdef PF_R(1 << 2)
46#define MAP_R_FLAG(1 << 2) PF_R(1 << 2)
47#else
48#define MAP_R_FLAG(1 << 2) 0
49#endif
50
51#ifdef LINUX1
52// I have no idea why this function is called ps_pread() on macos but ps_pdread on linux.
53#define ps_preadps_pdread ps_pdread
54#endif
55
56// Common code shared between linux/native/libsaproc/ps_core.c and macosx/native/libsaproc/ps_core.c
57
58//----------------------------------------------------------------------
59// ps_prochandle cleanup helper functions
60
61// close all file descriptors
62static void close_files(struct ps_prochandle* ph) {
63 lib_info* lib = NULL((void*)0);
64
65 // close core file descriptor
66 if (ph->core->core_fd >= 0)
67 close(ph->core->core_fd);
68
69 // close exec file descriptor
70 if (ph->core->exec_fd >= 0)
71 close(ph->core->exec_fd);
72
73 // close interp file descriptor
74 if (ph->core->interp_fd >= 0)
75 close(ph->core->interp_fd);
76
77 // close class share archive file
78 if (ph->core->classes_jsa_fd >= 0)
79 close(ph->core->classes_jsa_fd);
80
81 // close all library file descriptors
82 lib = ph->libs;
83 while (lib) {
84 int fd = lib->fd;
85 if (fd >= 0 && fd != ph->core->exec_fd) {
86 close(fd);
87 }
88 lib = lib->next;
89 }
90}
91
92// clean all map_info stuff
93static void destroy_map_info(struct ps_prochandle* ph) {
94 map_info* map = ph->core->maps;
95 while (map) {
96 map_info* next = map->next;
97 free(map);
98 map = next;
99 }
100
101 if (ph->core->map_array) {
102 free(ph->core->map_array);
103 }
104
105 // Part of the class sharing workaround
106 map = ph->core->class_share_maps;
107 while (map) {
108 map_info* next = map->next;
109 free(map);
110 map = next;
111 }
112}
113
114// ps_prochandle operations
115void core_release(struct ps_prochandle* ph) {
116 if (ph->core) {
117 close_files(ph);
118 destroy_map_info(ph);
119 free(ph->core);
120 }
121}
122
123static map_info* allocate_init_map(int fd, off_t offset, uintptr_t vaddr, size_t memsz, uint32_t flags) {
124 map_info* map;
125 if ( (map = (map_info*) calloc(1, sizeof(map_info))) == NULL((void*)0)) {
126 print_debug("can't allocate memory for map_info\n");
127 return NULL((void*)0);
128 }
129
130 // initialize map
131 map->fd = fd;
132 map->offset = offset;
133 map->vaddr = vaddr;
134 map->memsz = memsz;
135 map->flags = flags;
136 return map;
137}
138
139// add map info with given fd, offset, vaddr and memsz
140map_info* add_map_info(struct ps_prochandle* ph, int fd, off_t offset,
141 uintptr_t vaddr, size_t memsz, uint32_t flags) {
142 map_info* map;
143 if ((map = allocate_init_map(fd, offset, vaddr, memsz, flags)) == NULL((void*)0)) {
144 return NULL((void*)0);
145 }
146
147 // add this to map list
148 map->next = ph->core->maps;
149 ph->core->maps = map;
150 ph->core->num_maps++;
151
152 return map;
153}
154
155// Part of the class sharing workaround
156static map_info* add_class_share_map_info(struct ps_prochandle* ph, off_t offset,
157 uintptr_t vaddr, size_t memsz) {
158 map_info* map;
159 if ((map = allocate_init_map(ph->core->classes_jsa_fd,
160 offset, vaddr, memsz, MAP_R_FLAG(1 << 2))) == NULL((void*)0)) {
161 return NULL((void*)0);
162 }
163
164 map->next = ph->core->class_share_maps;
165 ph->core->class_share_maps = map;
166 return map;
167}
168
169// Return the map_info for the given virtual address. We keep a sorted
170// array of pointers in ph->map_array, so we can binary search.
171map_info* core_lookup(struct ps_prochandle *ph, uintptr_t addr) {
172 int mid, lo = 0, hi = ph->core->num_maps - 1;
173 map_info *mp;
174
175 while (hi - lo > 1) {
176 mid = (lo + hi) / 2;
177 if (addr >= ph->core->map_array[mid]->vaddr) {
178 lo = mid;
179 } else {
180 hi = mid;
181 }
182 }
183
184 if (addr < ph->core->map_array[hi]->vaddr) {
185 mp = ph->core->map_array[lo];
186 } else {
187 mp = ph->core->map_array[hi];
188 }
189
190 if (addr >= mp->vaddr && addr < mp->vaddr + mp->memsz) {
191 return (mp);
192 }
193
194
195 // Part of the class sharing workaround
196 // Unfortunately, we have no way of detecting -Xshare state.
197 // Check out the share maps atlast, if we don't find anywhere.
198 // This is done this way so to avoid reading share pages
199 // ahead of other normal maps. For eg. with -Xshare:off we don't
200 // want to prefer class sharing data to data from core.
201 mp = ph->core->class_share_maps;
202 if (mp) {
203 print_debug("can't locate map_info at 0x%lx, trying class share maps\n", addr);
204 }
205 while (mp) {
206 if (addr >= mp->vaddr && addr < mp->vaddr + mp->memsz) {
207 print_debug("located map_info at 0x%lx from class share maps\n", addr);
208 return (mp);
209 }
210 mp = mp->next;
211 }
212
213 print_debug("can't locate map_info at 0x%lx\n", addr);
214 return (NULL((void*)0));
215}
216
217//---------------------------------------------------------------
218// Part of the class sharing workaround:
219//
220// With class sharing, pages are mapped from classes.jsa file.
221// The read-only class sharing pages are mapped as MAP_SHARED,
222// PROT_READ pages. These pages are not dumped into core dump.
223// With this workaround, these pages are read from classes.jsa.
224
225static bool read_jboolean(struct ps_prochandle* ph, uintptr_t addr, jboolean* pvalue) {
226 jboolean i;
227 if (ps_preadps_pdread(ph, (psaddr_t) addr, &i, sizeof(i)) == PS_OK) {
228 *pvalue = i;
229 return true1;
230 } else {
231 return false0;
232 }
233}
234
235static bool read_pointer(struct ps_prochandle* ph, uintptr_t addr, uintptr_t* pvalue) {
236 uintptr_t uip;
237 if (ps_preadps_pdread(ph, (psaddr_t) addr, (char *)&uip, sizeof(uip)) == PS_OK) {
238 *pvalue = uip;
239 return true1;
240 } else {
241 return false0;
242 }
243}
244
245// used to read strings from debuggee
246bool read_string(struct ps_prochandle* ph, uintptr_t addr, char* buf, size_t size) {
247 size_t i = 0;
248 char c = ' ';
249
250 while (c != '\0') {
251 if (ps_preadps_pdread(ph, (psaddr_t) addr, &c, sizeof(char)) != PS_OK) {
252 return false0;
253 }
254 if (i < size - 1) {
255 buf[i] = c;
256 } else {
257 // smaller buffer
258 return false0;
259 }
260 i++; addr++;
261 }
262 buf[i] = '\0';
263 return true1;
264}
265
266#ifdef LINUX1
267// mangled name of Arguments::SharedArchivePath
268#define SHARED_ARCHIVE_PATH_SYM"_ZN9Arguments17SharedArchivePathE" "_ZN9Arguments17SharedArchivePathE"
269#define USE_SHARED_SPACES_SYM"UseSharedSpaces" "UseSharedSpaces"
270#define SHARED_BASE_ADDRESS_SYM"SharedBaseAddress" "SharedBaseAddress"
271#define LIBJVM_NAME"/libjvm.so" "/libjvm.so"
272#endif
273
274#ifdef __APPLE__
275// mangled name of Arguments::SharedArchivePath
276#define SHARED_ARCHIVE_PATH_SYM"_ZN9Arguments17SharedArchivePathE" "__ZN9Arguments17SharedArchivePathE"
277#define USE_SHARED_SPACES_SYM"UseSharedSpaces" "_UseSharedSpaces"
278#define SHARED_BASE_ADDRESS_SYM"SharedBaseAddress" "_SharedBaseAddress"
279#define LIBJVM_NAME"/libjvm.so" "/libjvm.dylib"
280#endif
281
282bool init_classsharing_workaround(struct ps_prochandle* ph) {
283 lib_info* lib = ph->libs;
284 while (lib != NULL((void*)0)) {
285 // we are iterating over shared objects from the core dump. look for
286 // libjvm.so.
287 const char *jvm_name = 0;
288 if ((jvm_name = strstr(lib->name, LIBJVM_NAME"/libjvm.so")) != 0) {
289 char classes_jsa[PATH_MAX4096];
290 CDSFileMapHeaderBase header;
291 int fd = -1;
292 uintptr_t useSharedSpacesAddr = 0;
293 uintptr_t sharedBaseAddressAddr = 0, sharedBaseAddress = 0;
294 uintptr_t sharedArchivePathAddrAddr = 0, sharedArchivePathAddr = 0;
295 jboolean useSharedSpaces = 0;
296 int m;
297 size_t n;
298
299 memset(classes_jsa, 0, sizeof(classes_jsa));
300 jvm_name = lib->name;
301 useSharedSpacesAddr = lookup_symbol(ph, jvm_name, USE_SHARED_SPACES_SYM"UseSharedSpaces");
302 if (useSharedSpacesAddr == 0) {
303 print_debug("can't lookup 'UseSharedSpaces' symbol\n");
304 return false0;
305 }
306
307 // Hotspot vm types are not exported to build this library. So
308 // using equivalent type jboolean to read the value of
309 // UseSharedSpaces which is same as hotspot type "bool".
310 if (read_jboolean(ph, useSharedSpacesAddr, &useSharedSpaces) != true1) {
311 print_debug("can't read the value of 'UseSharedSpaces' symbol\n");
312 return false0;
313 }
314
315 if ((int)useSharedSpaces == 0) {
316 print_debug("UseSharedSpaces is false, assuming -Xshare:off!\n");
317 return true1;
318 }
319
320 sharedBaseAddressAddr = lookup_symbol(ph, jvm_name, SHARED_BASE_ADDRESS_SYM"SharedBaseAddress");
321 if (sharedBaseAddressAddr == 0) {
322 print_debug("can't lookup 'SharedBaseAddress' flag\n");
323 return false0;
324 }
325
326 if (read_pointer(ph, sharedBaseAddressAddr, &sharedBaseAddress) != true1) {
327 print_debug("can't read the value of 'SharedBaseAddress' flag\n");
328 return false0;
329 }
330
331 sharedArchivePathAddrAddr = lookup_symbol(ph, jvm_name, SHARED_ARCHIVE_PATH_SYM"_ZN9Arguments17SharedArchivePathE");
332 if (sharedArchivePathAddrAddr == 0) {
333 print_debug("can't lookup shared archive path symbol\n");
334 return false0;
335 }
336
337 if (read_pointer(ph, sharedArchivePathAddrAddr, &sharedArchivePathAddr) != true1) {
338 print_debug("can't read shared archive path pointer\n");
339 return false0;
340 }
341
342 if (read_string(ph, sharedArchivePathAddr, classes_jsa, sizeof(classes_jsa)) != true1) {
343 print_debug("can't read shared archive path value\n");
344 return false0;
345 }
346
347 print_debug("looking for %s\n", classes_jsa);
348 // open the class sharing archive file
349 fd = pathmap_open(classes_jsa);
350 if (fd < 0) {
351 print_debug("can't open %s!\n", classes_jsa);
352 ph->core->classes_jsa_fd = -1;
353 return false0;
354 } else {
355 print_debug("opened %s\n", classes_jsa);
356 }
357
358 // read CDSFileMapHeaderBase from the file
359 size_t header_size = sizeof(CDSFileMapHeaderBase);
360 memset(&header, 0, header_size);
361 if ((n = read(fd, &header, header_size))
Although the value stored to 'n' is used in the enclosing expression, the value is never actually read from 'n'
362 != header_size) {
363 print_debug("can't read shared archive file map header from %s\n", classes_jsa);
364 close(fd);
365 return false0;
366 }
367
368 // check file magic
369 if (header._generic_header._magic != CDS_ARCHIVE_MAGIC0xf00baba2) {
370 print_debug("%s has bad shared archive file magic number 0x%x, expecting 0x%x\n",
371 classes_jsa, header._generic_header._magic, CDS_ARCHIVE_MAGIC0xf00baba2);
372 close(fd);
373 return false0;
374 }
375
376 // check version
377 if (header._generic_header._version != CURRENT_CDS_ARCHIVE_VERSION12) {
378 print_debug("%s has wrong shared archive file version %d, expecting %d\n",
379 classes_jsa, header._generic_header._version, CURRENT_CDS_ARCHIVE_VERSION12);
380 close(fd);
381 return false0;
382 }
383
384 ph->core->classes_jsa_fd = fd;
385 // add read-only maps from classes.jsa to the list of maps
386 for (m = 0; m < NUM_CDS_REGIONS7; m++) {
387 if (header._space[m]._read_only &&
388 !header._space[m]._is_heap_region &&
389 !header._space[m]._is_bitmap_region) {
390 // With *some* linux versions, the core file doesn't include read-only mmap'ed
391 // files regions, so let's add them here. This is harmless if the core file also
392 // include these regions.
393 uintptr_t base = sharedBaseAddress + (uintptr_t) header._space[m]._mapping_offset;
394 size_t size = header._space[m]._used;
395 // no need to worry about the fractional pages at-the-end.
396 // possible fractional pages are handled by core_read_data.
397 add_class_share_map_info(ph, (off_t) header._space[m]._file_offset,
398 base, size);
399 print_debug("added a share archive map [%d] at 0x%lx (size 0x%lx bytes)\n", m, base, size);
400 }
401 }
402 return true1;
403 }
404 lib = lib->next;
405 }
406 return true1;
407}
408
409#endif // defined(LINUX) || defined(__APPLE__)