27
27
28
28
import java .io .PrintStream ;
29
29
import java .math .BigInteger ;
30
+ import java .time .Instant ;
31
+ import java .time .ZoneId ;
32
+ import java .time .format .DateTimeFormatter ;
30
33
import java .util .HexFormat ;
31
34
import java .util .regex .Pattern ;
32
35
import java .util .regex .Matcher ;
41
44
public class Debug {
42
45
43
46
private String prefix ;
47
+ private boolean printDateTime ;
48
+ private boolean printThreadDetails ;
44
49
45
50
private static String args ;
51
+ private static boolean threadInfoAll ;
52
+ private static boolean timeStampInfoAll ;
53
+ private static final String TIMESTAMP_OPTION = "+timestamp" ;
54
+ private static final String THREAD_OPTION = "+thread" ;
46
55
47
56
static {
48
57
args = GetPropertyAction .privilegedGetProperty ("java.security.debug" );
@@ -61,12 +70,21 @@ public class Debug {
61
70
args = marshal (args );
62
71
if (args .equals ("help" )) {
63
72
Help ();
73
+ } else if (args .contains ("all" )) {
74
+ // "all" option has special handling for decorator options
75
+ // If the thread or timestamp decorator option is detected
76
+ // with the "all" option, then it impacts decorator options
77
+ // for other categories
78
+ int beginIndex = args .lastIndexOf ("all" ) + "all" .length ();
79
+ int commaIndex = args .indexOf (',' , beginIndex );
80
+ if (commaIndex == -1 ) commaIndex = args .length ();
81
+ threadInfoAll = args .substring (beginIndex , commaIndex ).contains (THREAD_OPTION );
82
+ timeStampInfoAll = args .substring (beginIndex , commaIndex ).contains (TIMESTAMP_OPTION );
64
83
}
65
84
}
66
85
}
67
86
68
- public static void Help ()
69
- {
87
+ public static void Help () {
70
88
System .err .println ();
71
89
System .err .println ("all turn on all debugging" );
72
90
System .err .println ("access print all checkPermission results" );
@@ -95,6 +113,11 @@ public static void Help()
95
113
System .err .println ("ts timestamping" );
96
114
System .err .println ("x509 X.509 certificate debugging" );
97
115
System .err .println ();
116
+ System .err .println ("+timestamp can be appended to any of above options to print" );
117
+ System .err .println (" a timestamp for that debug option" );
118
+ System .err .println ("+thread can be appended to any of above options to print" );
119
+ System .err .println (" thread and caller information for that debug option" );
120
+ System .err .println ();
98
121
System .err .println ("The following can be used with access:" );
99
122
System .err .println ();
100
123
System .err .println ("stack include stack trace" );
@@ -139,32 +162,65 @@ public static void Help()
139
162
* option is set. Set the prefix to be the same as option.
140
163
*/
141
164
142
- public static Debug getInstance (String option )
143
- {
165
+ public static Debug getInstance (String option ) {
144
166
return getInstance (option , option );
145
167
}
146
168
147
169
/**
148
170
* Get a Debug object corresponding to whether or not the given
149
171
* option is set. Set the prefix to prefix.
150
172
*/
151
- public static Debug getInstance (String option , String prefix )
152
- {
173
+ public static Debug getInstance (String option , String prefix ) {
153
174
if (isOn (option )) {
154
175
Debug d = new Debug ();
155
176
d .prefix = prefix ;
177
+ d .configureExtras (option );
156
178
return d ;
157
179
} else {
158
180
return null ;
159
181
}
160
182
}
161
183
184
+ private static String formatCaller () {
185
+ return StackWalker .getInstance ().walk (s ->
186
+ s .dropWhile (f ->
187
+ f .getClassName ().startsWith ("sun.security.util.Debug" ))
188
+ .map (f -> f .getFileName () + ":" + f .getLineNumber ())
189
+ .findFirst ().orElse ("unknown caller" ));
190
+ }
191
+
192
+ // parse an option string to determine if extra details,
193
+ // like thread and timestamp, should be printed
194
+ private void configureExtras (String option ) {
195
+ // treat "all" as special case, only used for java.security.debug property
196
+ this .printDateTime = timeStampInfoAll ;
197
+ this .printThreadDetails = threadInfoAll ;
198
+
199
+ if (printDateTime && printThreadDetails ) {
200
+ // nothing left to configure
201
+ return ;
202
+ }
203
+
204
+ // args is converted to lower case for the most part via marshal method
205
+ int optionIndex = args .lastIndexOf (option );
206
+ if (optionIndex == -1 ) {
207
+ // option not in args list. Only here since "all" was present
208
+ // in debug property argument. "all" option already parsed
209
+ return ;
210
+ }
211
+ int beginIndex = optionIndex + option .length ();
212
+ int commaIndex = args .indexOf (',' , beginIndex );
213
+ if (commaIndex == -1 ) commaIndex = args .length ();
214
+ String subOpt = args .substring (beginIndex , commaIndex );
215
+ printDateTime = printDateTime || subOpt .contains (TIMESTAMP_OPTION );
216
+ printThreadDetails = printThreadDetails || subOpt .contains (THREAD_OPTION );
217
+ }
218
+
162
219
/**
163
220
* True if the system property "security.debug" contains the
164
221
* string "option".
165
222
*/
166
- public static boolean isOn (String option )
167
- {
223
+ public static boolean isOn (String option ) {
168
224
if (args == null )
169
225
return false ;
170
226
else {
@@ -187,37 +243,53 @@ public static boolean isVerbose() {
187
243
* created from the call to getInstance.
188
244
*/
189
245
190
- public void println (String message )
191
- {
192
- System .err .println (prefix + ": " +message );
246
+ public void println (String message ) {
247
+ System .err .println (prefix + extraInfo () + ": " + message );
193
248
}
194
249
195
250
/**
196
251
* print a message to stderr that is prefixed with the prefix
197
252
* created from the call to getInstance and obj.
198
253
*/
199
- public void println (Object obj , String message )
200
- {
201
- System .err .println (prefix + " [" + obj .getClass ().getSimpleName () +
254
+ public void println (Object obj , String message ) {
255
+ System .err .println (prefix + extraInfo () + " [" + obj .getClass ().getSimpleName () +
202
256
"@" + System .identityHashCode (obj ) + "]: " +message );
203
257
}
204
258
205
259
/**
206
260
* print a blank line to stderr that is prefixed with the prefix.
207
261
*/
208
262
209
- public void println ()
210
- {
211
- System .err .println (prefix + ":" );
263
+ public void println () {
264
+ System .err .println (prefix + extraInfo () + ":" );
212
265
}
213
266
214
267
/**
215
268
* print a message to stderr that is prefixed with the prefix.
216
269
*/
217
270
218
- public static void println (String prefix , String message )
219
- {
220
- System .err .println (prefix + ": " +message );
271
+ public void println (String prefix , String message ) {
272
+ System .err .println (prefix + extraInfo () + ": " + message );
273
+ }
274
+
275
+ /**
276
+ * If thread debug option enabled, include information containing
277
+ * hex value of threadId and the current thread name
278
+ * If timestamp debug option enabled, include timestamp string
279
+ * @return extra info if debug option enabled.
280
+ */
281
+ private String extraInfo () {
282
+ String retString = "" ;
283
+ if (printThreadDetails ) {
284
+ retString = "0x" + Long .toHexString (
285
+ Thread .currentThread ().threadId ()).toUpperCase (Locale .ROOT ) +
286
+ "|" + Thread .currentThread ().getName () + "|" + formatCaller ();
287
+ }
288
+ if (printDateTime ) {
289
+ retString += (retString .isEmpty () ? "" : "|" )
290
+ + FormatHolder .DATE_TIME_FORMATTER .format (Instant .now ());
291
+ }
292
+ return retString .isEmpty () ? "" : "[" + retString + "]" ;
221
293
}
222
294
223
295
/**
@@ -333,4 +405,11 @@ public static String toString(byte[] b) {
333
405
return HexFormat .ofDelimiter (":" ).formatHex (b );
334
406
}
335
407
408
+ // Holder class to break cyclic dependency seen during build
409
+ private static class FormatHolder {
410
+ private static final String PATTERN = "yyyy-MM-dd kk:mm:ss.SSS" ;
411
+ private static final DateTimeFormatter DATE_TIME_FORMATTER = DateTimeFormatter
412
+ .ofPattern (PATTERN , Locale .ENGLISH )
413
+ .withZone (ZoneId .systemDefault ());
414
+ }
336
415
}
1 commit comments
openjdk-notifier[bot] commentedon Jun 26, 2024
Review
Issues