Bug Summary

File:jdk/src/java.desktop/share/native/common/awt/debug/debug_trace.c
Warning:line 134, column 10
Dereference of null pointer (loaded from variable 'plineid')

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 debug_trace.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 __MEDIALIB_OLD_NAMES -D __USE_J2D_NAMES -D MLIB_NO_LIBSUNMATH -I /home/daniel/Projects/java/jdk/src/java.desktop/unix/native/libawt -I /home/daniel/Projects/java/jdk/src/java.desktop/share/native/libawt -I /home/daniel/Projects/java/jdk/src/java.desktop/share/native/common/awt/debug -I /home/daniel/Projects/java/jdk/src/java.desktop/unix/native/common/awt -I /home/daniel/Projects/java/jdk/build/linux-x86_64-server-fastdebug/support/headers/java.desktop -I /home/daniel/Projects/java/jdk/src/java.desktop/share/native/libawt/awt/image -I /home/daniel/Projects/java/jdk/src/java.desktop/share/native/libawt/awt/image/cvutils -I /home/daniel/Projects/java/jdk/src/java.desktop/unix/native/libawt/java2d -I /home/daniel/Projects/java/jdk/src/java.desktop/share/native/libawt/java2d -I /home/daniel/Projects/java/jdk/src/java.desktop/share/native/libawt/java2d/loops -I /home/daniel/Projects/java/jdk/src/java.desktop/share/native/libawt/java2d/pipe -I /home/daniel/Projects/java/jdk/build/linux-x86_64-server-fastdebug/support/headers/java.base -I /home/daniel/Projects/java/jdk/src/java.desktop/share/native/libawt/awt/medialib -I /home/daniel/Projects/java/jdk/src/java.desktop/share/native/common/awt/medialib -I /home/daniel/Projects/java/jdk/src/java.desktop/share/native/libmlib_image -I /home/daniel/Projects/java/jdk/src/java.desktop/unix/native/include -I /home/daniel/Projects/java/jdk/src/java.desktop/share/native/include -I /home/daniel/Projects/java/jdk/src/java.base/linux/native/libjava -I /home/daniel/Projects/java/jdk/src/java.base/unix/native/libjava -I /home/daniel/Projects/java/jdk/src/java.base/share/native/libjava -I /home/daniel/Projects/java/jdk/src/java.base/unix/native/include -I /home/daniel/Projects/java/jdk/src/java.base/share/native/include -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 -O3 -Wno-unused-parameter -Wno-unused -Wno-sign-compare -Wno-unused-result -Wno-maybe-uninitialized -Wno-format-nonliteral -Wno-parentheses -Wno-unused-value -Wno-unused-function -std=c99 -fdebug-compilation-dir /home/daniel/Projects/java/jdk/make -ferror-limit 19 -fmessage-length 0 -fvisibility default -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/java.desktop/share/native/common/awt/debug/debug_trace.c
1/*
2 * Copyright (c) 1999, 2018, 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. Oracle designates this
8 * particular file as subject to the "Classpath" exception as provided
9 * by Oracle in the LICENSE file that accompanied this code.
10 *
11 * This code is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14 * version 2 for more details (a copy is included in the LICENSE file that
15 * accompanied this code).
16 *
17 * You should have received a copy of the GNU General Public License version
18 * 2 along with this work; if not, write to the Free Software Foundation,
19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20 *
21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22 * or visit www.oracle.com if you need additional information or have any
23 * questions.
24 */
25
26#include "debug_util.h"
27
28static void JNICALL DTrace_PrintStdErr(const char *msg);
29
30#if defined(DEBUG1)
31enum {
32 MAX_TRACES = 200, /* max number of defined trace points allowed */
33 MAX_TRACE_BUFFER = 512, /* maximum size of a given trace output */
34 MAX_LINE = 100000, /* reasonable upper limit on line number in source file */
35 MAX_ARGC = 8 /* maximum number of arguments to print functions */
36};
37
38typedef enum dtrace_scope {
39 DTRACE_FILE,
40 DTRACE_LINE
41} dtrace_scope;
42
43typedef struct dtrace_info {
44 char file[FILENAME_MAX4096+1];
45 int line;
46 int enabled;
47 dtrace_scope scope;
48} dtrace_info, * p_dtrace_info;
49
50static dtrace_info DTraceInfo[MAX_TRACES];
51static char DTraceBuffer[MAX_TRACE_BUFFER*2+1]; /* double the buffer size to catch overruns */
52static dmutex_t DTraceMutex = NULL((void*)0);
53static dbool_t GlobalTracingEnabled = FALSE0;
54static int NumTraces = 0;
55
56static DTRACE_OUTPUT_CALLBACK PfnTraceCallback = DTrace_PrintStdErr;
57
58static p_dtrace_info DTrace_GetInfo(dtrace_id tid) {
59 DASSERT(tid < MAX_TRACES)if ( !(tid < MAX_TRACES) ) { DAssert_Impl( "tid < MAX_TRACES"
, "/home/daniel/Projects/java/jdk/src/java.desktop/share/native/common/awt/debug/debug_trace.c"
, 59); } else { }
;
60 return &DTraceInfo[tid];
61}
62
63static dtrace_id DTrace_CreateTraceId(const char * file, int line, dtrace_scope scope) {
64 dtrace_id tid = NumTraces++;
65 p_dtrace_info info = &DTraceInfo[tid];
66 DASSERT(NumTraces < MAX_TRACES)if ( !(NumTraces < MAX_TRACES) ) { DAssert_Impl( "NumTraces < MAX_TRACES"
, "/home/daniel/Projects/java/jdk/src/java.desktop/share/native/common/awt/debug/debug_trace.c"
, 66); } else { }
;
67
68 strcpy(info->file, file);
69 info->line = line;
70 info->enabled = FALSE0;
71 info->scope = scope;
72 return tid;
73}
74
75/*
76 * Compares the trailing characters in a filename to see if they match
77 * e.g. "src\win32\foobar.c" and "foobar.c" would be considered equal
78 * but "src\win32\foo.c" and "src\win32\bar.c" would not.
79 */
80static dbool_t FileNamesSame(const char * fileOne, const char * fileTwo) {
81 size_t lengthOne = strlen(fileOne);
82 size_t lengthTwo = strlen(fileTwo);
83 size_t numCompareChars;
84 dbool_t tailsEqual;
85
86 if (fileOne == fileTwo) {
87 return TRUE1;
88 } else if (fileOne == NULL((void*)0) || fileTwo == NULL((void*)0)) {
89 return FALSE0;
90 }
91 /* compare the tail ends of the strings for equality */
92 numCompareChars = lengthOne < lengthTwo ? lengthOne : lengthTwo;
93 tailsEqual = strcmp(fileOne + lengthOne - numCompareChars,
94 fileTwo + lengthTwo - numCompareChars) == 0;
95 return tailsEqual;
96}
97
98/*
99 * Finds the trace id for a given file/line location or creates one
100 * if it doesn't exist
101 */
102static dtrace_id DTrace_GetTraceId(const char * file, int line, dtrace_scope scope) {
103 dtrace_id tid;
104 p_dtrace_info info;
105
106 /* check to see if the trace point has already been created */
107 for ( tid = 0; tid < NumTraces; tid++ ) {
108 info = DTrace_GetInfo(tid);
109 if ( info->scope == scope ) {
110 dbool_t sameFile = FileNamesSame(file, info->file);
111 dbool_t sameLine = info->line == line;
112
113 if ( (info->scope == DTRACE_FILE && sameFile) ||
114 (info->scope == DTRACE_LINE && sameFile && sameLine) ) {
115 goto Exit;
116 }
117 }
118 }
119
120 /* trace point wasn't created, so force it's creation */
121 tid = DTrace_CreateTraceId(file, line, scope);
122Exit:
123 return tid;
124}
125
126
127static dbool_t DTrace_IsEnabledAt(dtrace_id * pfileid, dtrace_id * plineid, const char * file, int line) {
128 DASSERT(pfileid != NULL && plineid != NULL)if ( !(pfileid != ((void*)0) && plineid != ((void*)0)
) ) { DAssert_Impl( "pfileid != NULL && plineid != NULL"
, "/home/daniel/Projects/java/jdk/src/java.desktop/share/native/common/awt/debug/debug_trace.c"
, 128); } else { }
;
11
Assuming 'pfileid' is not equal to null
12
Assuming 'plineid' is equal to null
13
Taking true branch
129
130 if ( *pfileid == UNDEFINED_TRACE_ID ) {
14
Assuming the condition is false
15
Taking false branch
131 /* first time calling the trace for this file, so obtain a trace id */
132 *pfileid = DTrace_GetTraceId(file, -1, DTRACE_FILE);
133 }
134 if ( *plineid == UNDEFINED_TRACE_ID ) {
16
Dereference of null pointer (loaded from variable 'plineid')
135 /* first time calling the trace for this line, so obtain a trace id */
136 *plineid = DTrace_GetTraceId(file, line, DTRACE_LINE);
137 }
138
139 return GlobalTracingEnabled || DTraceInfo[*pfileid].enabled || DTraceInfo[*plineid].enabled;
140}
141
142/*
143 * Initialize trace functionality. This MUST BE CALLED before any
144 * tracing function is called.
145 */
146void DTrace_Initialize() {
147 DTraceMutex = DMutex_Create();
148}
149
150/*
151 * Cleans up tracing system. Should be called when tracing functionality
152 * is no longer needed.
153 */
154void DTrace_Shutdown() {
155 DMutex_Destroy(DTraceMutex);
156}
157
158void DTrace_DisableMutex() {
159 DTraceMutex = NULL((void*)0);
160}
161
162/*
163 * Enable tracing for all modules.
164 */
165void DTrace_EnableAll(dbool_t enabled) {
166 DMutex_Enter(DTraceMutex);
167 GlobalTracingEnabled = enabled;
168 DMutex_Exit(DTraceMutex);
169}
170
171/*
172 * Enable tracing for a specific module. Filename may
173 * be fully or partially qualified.
174 * e.g. awt_Component.cpp
175 * or
176 * src\win32\native\sun\windows\awt_Component.cpp
177 */
178void DTrace_EnableFile(const char * file, dbool_t enabled) {
179 dtrace_id tid;
180 p_dtrace_info info;
181
182 DASSERT(file != NULL)if ( !(file != ((void*)0)) ) { DAssert_Impl( "file != NULL", "/home/daniel/Projects/java/jdk/src/java.desktop/share/native/common/awt/debug/debug_trace.c"
, 182); } else { }
;
183 DMutex_Enter(DTraceMutex);
184 tid = DTrace_GetTraceId(file, -1, DTRACE_FILE);
185 info = DTrace_GetInfo(tid);
186 info->enabled = enabled;
187 DMutex_Exit(DTraceMutex);
188}
189
190/*
191 * Enable tracing for a specific line in a specific module.
192 * See comments above regarding filename argument.
193 */
194void DTrace_EnableLine(const char * file, int line, dbool_t enabled) {
195 dtrace_id tid;
196 p_dtrace_info info;
197
198 DASSERT(file != NULL && (line > 0 && line < MAX_LINE))if ( !(file != ((void*)0) && (line > 0 && line
< MAX_LINE)) ) { DAssert_Impl( "file != NULL && (line > 0 && line < MAX_LINE)"
, "/home/daniel/Projects/java/jdk/src/java.desktop/share/native/common/awt/debug/debug_trace.c"
, 198); } else { }
;
199 DMutex_Enter(DTraceMutex);
200 tid = DTrace_GetTraceId(file, line, DTRACE_LINE);
201 info = DTrace_GetInfo(tid);
202 info->enabled = enabled;
203 DMutex_Exit(DTraceMutex);
204}
205
206static void DTrace_ClientPrint(const char * msg) {
207 DASSERT(msg != NULL && PfnTraceCallback != NULL)if ( !(msg != ((void*)0) && PfnTraceCallback != ((void
*)0)) ) { DAssert_Impl( "msg != NULL && PfnTraceCallback != NULL"
, "/home/daniel/Projects/java/jdk/src/java.desktop/share/native/common/awt/debug/debug_trace.c"
, 207); } else { }
;
208 (*PfnTraceCallback)(msg);
209}
210
211/*
212 * Print implementation for the use of client defined trace macros. Unsynchronized so it must
213 * be used from within a DTRACE_PRINT_CALLBACK function.
214 */
215void DTrace_VPrintImpl(const char * fmt, va_list arglist) {
216 DASSERT(fmt != NULL)if ( !(fmt != ((void*)0)) ) { DAssert_Impl( "fmt != NULL", "/home/daniel/Projects/java/jdk/src/java.desktop/share/native/common/awt/debug/debug_trace.c"
, 216); } else { }
;
217
218 /* format the trace message */
219 vsprintf(DTraceBuffer, fmt, arglist);
220 /* not a real great overflow check (memory would already be hammered) but better than nothing */
221 DASSERT(strlen(DTraceBuffer) < MAX_TRACE_BUFFER)if ( !(strlen(DTraceBuffer) < MAX_TRACE_BUFFER) ) { DAssert_Impl
( "strlen(DTraceBuffer) < MAX_TRACE_BUFFER", "/home/daniel/Projects/java/jdk/src/java.desktop/share/native/common/awt/debug/debug_trace.c"
, 221); } else { }
;
222 /* output the trace message */
223 DTrace_ClientPrint(DTraceBuffer);
224}
225
226/*
227 * Print implementation for the use of client defined trace macros. Unsynchronized so it must
228 * be used from within a DTRACE_PRINT_CALLBACK function.
229 */
230void DTrace_PrintImpl(const char * fmt, ...) {
231 va_list arglist;
232
233 va_start(arglist, fmt)__builtin_va_start(arglist, fmt);
234 DTrace_VPrintImpl(fmt, arglist);
235 va_end(arglist)__builtin_va_end(arglist);
236}
237
238/*
239 * Called via DTRACE_PRINT macro. Outputs printf style formatted text.
240 * JNIEXPORT because these functions are also called from libawt_xawt.
241 */
242JNIEXPORT__attribute__((visibility("default"))) void JNICALL
243DTrace_VPrint( const char * file, int line, int argc, const char * fmt, va_list arglist ) {
244 DASSERT(fmt != NULL)if ( !(fmt != ((void*)0)) ) { DAssert_Impl( "fmt != NULL", "/home/daniel/Projects/java/jdk/src/java.desktop/share/native/common/awt/debug/debug_trace.c"
, 244); } else { }
;
245 DTrace_VPrintImpl(fmt, arglist);
246}
247
248/*
249 * Called via DTRACE_PRINTLN macro. Outputs printf style formatted text with an automatic newline.
250 * JNIEXPORT because these functions are also called from libawt_xawt.
251 */
252JNIEXPORT__attribute__((visibility("default"))) void JNICALL
253DTrace_VPrintln( const char * file, int line, int argc, const char * fmt, va_list arglist ) {
254 DTrace_VPrintImpl(fmt, arglist);
255 DTrace_PrintImpl("\n");
256}
257
258/*
259 * Called via DTRACE_ macros. If tracing is enabled at the given location, it enters
260 * the trace mutex and invokes the callback function to output the trace.
261 * JNIEXPORT because these functions are also called from libawt_xawt.
262 */
263JNIEXPORT__attribute__((visibility("default"))) void JNICALL
264DTrace_PrintFunction( DTRACE_PRINT_CALLBACK pfn, dtrace_id * pFileTraceId, dtrace_id * pLineTraceId,
265 const char * file, int line,
266 int argc, const char * fmt, ... ) {
267 va_list arglist;
268
269 DASSERT(file != NULL)if ( !(file != ((void*)0)) ) { DAssert_Impl( "file != NULL", "/home/daniel/Projects/java/jdk/src/java.desktop/share/native/common/awt/debug/debug_trace.c"
, 269); } else { }
;
1
Assuming 'file' is not equal to null
2
Taking false branch
270 DASSERT(line > 0 && line < MAX_LINE)if ( !(line > 0 && line < MAX_LINE) ) { DAssert_Impl
( "line > 0 && line < MAX_LINE", "/home/daniel/Projects/java/jdk/src/java.desktop/share/native/common/awt/debug/debug_trace.c"
, 270); } else { }
;
3
Assuming 'line' is <= 0
4
Taking true branch
271 DASSERT(argc <= MAX_ARGC)if ( !(argc <= MAX_ARGC) ) { DAssert_Impl( "argc <= MAX_ARGC"
, "/home/daniel/Projects/java/jdk/src/java.desktop/share/native/common/awt/debug/debug_trace.c"
, 271); } else { }
;
5
Assuming 'argc' is <= MAX_ARGC
6
Taking false branch
272 DASSERT(fmt != NULL)if ( !(fmt != ((void*)0)) ) { DAssert_Impl( "fmt != NULL", "/home/daniel/Projects/java/jdk/src/java.desktop/share/native/common/awt/debug/debug_trace.c"
, 272); } else { }
;
7
Assuming 'fmt' is not equal to null
8
Taking false branch
273
274 DMutex_Enter(DTraceMutex);
275 if ( DTrace_IsEnabledAt(pFileTraceId, pLineTraceId, file, line) ) {
9
Passing value via 2nd parameter 'plineid'
10
Calling 'DTrace_IsEnabledAt'
276 va_start(arglist, fmt)__builtin_va_start(arglist, fmt);
277 (*pfn)(file, line, argc, fmt, arglist);
278 va_end(arglist)__builtin_va_end(arglist);
279 }
280 DMutex_Exit(DTraceMutex);
281}
282
283/*
284 * Sets a callback function to be used to output
285 * trace statements.
286 */
287void DTrace_SetOutputCallback(DTRACE_OUTPUT_CALLBACK pfn) {
288 DASSERT(pfn != NULL)if ( !(pfn != ((void*)0)) ) { DAssert_Impl( "pfn != NULL", "/home/daniel/Projects/java/jdk/src/java.desktop/share/native/common/awt/debug/debug_trace.c"
, 288); } else { }
;
289
290 DMutex_Enter(DTraceMutex);
291 PfnTraceCallback = pfn;
292 DMutex_Exit(DTraceMutex);
293}
294
295#endif /* DEBUG */
296
297/**********************************************************************************
298 * Support for Java tracing in release or debug mode builds
299 */
300
301static void JNICALL DTrace_PrintStdErr(const char *msg) {
302 fprintf(stderr, "%s", msg)__fprintf_chk (stderr, 2 - 1, "%s", msg);
303 fflush(stderrstderr);
304}
305
306static void DTrace_JavaPrint(const char * msg) {
307#if defined(DEBUG1)
308 DMutex_Enter(DTraceMutex);
309 DTrace_ClientPrint(msg);
310 DMutex_Exit(DTraceMutex);
311#else
312 DTrace_PrintStdErr(msg);
313#endif
314}
315
316static void DTrace_JavaPrintln(const char * msg) {
317#if defined(DEBUG1)
318 DMutex_Enter(DTraceMutex);
319 DTrace_ClientPrint(msg);
320 DTrace_ClientPrint("\n");
321 DMutex_Exit(DTraceMutex);
322#else
323 DTrace_PrintStdErr(msg);
324 DTrace_PrintStdErr("\n");
325#endif
326}
327
328/*********************************************************************************
329 * Native method implementations. Java print trace calls are functional in
330 * release builds, but functions to enable/disable native tracing are not.
331 */
332
333/* Implementation of DebugSettings.setCTracingOn*/
334JNIEXPORT__attribute__((visibility("default"))) void JNICALL
335Java_sun_awt_DebugSettings_setCTracingOn__Z(JNIEnv *env, jobject self, jboolean enabled) {
336#if defined(DEBUG1)
337 DTrace_EnableAll(enabled == JNI_TRUE1);
338#endif
339}
340
341/* Implementation of DebugSettings.setCTracingOn*/
342JNIEXPORT__attribute__((visibility("default"))) void JNICALL
343Java_sun_awt_DebugSettings_setCTracingOn__ZLjava_lang_String_2(
344 JNIEnv *env,
345 jobject self,
346 jboolean enabled,
347 jstring file ) {
348#if defined(DEBUG1)
349 const char * cfile;
350 cfile = JNU_GetStringPlatformChars(env, file, NULL((void*)0));
351 if ( cfile == NULL((void*)0) ) {
352 return;
353 }
354 DTrace_EnableFile(cfile, enabled == JNI_TRUE1);
355 JNU_ReleaseStringPlatformChars(env, file, cfile);
356#endif
357}
358
359/* Implementation of DebugSettings.setCTracingOn*/
360JNIEXPORT__attribute__((visibility("default"))) void JNICALL
361Java_sun_awt_DebugSettings_setCTracingOn__ZLjava_lang_String_2I(
362 JNIEnv *env,
363 jobject self,
364 jboolean enabled,
365 jstring file,
366 jint line ) {
367#if defined(DEBUG1)
368 const char * cfile;
369 cfile = JNU_GetStringPlatformChars(env, file, NULL((void*)0));
370 if ( cfile == NULL((void*)0) ) {
371 return;
372 }
373 DTrace_EnableLine(cfile, line, enabled == JNI_TRUE1);
374 JNU_ReleaseStringPlatformChars(env, file, cfile);
375#endif
376}