Bug Summary

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

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) {
Although the value stored to 'jvm_name' is used in the enclosing expression, the value is never actually read from 'jvm_name'
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))
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__)