| 1 | /* |
| 2 | * Copyright (c) 2003, 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 | /* Error message and general message handling functions. */ |
| 27 | |
| 28 | /* NOTE: We assume that most strings passed around this library are |
| 29 | * UTF-8 (modified or standard) and not platform encoding. |
| 30 | * Before sending any strings to the "system" (e.g. OS system |
| 31 | * calls, or system input/output functions like fprintf) we need |
| 32 | * to make sure that the strings are transformed from UTF-8 to |
| 33 | * the platform encoding accepted by the system. |
| 34 | * UTF-8 and most encodings have simple ASCII or ISO-Latin |
| 35 | * characters as a subset, so in most cases the strings really |
| 36 | * don't need to be converted, but we don't know that easily. |
| 37 | * Parts of messages can be non-ASCII in some cases, so they may |
| 38 | * include classnames, methodnames, signatures, or other pieces |
| 39 | * that could contain non-ASCII characters, either from JNI or |
| 40 | * JVMTI (which both return modified UTF-8 strings). |
| 41 | * (It's possible that the platform encoding IS UTF-8, but we |
| 42 | * assume not, just to be safe). |
| 43 | * |
| 44 | */ |
| 45 | |
| 46 | #include <stdarg.h> |
| 47 | #include <errno.h> |
| 48 | |
| 49 | #include "util.h" |
| 50 | #include "utf_util.h" |
| 51 | #include "proc_md.h" |
| 52 | |
| 53 | /* Maximum number of bytes in a message, including the trailing zero. |
| 54 | * Do not print very long messages as they could be truncated. |
| 55 | * Use at most one pathname per message. NOTE, we use MAXPATHLEN*2 |
| 56 | * in case each character in the pathname takes 2 bytes. |
| 57 | */ |
| 58 | #define MAX_MESSAGE_BUF MAXPATHLEN*2+512 |
| 59 | |
| 60 | /* Print message in platform encoding (assume all input is UTF-8 safe) |
| 61 | * NOTE: This function is at the lowest level of the call tree. |
| 62 | * Do not use the ERROR* macros here. |
| 63 | */ |
| 64 | static void |
| 65 | vprint_message(FILE *fp, const char *prefix, const char *suffix, |
| 66 | const char *format, va_list ap) |
| 67 | { |
| 68 | jbyte utf8buf[MAX_MESSAGE_BUF]; |
| 69 | int len; |
| 70 | char pbuf[MAX_MESSAGE_BUF]; |
| 71 | |
| 72 | /* Fill buffer with single UTF-8 string */ |
| 73 | (void)vsnprintf((char*)utf8buf, sizeof(utf8buf), format, ap); |
| 74 | utf8buf[sizeof(utf8buf) - 1] = 0; |
| 75 | len = (int)strlen((char*)utf8buf); |
| 76 | |
| 77 | /* Convert to platform encoding (ignore errors, dangerous area) */ |
| 78 | (void)utf8ToPlatform(utf8buf, len, pbuf, (int)sizeof(pbuf)); |
| 79 | |
| 80 | (void)fprintf(fp, "%s%s%s" , prefix, pbuf, suffix); |
| 81 | } |
| 82 | |
| 83 | /* Print message in platform encoding (assume all input is UTF-8 safe) |
| 84 | * NOTE: This function is at the lowest level of the call tree. |
| 85 | * Do not use the ERROR* macros here. |
| 86 | */ |
| 87 | void |
| 88 | print_message(FILE *fp, const char *prefix, const char *suffix, |
| 89 | const char *format, ...) |
| 90 | { |
| 91 | va_list ap; |
| 92 | |
| 93 | va_start(ap, format); |
| 94 | vprint_message(fp, prefix, suffix, format, ap); |
| 95 | va_end(ap); |
| 96 | } |
| 97 | |
| 98 | /* Generate error message */ |
| 99 | void |
| 100 | error_message(const char *format, ...) |
| 101 | { |
| 102 | va_list ap; |
| 103 | |
| 104 | va_start(ap, format); |
| 105 | vprint_message(stderr, "ERROR: " , "\n" , format, ap); |
| 106 | va_end(ap); |
| 107 | if ( gdata->doerrorexit ) { |
| 108 | EXIT_ERROR(AGENT_ERROR_INTERNAL,"Requested errorexit=y exit()" ); |
| 109 | } |
| 110 | } |
| 111 | |
| 112 | /* Print plain message to stdout. */ |
| 113 | void |
| 114 | tty_message(const char *format, ...) |
| 115 | { |
| 116 | va_list ap; |
| 117 | |
| 118 | va_start(ap, format); |
| 119 | vprint_message(stdout, "" , "\n" , format, ap); |
| 120 | va_end(ap); |
| 121 | (void)fflush(stdout); |
| 122 | } |
| 123 | |
| 124 | /* Print assertion error message to stderr. */ |
| 125 | void |
| 126 | jdiAssertionFailed(char *fileName, int lineNumber, char *msg) |
| 127 | { |
| 128 | LOG_MISC(("ASSERT FAILED: %s : %d - %s\n" , fileName, lineNumber, msg)); |
| 129 | print_message(stderr, "ASSERT FAILED: " , "\n" , |
| 130 | "%s : %d - %s" , fileName, lineNumber, msg); |
| 131 | if (gdata && gdata->assertFatal) { |
| 132 | EXIT_ERROR(AGENT_ERROR_INTERNAL,"Assertion Failed" ); |
| 133 | } |
| 134 | } |
| 135 | |
| 136 | /* Macro for case on switch, returns string for name. */ |
| 137 | #define CASE_RETURN_TEXT(name) case name: return #name; |
| 138 | |
| 139 | /* Mapping of JVMTI errors to their name */ |
| 140 | const char * |
| 141 | jvmtiErrorText(jvmtiError error) |
| 142 | { |
| 143 | switch ((int)error) { |
| 144 | CASE_RETURN_TEXT(JVMTI_ERROR_NONE) |
| 145 | CASE_RETURN_TEXT(JVMTI_ERROR_INVALID_THREAD) |
| 146 | CASE_RETURN_TEXT(JVMTI_ERROR_INVALID_THREAD_GROUP) |
| 147 | CASE_RETURN_TEXT(JVMTI_ERROR_INVALID_PRIORITY) |
| 148 | CASE_RETURN_TEXT(JVMTI_ERROR_THREAD_NOT_SUSPENDED) |
| 149 | CASE_RETURN_TEXT(JVMTI_ERROR_THREAD_SUSPENDED) |
| 150 | CASE_RETURN_TEXT(JVMTI_ERROR_THREAD_NOT_ALIVE) |
| 151 | CASE_RETURN_TEXT(JVMTI_ERROR_INVALID_OBJECT) |
| 152 | CASE_RETURN_TEXT(JVMTI_ERROR_INVALID_CLASS) |
| 153 | CASE_RETURN_TEXT(JVMTI_ERROR_CLASS_NOT_PREPARED) |
| 154 | CASE_RETURN_TEXT(JVMTI_ERROR_INVALID_METHODID) |
| 155 | CASE_RETURN_TEXT(JVMTI_ERROR_INVALID_LOCATION) |
| 156 | CASE_RETURN_TEXT(JVMTI_ERROR_INVALID_FIELDID) |
| 157 | CASE_RETURN_TEXT(JVMTI_ERROR_NO_MORE_FRAMES) |
| 158 | CASE_RETURN_TEXT(JVMTI_ERROR_OPAQUE_FRAME) |
| 159 | CASE_RETURN_TEXT(JVMTI_ERROR_TYPE_MISMATCH) |
| 160 | CASE_RETURN_TEXT(JVMTI_ERROR_INVALID_SLOT) |
| 161 | CASE_RETURN_TEXT(JVMTI_ERROR_DUPLICATE) |
| 162 | CASE_RETURN_TEXT(JVMTI_ERROR_NOT_FOUND) |
| 163 | CASE_RETURN_TEXT(JVMTI_ERROR_INVALID_MONITOR) |
| 164 | CASE_RETURN_TEXT(JVMTI_ERROR_NOT_MONITOR_OWNER) |
| 165 | CASE_RETURN_TEXT(JVMTI_ERROR_INTERRUPT) |
| 166 | CASE_RETURN_TEXT(JVMTI_ERROR_INVALID_CLASS_FORMAT) |
| 167 | CASE_RETURN_TEXT(JVMTI_ERROR_CIRCULAR_CLASS_DEFINITION) |
| 168 | CASE_RETURN_TEXT(JVMTI_ERROR_FAILS_VERIFICATION) |
| 169 | CASE_RETURN_TEXT(JVMTI_ERROR_UNSUPPORTED_REDEFINITION_METHOD_ADDED) |
| 170 | CASE_RETURN_TEXT(JVMTI_ERROR_UNSUPPORTED_REDEFINITION_SCHEMA_CHANGED) |
| 171 | CASE_RETURN_TEXT(JVMTI_ERROR_INVALID_TYPESTATE) |
| 172 | CASE_RETURN_TEXT(JVMTI_ERROR_UNSUPPORTED_REDEFINITION_HIERARCHY_CHANGED) |
| 173 | CASE_RETURN_TEXT(JVMTI_ERROR_UNSUPPORTED_REDEFINITION_METHOD_DELETED) |
| 174 | CASE_RETURN_TEXT(JVMTI_ERROR_UNSUPPORTED_VERSION) |
| 175 | CASE_RETURN_TEXT(JVMTI_ERROR_NAMES_DONT_MATCH) |
| 176 | CASE_RETURN_TEXT(JVMTI_ERROR_UNSUPPORTED_REDEFINITION_CLASS_MODIFIERS_CHANGED) |
| 177 | CASE_RETURN_TEXT(JVMTI_ERROR_UNSUPPORTED_REDEFINITION_METHOD_MODIFIERS_CHANGED) |
| 178 | CASE_RETURN_TEXT(JVMTI_ERROR_NOT_AVAILABLE) |
| 179 | CASE_RETURN_TEXT(JVMTI_ERROR_MUST_POSSESS_CAPABILITY) |
| 180 | CASE_RETURN_TEXT(JVMTI_ERROR_NULL_POINTER) |
| 181 | CASE_RETURN_TEXT(JVMTI_ERROR_ABSENT_INFORMATION) |
| 182 | CASE_RETURN_TEXT(JVMTI_ERROR_INVALID_EVENT_TYPE) |
| 183 | CASE_RETURN_TEXT(JVMTI_ERROR_ILLEGAL_ARGUMENT) |
| 184 | CASE_RETURN_TEXT(JVMTI_ERROR_OUT_OF_MEMORY) |
| 185 | CASE_RETURN_TEXT(JVMTI_ERROR_ACCESS_DENIED) |
| 186 | CASE_RETURN_TEXT(JVMTI_ERROR_WRONG_PHASE) |
| 187 | CASE_RETURN_TEXT(JVMTI_ERROR_INTERNAL) |
| 188 | CASE_RETURN_TEXT(JVMTI_ERROR_UNATTACHED_THREAD) |
| 189 | CASE_RETURN_TEXT(JVMTI_ERROR_INVALID_ENVIRONMENT) |
| 190 | |
| 191 | CASE_RETURN_TEXT(AGENT_ERROR_INTERNAL) |
| 192 | CASE_RETURN_TEXT(AGENT_ERROR_VM_DEAD) |
| 193 | CASE_RETURN_TEXT(AGENT_ERROR_NO_JNI_ENV) |
| 194 | CASE_RETURN_TEXT(AGENT_ERROR_JNI_EXCEPTION) |
| 195 | CASE_RETURN_TEXT(AGENT_ERROR_JVMTI_INTERNAL) |
| 196 | CASE_RETURN_TEXT(AGENT_ERROR_JDWP_INTERNAL) |
| 197 | CASE_RETURN_TEXT(AGENT_ERROR_NOT_CURRENT_FRAME) |
| 198 | CASE_RETURN_TEXT(AGENT_ERROR_OUT_OF_MEMORY) |
| 199 | CASE_RETURN_TEXT(AGENT_ERROR_INVALID_TAG) |
| 200 | CASE_RETURN_TEXT(AGENT_ERROR_ALREADY_INVOKING) |
| 201 | CASE_RETURN_TEXT(AGENT_ERROR_INVALID_INDEX) |
| 202 | CASE_RETURN_TEXT(AGENT_ERROR_INVALID_LENGTH) |
| 203 | CASE_RETURN_TEXT(AGENT_ERROR_INVALID_STRING) |
| 204 | CASE_RETURN_TEXT(AGENT_ERROR_INVALID_CLASS_LOADER) |
| 205 | CASE_RETURN_TEXT(AGENT_ERROR_INVALID_ARRAY) |
| 206 | CASE_RETURN_TEXT(AGENT_ERROR_TRANSPORT_LOAD) |
| 207 | CASE_RETURN_TEXT(AGENT_ERROR_TRANSPORT_INIT) |
| 208 | CASE_RETURN_TEXT(AGENT_ERROR_NATIVE_METHOD) |
| 209 | CASE_RETURN_TEXT(AGENT_ERROR_INVALID_COUNT) |
| 210 | CASE_RETURN_TEXT(AGENT_ERROR_INVALID_FRAMEID) |
| 211 | CASE_RETURN_TEXT(AGENT_ERROR_NULL_POINTER) |
| 212 | CASE_RETURN_TEXT(AGENT_ERROR_ILLEGAL_ARGUMENT) |
| 213 | CASE_RETURN_TEXT(AGENT_ERROR_INVALID_THREAD) |
| 214 | CASE_RETURN_TEXT(AGENT_ERROR_INVALID_EVENT_TYPE) |
| 215 | CASE_RETURN_TEXT(AGENT_ERROR_INVALID_OBJECT) |
| 216 | CASE_RETURN_TEXT(AGENT_ERROR_NO_MORE_FRAMES) |
| 217 | |
| 218 | default: return "ERROR_unknown" ; |
| 219 | } |
| 220 | } |
| 221 | |
| 222 | const char * |
| 223 | eventText(int i) |
| 224 | { |
| 225 | switch ( i ) { |
| 226 | CASE_RETURN_TEXT(EI_SINGLE_STEP) |
| 227 | CASE_RETURN_TEXT(EI_BREAKPOINT) |
| 228 | CASE_RETURN_TEXT(EI_FRAME_POP) |
| 229 | CASE_RETURN_TEXT(EI_EXCEPTION) |
| 230 | CASE_RETURN_TEXT(EI_THREAD_START) |
| 231 | CASE_RETURN_TEXT(EI_THREAD_END) |
| 232 | CASE_RETURN_TEXT(EI_CLASS_PREPARE) |
| 233 | CASE_RETURN_TEXT(EI_CLASS_LOAD) |
| 234 | CASE_RETURN_TEXT(EI_FIELD_ACCESS) |
| 235 | CASE_RETURN_TEXT(EI_FIELD_MODIFICATION) |
| 236 | CASE_RETURN_TEXT(EI_EXCEPTION_CATCH) |
| 237 | CASE_RETURN_TEXT(EI_METHOD_ENTRY) |
| 238 | CASE_RETURN_TEXT(EI_METHOD_EXIT) |
| 239 | CASE_RETURN_TEXT(EI_VM_INIT) |
| 240 | CASE_RETURN_TEXT(EI_VM_DEATH) |
| 241 | CASE_RETURN_TEXT(EI_GC_FINISH) |
| 242 | default: return "EVENT_unknown" ; |
| 243 | } |
| 244 | } |
| 245 | |
| 246 | /* Macro for case on switch, returns string for name. */ |
| 247 | #define CASE_RETURN_JDWP_ERROR_TEXT(name) case JDWP_ERROR(name): return #name; |
| 248 | |
| 249 | const char * |
| 250 | jdwpErrorText(jdwpError serror) |
| 251 | { |
| 252 | switch ( serror ) { |
| 253 | CASE_RETURN_JDWP_ERROR_TEXT(NONE) |
| 254 | CASE_RETURN_JDWP_ERROR_TEXT(INVALID_THREAD) |
| 255 | CASE_RETURN_JDWP_ERROR_TEXT(INVALID_THREAD_GROUP) |
| 256 | CASE_RETURN_JDWP_ERROR_TEXT(INVALID_PRIORITY) |
| 257 | CASE_RETURN_JDWP_ERROR_TEXT(THREAD_NOT_SUSPENDED) |
| 258 | CASE_RETURN_JDWP_ERROR_TEXT(THREAD_SUSPENDED) |
| 259 | CASE_RETURN_JDWP_ERROR_TEXT(INVALID_OBJECT) |
| 260 | CASE_RETURN_JDWP_ERROR_TEXT(INVALID_CLASS) |
| 261 | CASE_RETURN_JDWP_ERROR_TEXT(CLASS_NOT_PREPARED) |
| 262 | CASE_RETURN_JDWP_ERROR_TEXT(INVALID_METHODID) |
| 263 | CASE_RETURN_JDWP_ERROR_TEXT(INVALID_LOCATION) |
| 264 | CASE_RETURN_JDWP_ERROR_TEXT(INVALID_FIELDID) |
| 265 | CASE_RETURN_JDWP_ERROR_TEXT(INVALID_FRAMEID) |
| 266 | CASE_RETURN_JDWP_ERROR_TEXT(NO_MORE_FRAMES) |
| 267 | CASE_RETURN_JDWP_ERROR_TEXT(OPAQUE_FRAME) |
| 268 | CASE_RETURN_JDWP_ERROR_TEXT(NOT_CURRENT_FRAME) |
| 269 | CASE_RETURN_JDWP_ERROR_TEXT(TYPE_MISMATCH) |
| 270 | CASE_RETURN_JDWP_ERROR_TEXT(INVALID_SLOT) |
| 271 | CASE_RETURN_JDWP_ERROR_TEXT(DUPLICATE) |
| 272 | CASE_RETURN_JDWP_ERROR_TEXT(NOT_FOUND) |
| 273 | CASE_RETURN_JDWP_ERROR_TEXT(INVALID_MONITOR) |
| 274 | CASE_RETURN_JDWP_ERROR_TEXT(NOT_MONITOR_OWNER) |
| 275 | CASE_RETURN_JDWP_ERROR_TEXT(INTERRUPT) |
| 276 | CASE_RETURN_JDWP_ERROR_TEXT(INVALID_CLASS_FORMAT) |
| 277 | CASE_RETURN_JDWP_ERROR_TEXT(CIRCULAR_CLASS_DEFINITION) |
| 278 | CASE_RETURN_JDWP_ERROR_TEXT(FAILS_VERIFICATION) |
| 279 | CASE_RETURN_JDWP_ERROR_TEXT(ADD_METHOD_NOT_IMPLEMENTED) |
| 280 | CASE_RETURN_JDWP_ERROR_TEXT(SCHEMA_CHANGE_NOT_IMPLEMENTED) |
| 281 | CASE_RETURN_JDWP_ERROR_TEXT(INVALID_TYPESTATE) |
| 282 | CASE_RETURN_JDWP_ERROR_TEXT(HIERARCHY_CHANGE_NOT_IMPLEMENTED) |
| 283 | CASE_RETURN_JDWP_ERROR_TEXT(DELETE_METHOD_NOT_IMPLEMENTED) |
| 284 | CASE_RETURN_JDWP_ERROR_TEXT(UNSUPPORTED_VERSION) |
| 285 | CASE_RETURN_JDWP_ERROR_TEXT(NAMES_DONT_MATCH) |
| 286 | CASE_RETURN_JDWP_ERROR_TEXT(CLASS_MODIFIERS_CHANGE_NOT_IMPLEMENTED) |
| 287 | CASE_RETURN_JDWP_ERROR_TEXT(METHOD_MODIFIERS_CHANGE_NOT_IMPLEMENTED) |
| 288 | CASE_RETURN_JDWP_ERROR_TEXT(CLASS_ATTRIBUTE_CHANGE_NOT_IMPLEMENTED) |
| 289 | CASE_RETURN_JDWP_ERROR_TEXT(NOT_IMPLEMENTED) |
| 290 | CASE_RETURN_JDWP_ERROR_TEXT(NULL_POINTER) |
| 291 | CASE_RETURN_JDWP_ERROR_TEXT(ABSENT_INFORMATION) |
| 292 | CASE_RETURN_JDWP_ERROR_TEXT(INVALID_EVENT_TYPE) |
| 293 | CASE_RETURN_JDWP_ERROR_TEXT(ILLEGAL_ARGUMENT) |
| 294 | CASE_RETURN_JDWP_ERROR_TEXT(OUT_OF_MEMORY) |
| 295 | CASE_RETURN_JDWP_ERROR_TEXT(ACCESS_DENIED) |
| 296 | CASE_RETURN_JDWP_ERROR_TEXT(VM_DEAD) |
| 297 | CASE_RETURN_JDWP_ERROR_TEXT(INTERNAL) |
| 298 | CASE_RETURN_JDWP_ERROR_TEXT(UNATTACHED_THREAD) |
| 299 | CASE_RETURN_JDWP_ERROR_TEXT(INVALID_TAG) |
| 300 | CASE_RETURN_JDWP_ERROR_TEXT(ALREADY_INVOKING) |
| 301 | CASE_RETURN_JDWP_ERROR_TEXT(INVALID_INDEX) |
| 302 | CASE_RETURN_JDWP_ERROR_TEXT(INVALID_LENGTH) |
| 303 | CASE_RETURN_JDWP_ERROR_TEXT(INVALID_STRING) |
| 304 | CASE_RETURN_JDWP_ERROR_TEXT(INVALID_CLASS_LOADER) |
| 305 | CASE_RETURN_JDWP_ERROR_TEXT(INVALID_ARRAY) |
| 306 | CASE_RETURN_JDWP_ERROR_TEXT(TRANSPORT_LOAD) |
| 307 | CASE_RETURN_JDWP_ERROR_TEXT(TRANSPORT_INIT) |
| 308 | CASE_RETURN_JDWP_ERROR_TEXT(NATIVE_METHOD) |
| 309 | CASE_RETURN_JDWP_ERROR_TEXT(INVALID_COUNT) |
| 310 | default: return "JDWP_ERROR_unknown" ; |
| 311 | } |
| 312 | } |
| 313 | |
| 314 | static int p = 1; |
| 315 | |
| 316 | void |
| 317 | do_pause(void) |
| 318 | { |
| 319 | THREAD_T tid = GET_THREAD_ID(); |
| 320 | PID_T pid = GETPID(); |
| 321 | int timeleft = 600; /* 10 minutes max */ |
| 322 | int interval = 10; /* 10 second message check */ |
| 323 | |
| 324 | /*LINTED*/ |
| 325 | tty_message("DEBUGGING: JDWP pause for PID %d, THREAD %d (0x%x)" , |
| 326 | /*LINTED*/ |
| 327 | (int)(intptr_t)pid, (int)(intptr_t)tid, (int)(intptr_t)tid); |
| 328 | while ( p && timeleft > 0 ) { |
| 329 | (void)sleep(interval); /* 'assign p = 0;' to get out of loop */ |
| 330 | timeleft -= interval; |
| 331 | } |
| 332 | if ( timeleft <= 0 ) { |
| 333 | tty_message("DEBUGGING: JDWP pause got tired of waiting and gave up." ); |
| 334 | } |
| 335 | } |
| 336 | |