char * inStream_readString(PacketInputStream *stream) { int length; char *string; length = inStream_readInt(stream); string = jvmtiAllocate(length + 1); if (string != NULL) { int new_length; (void)readBytes(stream, string, length); string[length] = '\0'; /* This is Standard UTF-8, convert to Modified UTF-8 if necessary */ new_length = (gdata->npt->utf8sToUtf8mLength) (gdata->npt->utf, (jbyte*)string, length); if ( new_length != length ) { char *new_string; new_string = jvmtiAllocate(new_length+1); (gdata->npt->utf8sToUtf8m) (gdata->npt->utf, (jbyte*)string, length, (jbyte*)new_string, new_length); jvmtiDeallocate(string); return new_string; } } return string; }
static RefNode * createNode(JNIEnv *env, jobject ref) { RefNode *node; jobject weakRef; weakRef = JNI_FUNC_PTR(env,NewWeakGlobalRef)(env, ref); if (weakRef == NULL) { return NULL; } /* * TO DO: Consider fewer allocations of bigger chunks if * performance is a problem here. */ node = jvmtiAllocate(sizeof(*node)); if (node == NULL) { JNI_FUNC_PTR(env,DeleteWeakGlobalRef)(env, weakRef); return NULL; } node->ref = weakRef; node->isStrong = JNI_FALSE; node->count = 1; node->seqNum = newSeqNum(); return node; }
/* * Print the last transport error */ static void printLastError(jdwpTransportEnv *t, jdwpTransportError err) { char *msg; jbyte *utf8msg; jdwpTransportError rv; msg = NULL; utf8msg = NULL; rv = (*t)->GetLastError(t, &msg); /* This is a platform encoded string */ if ( msg != NULL ) { int len; int maxlen; /* Convert this string to UTF8 */ len = (int)strlen(msg); maxlen = len+len/2+2; /* Should allow for plenty of room */ utf8msg = (jbyte*)jvmtiAllocate(maxlen+1); (void)(gdata->npt->utf8FromPlatform)(gdata->npt->utf, msg, len, utf8msg, maxlen); utf8msg[maxlen] = 0; } if (rv == JDWPTRANSPORT_ERROR_NONE) { ERROR_MESSAGE(("transport error %d: %s",err, utf8msg)); } else if ( msg!=NULL ) { ERROR_MESSAGE(("transport error %d: %s",err, utf8msg)); } else { ERROR_MESSAGE(("transport error %d: %s",err, "UNKNOWN")); } jvmtiDeallocate(msg); jvmtiDeallocate(utf8msg); }
static void enqueue(jdwpPacket *packet) { struct PacketList *pL; struct PacketList *walker; pL = jvmtiAllocate((jint)sizeof(struct PacketList)); if (pL == NULL) { EXIT_ERROR(AGENT_ERROR_OUT_OF_MEMORY,"packet list"); } pL->packet = *packet; pL->next = NULL; debugMonitorEnter(cmdQueueLock); if (cmdQueue == NULL) { cmdQueue = pL; debugMonitorNotify(cmdQueueLock); } else { walker = (struct PacketList *)cmdQueue; while (walker->next != NULL) walker = walker->next; walker->next = pL; } debugMonitorExit(cmdQueueLock); }
jdwpError outStream_writeString(PacketOutputStream *stream, char *string) { jdwpError error; jint length; /* Options utf8=y/n controls if we want Standard UTF-8 or Modified */ if ( gdata->modifiedUtf8 ) { length = (int)strlen(string); (void)outStream_writeInt(stream, length); error = writeBytes(stream, (jbyte *)string, length); } else { jint new_length; length = (int)strlen(string); new_length = (gdata->npt->utf8mToUtf8sLength) (gdata->npt->utf, (jbyte*)string, length); if ( new_length == length ) { (void)outStream_writeInt(stream, length); error = writeBytes(stream, (jbyte *)string, length); } else { char *new_string; new_string = jvmtiAllocate(new_length+1); (gdata->npt->utf8mToUtf8s) (gdata->npt->utf, (jbyte*)string, length, (jbyte*)new_string, new_length); (void)outStream_writeInt(stream, new_length); error = writeBytes(stream, (jbyte *)new_string, new_length); jvmtiDeallocate(new_string); } } return error; }
/** * Allocate a HandlerNode. * We do it because eventHandler doesn't know how big to make it. */ HandlerNode * eventFilterRestricted_alloc(jint filterCount) { /*LINTED*/ size_t size = offsetof(EventFilterPrivate_HandlerNode, ef) + offsetof(EventFilters, filters) + (filterCount * (int)sizeof(Filter)); HandlerNode *node = jvmtiAllocate((jint)size); if (node != NULL) { int i; Filter *filter; (void)memset(node, 0, size); FILTER_COUNT(node) = filterCount; /* Initialize all modifiers */ for (i = 0, filter = FILTERS_ARRAY(node); i < filterCount; i++, filter++) { filter->modifier = JDWP_REQUEST_NONE; } } return node; }
void * bagAdd(struct bag *theBag) { int allocated = theBag->allocated; int itemSize = theBag->itemSize; void *items = theBag->items; void *ret; /* if there are no unused slots reallocate */ if (theBag->used >= allocated) { void *new_items; allocated *= 2; new_items = jvmtiAllocate(allocated * itemSize); if (new_items == NULL) { return NULL; } (void)memcpy(new_items, items, (theBag->used) * itemSize); jvmtiDeallocate(items); items = new_items; theBag->allocated = allocated; theBag->items = items; } ret = ((char *)items) + (itemSize * (theBag->used)++); (void)memset(ret, 0, itemSize); return ret; }
struct bag * bagCreateBag(int itemSize, int initialAllocation) { struct bag *theBag = (struct bag *)jvmtiAllocate(sizeof(struct bag)); if (theBag == NULL) { return NULL; } itemSize = (itemSize + 7) & ~7; /* fit 8 byte boundary */ theBag->items = jvmtiAllocate(initialAllocation * itemSize); if (theBag->items == NULL) { jvmtiDeallocate(theBag); return NULL; } theBag->used = 0; theBag->allocated = initialAllocation; theBag->itemSize = itemSize; return theBag; }
/* Initialize the hash table stored in gdata area */ static void initializeObjectsByID(int size) { /* Size should always be a power of 2 */ if ( size > HASH_MAX_SIZE ) size = HASH_MAX_SIZE; gdata->objectsByIDsize = size; gdata->objectsByIDcount = 0; gdata->objectsByID = (RefNode**)jvmtiAllocate((int)sizeof(RefNode*)*size); (void)memset(gdata->objectsByID, 0, (int)sizeof(RefNode*)*size); }
static jdwpError launch(char *command, char *name, char *address) { jint rc; char *buf; char *commandLine; int len; /* Construct complete command line (all in UTF-8) */ commandLine = jvmtiAllocate((int)strlen(command) + (int)strlen(name) + (int)strlen(address) + 3); if (commandLine == NULL) { return JDWP_ERROR(OUT_OF_MEMORY); } (void)strcpy(commandLine, command); (void)strcat(commandLine, " "); (void)strcat(commandLine, name); (void)strcat(commandLine, " "); (void)strcat(commandLine, address); /* Convert commandLine from UTF-8 to platform encoding */ len = (int)strlen(commandLine); buf = jvmtiAllocate(len*3+3); (void)(gdata->npt->utf8ToPlatform)(gdata->npt->utf, (jbyte*)commandLine, len, buf, len*3+3); /* Exec commandLine */ rc = dbgsysExec(buf); /* Free up buffers */ jvmtiDeallocate(buf); jvmtiDeallocate(commandLine); /* And non-zero exit status means we had an error */ if (rc != SYS_OK) { return JDWP_ERROR(TRANSPORT_INIT); } return JDWP_ERROR(NONE); }
char * inStream_readString(PacketInputStream *stream) { int length; char *string; length = inStream_readInt(stream); string = jvmtiAllocate(length + 1); if (string != NULL) { (void)readBytes(stream, string, length); string[length] = '\0'; } return string; }
static jdwpError writeBytes(PacketOutputStream *stream, void *source, int size) { jbyte *bytes = (jbyte *)source; if (stream->error) { return stream->error; } while (size > 0) { jint count; if (stream->left == 0) { jint segSize = SMALLEST(2 * stream->segment->length, MAX_SEGMENT_SIZE); jbyte *newSeg = jvmtiAllocate(segSize); struct PacketData *newHeader = jvmtiAllocate(sizeof(*newHeader)); if ((newSeg == NULL) || (newHeader == NULL)) { jvmtiDeallocate(newSeg); jvmtiDeallocate(newHeader); stream->error = JDWP_ERROR(OUT_OF_MEMORY); return stream->error; } newHeader->length = 0; newHeader->data = newSeg; newHeader->next = NULL; stream->segment->next = newHeader; stream->segment = newHeader; stream->current = newHeader->data; stream->left = segSize; } count = SMALLEST(size, stream->left); (void)memcpy(stream->current, bytes, count); stream->current += count; stream->left -= count; stream->segment->length += count; size -= count; bytes += count; } return JDWP_ERROR(NONE); }
/* * This, currently, cannot go through the normal event handling code * because the JVMTI event does not contain a thread. */ void eventHelper_reportVMInit(JNIEnv *env, jbyte sessionID, jthread thread, jbyte suspendPolicy) { HelperCommand *command = jvmtiAllocate(sizeof(*command)); if (command == NULL) { EXIT_ERROR(AGENT_ERROR_OUT_OF_MEMORY,"HelperCommmand"); } (void)memset(command, 0, sizeof(*command)); command->commandKind = COMMAND_REPORT_VM_INIT; command->sessionID = sessionID; saveGlobalRef(env, thread, &(command->u.reportVMInit.thread)); command->u.reportVMInit.suspendPolicy = suspendPolicy; enqueueCommand(command, JNI_TRUE, JNI_FALSE); }
void eventHelper_reportInvokeDone(jbyte sessionID, jthread thread) { JNIEnv *env = getEnv(); HelperCommand *command = jvmtiAllocate(sizeof(*command)); if (command == NULL) { EXIT_ERROR(AGENT_ERROR_OUT_OF_MEMORY,"HelperCommand"); } (void)memset(command, 0, sizeof(*command)); command->commandKind = COMMAND_REPORT_INVOKE_DONE; command->sessionID = sessionID; saveGlobalRef(env, thread, &(command->u.reportInvokeDone.thread)); enqueueCommand(command, JNI_TRUE, JNI_FALSE); }
static jint outStream_send(PacketOutputStream *stream) { jint rc; jint len = 0; PacketData *segment; jbyte *data, *posP; /* * If there's only 1 segment then we just send the * packet. */ if (stream->firstSegment.next == NULL) { stream->packet.type.cmd.len = 11 + stream->firstSegment.length; stream->packet.type.cmd.data = stream->firstSegment.data; rc = transport_sendPacket(&stream->packet); return rc; } /* * Multiple segments */ len = 0; segment = (PacketData *)&(stream->firstSegment); do { len += segment->length; segment = segment->next; } while (segment != NULL); data = jvmtiAllocate(len); if (data == NULL) { return JDWP_ERROR(OUT_OF_MEMORY); } posP = data; segment = (PacketData *)&(stream->firstSegment); while (segment != NULL) { (void)memcpy(posP, segment->data, segment->length); posP += segment->length; segment = segment->next; } stream->packet.type.cmd.len = 11 + len; stream->packet.type.cmd.data = data; rc = transport_sendPacket(&stream->packet); stream->packet.type.cmd.data = NULL; jvmtiDeallocate(data); return rc; }
void eventHelper_suspendThread(jbyte sessionID, jthread thread) { JNIEnv *env = getEnv(); HelperCommand *command = jvmtiAllocate(sizeof(*command)); if (command == NULL) { EXIT_ERROR(AGENT_ERROR_OUT_OF_MEMORY,"HelperCommmand"); } (void)memset(command, 0, sizeof(*command)); command->commandKind = COMMAND_SUSPEND_THREAD; command->sessionID = sessionID; saveGlobalRef(env, thread, &(command->u.suspendThread.thread)); enqueueCommand(command, JNI_TRUE, JNI_FALSE); }
static void * newComponents(PacketOutputStream *out, jint length, size_t nbytes) { void *ptr = NULL; if ( length > 0 ) { ptr = jvmtiAllocate(length*((jint)nbytes)); if ( ptr == NULL ) { outStream_setError(out, JDWP_ERROR(OUT_OF_MEMORY)); } else { (void)memset(ptr, 0, length*nbytes); } } return ptr; }
jbyte eventHelper_reportEvents(jbyte sessionID, struct bag *eventBag) { int size = bagSize(eventBag); jbyte suspendPolicy = JDWP_SUSPEND_POLICY(NONE); jboolean reportingVMDeath = JNI_FALSE; jboolean wait; int command_size; HelperCommand *command; ReportEventCompositeCommand *recc; struct singleTracker tracker; if (size == 0) { return suspendPolicy; } (void)bagEnumerateOver(eventBag, enumForCombinedSuspendPolicy, &suspendPolicy); (void)bagEnumerateOver(eventBag, enumForVMDeath, &reportingVMDeath); /*LINTED*/ command_size = (int)(sizeof(HelperCommand) + sizeof(CommandSingle)*(size-1)); command = jvmtiAllocate(command_size); (void)memset(command, 0, command_size); command->commandKind = COMMAND_REPORT_EVENT_COMPOSITE; command->sessionID = sessionID; recc = &command->u.reportEventComposite; recc->suspendPolicy = suspendPolicy; recc->eventCount = size; tracker.recc = recc; tracker.index = 0; (void)bagEnumerateOver(eventBag, enumForCopyingSingles, &tracker); /* * We must wait if this thread (the event thread) is to be * suspended or if the VM is about to die. (Waiting in the latter * case ensures that we get the event out before the process dies.) */ wait = (jboolean)((suspendPolicy != JDWP_SUSPEND_POLICY(NONE)) || reportingVMDeath); enqueueCommand(command, wait, reportingVMDeath); return suspendPolicy; }
void debugDispatch_initialize(void) { /* * Create the level-one (CommandSet) dispatch table. * Zero the table so that unknown CommandSets do not * cause random errors. */ l1Array = jvmtiAllocate((JDWP_HIGHEST_COMMAND_SET+1) * sizeof(void *)); if (l1Array == NULL) { EXIT_ERROR(AGENT_ERROR_OUT_OF_MEMORY,"command set array"); } (void)memset(l1Array, 0, (JDWP_HIGHEST_COMMAND_SET+1) * sizeof(void *)); /* * Create the level-two (Command) dispatch tables to the * corresponding slots in the CommandSet dispatch table.. */ l1Array[JDWP_COMMAND_SET(VirtualMachine)] = (void *)VirtualMachine_Cmds; l1Array[JDWP_COMMAND_SET(ReferenceType)] = (void *)ReferenceType_Cmds; l1Array[JDWP_COMMAND_SET(ClassType)] = (void *)ClassType_Cmds; l1Array[JDWP_COMMAND_SET(InterfaceType)] = (void *)InterfaceType_Cmds; l1Array[JDWP_COMMAND_SET(ArrayType)] = (void *)ArrayType_Cmds; l1Array[JDWP_COMMAND_SET(Field)] = (void *)Field_Cmds; l1Array[JDWP_COMMAND_SET(Method)] = (void *)Method_Cmds; l1Array[JDWP_COMMAND_SET(ObjectReference)] = (void *)ObjectReference_Cmds; l1Array[JDWP_COMMAND_SET(StringReference)] = (void *)StringReference_Cmds; l1Array[JDWP_COMMAND_SET(ThreadReference)] = (void *)ThreadReference_Cmds; l1Array[JDWP_COMMAND_SET(ThreadGroupReference)] = (void *)ThreadGroupReference_Cmds; l1Array[JDWP_COMMAND_SET(ClassLoaderReference)] = (void *)ClassLoaderReference_Cmds; l1Array[JDWP_COMMAND_SET(ArrayReference)] = (void *)ArrayReference_Cmds; l1Array[JDWP_COMMAND_SET(EventRequest)] = (void *)EventRequest_Cmds; l1Array[JDWP_COMMAND_SET(StackFrame)] = (void *)StackFrame_Cmds; l1Array[JDWP_COMMAND_SET(ClassObjectReference)] = (void *)ClassObjectReference_Cmds; l1Array[JDWP_COMMAND_SET(ModuleReference)] = (void *)ModuleReference_Cmds; }
/* Create a fresh RefNode structure, create a weak ref and tag the object */ static RefNode * createNode(JNIEnv *env, jobject ref) { RefNode *node; jobject weakRef; jvmtiError error; /* Could allocate RefNode's in blocks, not sure it would help much */ node = (RefNode*)jvmtiAllocate((int)sizeof(RefNode)); if (node == NULL) { return NULL; } /* Create weak reference to make sure we have a reference */ weakRef = JNI_FUNC_PTR(env,NewWeakGlobalRef)(env, ref); if (weakRef == NULL) { jvmtiDeallocate(node); return NULL; } /* Set tag on weakRef */ error = JVMTI_FUNC_PTR(gdata->jvmti, SetTag) (gdata->jvmti, weakRef, ptr_to_jlong(node)); if ( error != JVMTI_ERROR_NONE ) { JNI_FUNC_PTR(env,DeleteWeakGlobalRef)(env, weakRef); jvmtiDeallocate(node); return NULL; } /* Fill in RefNode */ node->ref = weakRef; node->isStrong = JNI_FALSE; node->count = 1; node->seqNum = newSeqNum(); /* Count RefNode's created */ gdata->objectsByIDcount++; return node; }
static char * add_to_options(char *options, char *new_options) { size_t originalLength; char *combinedOptions; /* * Allocate enough space for both strings and * comma in between. */ originalLength = strlen(options); combinedOptions = jvmtiAllocate((jint)originalLength + 1 + (jint)strlen(new_options) + 1); if (combinedOptions == NULL) { return NULL; } (void)strcpy(combinedOptions, options); (void)strcat(combinedOptions, ","); (void)strcat(combinedOptions, new_options); return combinedOptions; }
int dbgsysExec(char *cmdLine) { int i; int argc; pid_t pid_err = (pid_t)(-1); /* this is the error return value */ pid_t pid; char **argv = NULL; char *p; char *args; /* Skip leading whitespace */ cmdLine = skipWhitespace(cmdLine); /*LINTED*/ args = jvmtiAllocate((jint)strlen(cmdLine)+1); if (args == NULL) { return SYS_NOMEM; } (void)strcpy(args, cmdLine); p = args; argc = 0; while (*p != '\0') { p = skipNonWhitespace(p); argc++; if (*p == '\0') { break; } p = skipWhitespace(p); } /*LINTED*/ argv = jvmtiAllocate((argc + 1) * (jint)sizeof(char *)); if (argv == 0) { jvmtiDeallocate(args); return SYS_NOMEM; } for (i = 0, p = args; i < argc; i++) { argv[i] = p; p = skipNonWhitespace(p); *p++ = '\0'; p = skipWhitespace(p); } argv[i] = NULL; /* NULL terminate */ if ((pid = FORK()) == 0) { /* Child process */ int i; long max_fd; /* close everything */ max_fd = sysconf(_SC_OPEN_MAX); /*LINTED*/ for (i = 3; i < (int)max_fd; i++) { (void)close(i); } (void)execvp(argv[0], argv); exit(-1); } jvmtiDeallocate(args); jvmtiDeallocate(argv); if (pid == pid_err) { return SYS_ERR; } else { return SYS_OK; } }
static jboolean parseOptions(char *options) { TransportSpec *currentTransport = NULL; char *end; char *current; int length; char *str; char *errmsg; /* Set defaults */ gdata->assertOn = DEFAULT_ASSERT_ON; gdata->assertFatal = DEFAULT_ASSERT_FATAL; logfile = DEFAULT_LOGFILE; /* Options being NULL will end up being an error. */ if (options == NULL) { options = ""; } /* Check for "help" BEFORE we add any environmental settings */ if ((strcmp(options, "help")) == 0) { printUsage(); forceExit(0); /* Kill entire process, no core dump wanted */ } /* These buffers are never freed */ { char *envOptions; /* * Add environmentally specified options. */ envOptions = getenv("_JAVA_JDWP_OPTIONS"); if (envOptions != NULL) { options = add_to_options(options, envOptions); if ( options==NULL ) { EXIT_ERROR(AGENT_ERROR_OUT_OF_MEMORY,"options"); } } /* * Allocate a buffer for names derived from option strings. It should * never be longer than the original options string itself. * Also keep a copy of the options in gdata->options. */ length = (int)strlen(options); gdata->options = jvmtiAllocate(length + 1); if (gdata->options == NULL) { EXIT_ERROR(AGENT_ERROR_OUT_OF_MEMORY,"options"); } (void)strcpy(gdata->options, options); names = jvmtiAllocate(length + 1); if (names == NULL) { EXIT_ERROR(AGENT_ERROR_OUT_OF_MEMORY,"options"); } transports = bagCreateBag(sizeof(TransportSpec), 3); if (transports == NULL) { EXIT_ERROR(AGENT_ERROR_OUT_OF_MEMORY,"transports"); } } current = names; end = names + length; str = options; while (*str) { char buf[100]; /*LINTED*/ if (!get_tok(&str, buf, (int)sizeof(buf), '=')) { goto syntax_error; } if (strcmp(buf, "transport") == 0) { currentTransport = bagAdd(transports); /*LINTED*/ if (!get_tok(&str, current, (int)(end - current), ',')) { goto syntax_error; } currentTransport->name = current; current += strlen(current) + 1; } else if (strcmp(buf, "address") == 0) { if (currentTransport == NULL) { errmsg = "address specified without transport"; goto bad_option_with_errmsg; } /*LINTED*/ if (!get_tok(&str, current, (int)(end - current), ',')) { goto syntax_error; } currentTransport->address = current; current += strlen(current) + 1; } else if (strcmp(buf, "timeout") == 0) { if (currentTransport == NULL) { errmsg = "timeout specified without transport"; goto bad_option_with_errmsg; } /*LINTED*/ if (!get_tok(&str, current, (int)(end - current), ',')) { goto syntax_error; } currentTransport->timeout = atol(current); current += strlen(current) + 1; } else if (strcmp(buf, "launch") == 0) { /*LINTED*/ if (!get_tok(&str, current, (int)(end - current), ',')) { goto syntax_error; } launchOnInit = current; current += strlen(current) + 1; } else if (strcmp(buf, "onthrow") == 0) { /* Read class name and convert in place to a signature */ *current = 'L'; /*LINTED*/ if (!get_tok(&str, current + 1, (int)(end - current - 1), ',')) { goto syntax_error; } initOnException = current; while (*current != '\0') { if (*current == '.') { *current = '/'; } current++; } *current++ = ';'; *current++ = '\0'; } else if (strcmp(buf, "assert") == 0) { /*LINTED*/ if (!get_tok(&str, current, (int)(end - current), ',')) { goto syntax_error; } if (strcmp(current, "y") == 0) { gdata->assertOn = JNI_TRUE; gdata->assertFatal = JNI_FALSE; } else if (strcmp(current, "fatal") == 0) { gdata->assertOn = JNI_TRUE; gdata->assertFatal = JNI_TRUE; } else if (strcmp(current, "n") == 0) { gdata->assertOn = JNI_FALSE; gdata->assertFatal = JNI_FALSE; } else { goto syntax_error; } current += strlen(current) + 1; } else if (strcmp(buf, "pause") == 0) { if ( !get_boolean(&str, &dopause) ) { goto syntax_error; } if ( dopause ) { do_pause(); } } else if (strcmp(buf, "coredump") == 0) { if ( !get_boolean(&str, &docoredump) ) { goto syntax_error; } } else if (strcmp(buf, "errorexit") == 0) { if ( !get_boolean(&str, &(gdata->doerrorexit)) ) { goto syntax_error; } } else if (strcmp(buf, "exitpause") == 0) { errmsg = "The exitpause option removed, use -XX:OnError"; goto bad_option_with_errmsg; } else if (strcmp(buf, "precrash") == 0) { errmsg = "The precrash option removed, use -XX:OnError"; goto bad_option_with_errmsg; } else if (strcmp(buf, "logfile") == 0) { /*LINTED*/ if (!get_tok(&str, current, (int)(end - current), ',')) { goto syntax_error; } logfile = current; current += strlen(current) + 1; } else if (strcmp(buf, "logflags") == 0) { /*LINTED*/ if (!get_tok(&str, current, (int)(end - current), ',')) { goto syntax_error; } /*LINTED*/ logflags = (unsigned)strtol(current, NULL, 0); } else if (strcmp(buf, "debugflags") == 0) { /*LINTED*/ if (!get_tok(&str, current, (int)(end - current), ',')) { goto syntax_error; } /*LINTED*/ gdata->debugflags = (unsigned)strtol(current, NULL, 0); } else if ( strcmp(buf, "suspend")==0 ) { if ( !get_boolean(&str, &suspendOnInit) ) { goto syntax_error; } } else if ( strcmp(buf, "server")==0 ) { if ( !get_boolean(&str, &isServer) ) { goto syntax_error; } } else if ( strcmp(buf, "strict")==0 ) { /* Obsolete, but accept it */ if ( !get_boolean(&str, &isStrict) ) { goto syntax_error; } } else if ( strcmp(buf, "quiet")==0 ) { if ( !get_boolean(&str, &(gdata->quiet)) ) { goto syntax_error; } } else if ( strcmp(buf, "onuncaught")==0 ) { if ( !get_boolean(&str, &initOnUncaught) ) { goto syntax_error; } } else if ( strcmp(buf, "mutf8")==0 ) { if ( !get_boolean(&str, &(gdata->modifiedUtf8)) ) { goto syntax_error; } } else if ( strcmp(buf, "stdalloc")==0 ) { /* Obsolete, but accept it */ if ( !get_boolean(&str, &useStandardAlloc) ) { goto syntax_error; } } else { goto syntax_error; } } /* Setup logging now */ if ( logfile!=NULL ) { setup_logging(logfile, logflags); (void)atexit(&atexit_finish_logging); } if (bagSize(transports) == 0) { errmsg = "no transport specified"; goto bad_option_with_errmsg; } /* * TO DO: Remove when multiple transports are allowed. (replace with * check below. */ if (bagSize(transports) > 1) { errmsg = "multiple transports are not supported in this release"; goto bad_option_with_errmsg; } if (!isServer) { jboolean specified = bagEnumerateOver(transports, checkAddress, NULL); if (!specified) { /* message already printed */ goto bad_option_no_msg; } } /* * The user has selected to wait for an exception before init happens */ if ((initOnException != NULL) || (initOnUncaught)) { initOnStartup = JNI_FALSE; if (launchOnInit == NULL) { /* * These rely on the launch=/usr/bin/foo * suboption, so it is an error if user did not * provide one. */ errmsg = "Specify launch=<command line> when using onthrow or onuncaught suboption"; goto bad_option_with_errmsg; } } return JNI_TRUE; syntax_error: ERROR_MESSAGE(("JDWP option syntax error: %s=%s", AGENTLIB, options)); return JNI_FALSE; bad_option_with_errmsg: ERROR_MESSAGE(("JDWP %s: %s=%s", errmsg, AGENTLIB, options)); return JNI_FALSE; bad_option_no_msg: ERROR_MESSAGE(("JDWP %s: %s=%s", "invalid option", AGENTLIB, options)); return JNI_FALSE; }
jdwpError transport_startTransport(jboolean isServer, char *name, char *address, long timeout) { jvmtiStartFunction func; jdwpTransportEnv *trans; char threadName[MAXPATHLEN + 100]; jint err; jdwpError serror; /* * If the transport is already loaded then use it * Note: We're assuming here that we don't support multiple * transports - when we do then we need to handle the case * where the transport library only supports a single environment. * That probably means we have a bag a transport environments * to correspond to the transports bag. */ if (transport != NULL) { trans = transport; } else { serror = loadTransport(name, &trans); if (serror != JDWP_ERROR(NONE)) { return serror; } } if (isServer) { char *retAddress; char *launchCommand; TransportInfo *info; jvmtiError error; int len; char* prop_value; info = jvmtiAllocate(sizeof(*info)); if (info == NULL) { return JDWP_ERROR(OUT_OF_MEMORY); } info->name = jvmtiAllocate((int)strlen(name)+1); (void)strcpy(info->name, name); info->address = NULL; info->timeout = timeout; if (info->name == NULL) { serror = JDWP_ERROR(OUT_OF_MEMORY); goto handleError; } if (address != NULL) { info->address = jvmtiAllocate((int)strlen(address)+1); (void)strcpy(info->address, address); if (info->address == NULL) { serror = JDWP_ERROR(OUT_OF_MEMORY); goto handleError; } } info->transport = trans; err = (*trans)->StartListening(trans, address, &retAddress); if (err != JDWPTRANSPORT_ERROR_NONE) { printLastError(trans, err); serror = JDWP_ERROR(TRANSPORT_INIT); goto handleError; } /* * Record listener address in a system property */ len = (int)strlen(name) + (int)strlen(retAddress) + 2; /* ':' and '\0' */ prop_value = (char*)jvmtiAllocate(len); strcpy(prop_value, name); strcat(prop_value, ":"); strcat(prop_value, retAddress); setTransportProperty(getEnv(), prop_value); jvmtiDeallocate(prop_value); (void)strcpy(threadName, "JDWP Transport Listener: "); (void)strcat(threadName, name); func = &acceptThread; error = spawnNewThread(func, (void*)info, threadName); if (error != JVMTI_ERROR_NONE) { serror = map2jdwpError(error); goto handleError; } launchCommand = debugInit_launchOnInit(); if (launchCommand != NULL) { serror = launch(launchCommand, name, retAddress); if (serror != JDWP_ERROR(NONE)) { goto handleError; } } else { if ( ! gdata->quiet ) { TTY_MESSAGE(("Listening for transport %s at address: %s", name, retAddress)); } } return JDWP_ERROR(NONE); handleError: jvmtiDeallocate(info->name); jvmtiDeallocate(info->address); jvmtiDeallocate(info); } else { /* * Note that we don't attempt to do a launch here. Launching * is currently supported only in server mode. */ /* * If we're connecting to another process, there shouldn't be * any concurrent listens, so its ok if we block here in this * thread, waiting for the attach to finish. */ err = (*trans)->Attach(trans, address, timeout, 0); if (err != JDWPTRANSPORT_ERROR_NONE) { printLastError(trans, err); serror = JDWP_ERROR(TRANSPORT_INIT); return serror; } /* * Start the transport loop in a separate thread */ (void)strcpy(threadName, "JDWP Transport Listener: "); (void)strcat(threadName, name); func = &attachThread; err = spawnNewThread(func, (void*)trans, threadName); serror = map2jdwpError(err); } return serror; }