Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
PojavLauncherTeam
GitHub Repository: PojavLauncherTeam/mobile
Path: blob/master/src/java.desktop/share/native/common/awt/debug/debug_trace.c
41171 views
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
28
static void JNICALL DTrace_PrintStdErr(const char *msg);
29
30
#if defined(DEBUG)
31
enum {
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
38
typedef enum dtrace_scope {
39
DTRACE_FILE,
40
DTRACE_LINE
41
} dtrace_scope;
42
43
typedef struct dtrace_info {
44
char file[FILENAME_MAX+1];
45
int line;
46
int enabled;
47
dtrace_scope scope;
48
} dtrace_info, * p_dtrace_info;
49
50
static dtrace_info DTraceInfo[MAX_TRACES];
51
static char DTraceBuffer[MAX_TRACE_BUFFER*2+1]; /* double the buffer size to catch overruns */
52
static dmutex_t DTraceMutex = NULL;
53
static dbool_t GlobalTracingEnabled = FALSE;
54
static int NumTraces = 0;
55
56
static DTRACE_OUTPUT_CALLBACK PfnTraceCallback = DTrace_PrintStdErr;
57
58
static p_dtrace_info DTrace_GetInfo(dtrace_id tid) {
59
DASSERT(tid < MAX_TRACES);
60
return &DTraceInfo[tid];
61
}
62
63
static 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);
67
68
strcpy(info->file, file);
69
info->line = line;
70
info->enabled = FALSE;
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
*/
80
static 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 TRUE;
88
} else if (fileOne == NULL || fileTwo == NULL) {
89
return FALSE;
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
*/
102
static 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);
122
Exit:
123
return tid;
124
}
125
126
127
static dbool_t DTrace_IsEnabledAt(dtrace_id * pfileid, dtrace_id * plineid, const char * file, int line) {
128
DASSERT(pfileid != NULL && plineid != NULL);
129
130
if ( *pfileid == UNDEFINED_TRACE_ID ) {
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 ) {
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
*/
146
void 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
*/
154
void DTrace_Shutdown() {
155
DMutex_Destroy(DTraceMutex);
156
}
157
158
void DTrace_DisableMutex() {
159
DTraceMutex = NULL;
160
}
161
162
/*
163
* Enable tracing for all modules.
164
*/
165
void 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
*/
178
void DTrace_EnableFile(const char * file, dbool_t enabled) {
179
dtrace_id tid;
180
p_dtrace_info info;
181
182
DASSERT(file != NULL);
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
*/
194
void 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));
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
206
static void DTrace_ClientPrint(const char * msg) {
207
DASSERT(msg != NULL && PfnTraceCallback != NULL);
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
*/
215
void DTrace_VPrintImpl(const char * fmt, va_list arglist) {
216
DASSERT(fmt != NULL);
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);
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
*/
230
void DTrace_PrintImpl(const char * fmt, ...) {
231
va_list arglist;
232
233
va_start(arglist, fmt);
234
DTrace_VPrintImpl(fmt, arglist);
235
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
*/
242
JNIEXPORT void JNICALL
243
DTrace_VPrint( const char * file, int line, int argc, const char * fmt, va_list arglist ) {
244
DASSERT(fmt != NULL);
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
*/
252
JNIEXPORT void JNICALL
253
DTrace_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
*/
263
JNIEXPORT void JNICALL
264
DTrace_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);
270
DASSERT(line > 0 && line < MAX_LINE);
271
DASSERT(argc <= MAX_ARGC);
272
DASSERT(fmt != NULL);
273
274
DMutex_Enter(DTraceMutex);
275
if ( DTrace_IsEnabledAt(pFileTraceId, pLineTraceId, file, line) ) {
276
va_start(arglist, fmt);
277
(*pfn)(file, line, argc, fmt, arglist);
278
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
*/
287
void DTrace_SetOutputCallback(DTRACE_OUTPUT_CALLBACK pfn) {
288
DASSERT(pfn != NULL);
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
301
static void JNICALL DTrace_PrintStdErr(const char *msg) {
302
fprintf(stderr, "%s", msg);
303
fflush(stderr);
304
}
305
306
static void DTrace_JavaPrint(const char * msg) {
307
#if defined(DEBUG)
308
DMutex_Enter(DTraceMutex);
309
DTrace_ClientPrint(msg);
310
DMutex_Exit(DTraceMutex);
311
#else
312
DTrace_PrintStdErr(msg);
313
#endif
314
}
315
316
static void DTrace_JavaPrintln(const char * msg) {
317
#if defined(DEBUG)
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*/
334
JNIEXPORT void JNICALL
335
Java_sun_awt_DebugSettings_setCTracingOn__Z(JNIEnv *env, jobject self, jboolean enabled) {
336
#if defined(DEBUG)
337
DTrace_EnableAll(enabled == JNI_TRUE);
338
#endif
339
}
340
341
/* Implementation of DebugSettings.setCTracingOn*/
342
JNIEXPORT void JNICALL
343
Java_sun_awt_DebugSettings_setCTracingOn__ZLjava_lang_String_2(
344
JNIEnv *env,
345
jobject self,
346
jboolean enabled,
347
jstring file ) {
348
#if defined(DEBUG)
349
const char * cfile;
350
cfile = JNU_GetStringPlatformChars(env, file, NULL);
351
if ( cfile == NULL ) {
352
return;
353
}
354
DTrace_EnableFile(cfile, enabled == JNI_TRUE);
355
JNU_ReleaseStringPlatformChars(env, file, cfile);
356
#endif
357
}
358
359
/* Implementation of DebugSettings.setCTracingOn*/
360
JNIEXPORT void JNICALL
361
Java_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(DEBUG)
368
const char * cfile;
369
cfile = JNU_GetStringPlatformChars(env, file, NULL);
370
if ( cfile == NULL ) {
371
return;
372
}
373
DTrace_EnableLine(cfile, line, enabled == JNI_TRUE);
374
JNU_ReleaseStringPlatformChars(env, file, cfile);
375
#endif
376
}
377
378