/*
 * 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);
}
Exemple #2
0
void
bagDestroyBag(struct bag *theBag)
{
    if (theBag != NULL) {
        jvmtiDeallocate(theBag->items);
        jvmtiDeallocate(theBag);
    }
}
/**
 * Free up global refs held by the filter.
 * free things up at the JNI level if needed.
 */
static jvmtiError
clearFilters(HandlerNode *node)
{
    JNIEnv *env = getEnv();
    jint i;
    jvmtiError error = JVMTI_ERROR_NONE;
    Filter *filter = FILTERS_ARRAY(node);

    for (i = 0; i < FILTER_COUNT(node); ++i, ++filter) {
        switch (filter->modifier) {
            case JDWP_REQUEST_MODIFIER(ThreadOnly):
                if ( filter->u.ThreadOnly.thread != NULL ) {
                    tossGlobalRef(env, &(filter->u.ThreadOnly.thread));
                }
                break;
            case JDWP_REQUEST_MODIFIER(LocationOnly):
                tossGlobalRef(env, &(filter->u.LocationOnly.clazz));
                break;
            case JDWP_REQUEST_MODIFIER(FieldOnly):
                tossGlobalRef(env, &(filter->u.FieldOnly.clazz));
                break;
            case JDWP_REQUEST_MODIFIER(ExceptionOnly):
                if ( filter->u.ExceptionOnly.exception != NULL ) {
                    tossGlobalRef(env, &(filter->u.ExceptionOnly.exception));
                }
                break;
            case JDWP_REQUEST_MODIFIER(InstanceOnly):
                if ( filter->u.InstanceOnly.instance != NULL ) {
                    tossGlobalRef(env, &(filter->u.InstanceOnly.instance));
                }
                break;
            case JDWP_REQUEST_MODIFIER(ClassOnly):
                tossGlobalRef(env, &(filter->u.ClassOnly.clazz));
                break;
            case JDWP_REQUEST_MODIFIER(ClassMatch):
                jvmtiDeallocate(filter->u.ClassMatch.classPattern);
                break;
            case JDWP_REQUEST_MODIFIER(ClassExclude):
                jvmtiDeallocate(filter->u.ClassExclude.classPattern);
                break;
            case JDWP_REQUEST_MODIFIER(Step): {
                jthread thread = filter->u.Step.thread;
                error = stepControl_endStep(thread);
                if (error == JVMTI_ERROR_NONE) {
                    tossGlobalRef(env, &(filter->u.Step.thread));
                }
                break;
            }
        }
    }
    if (error == JVMTI_ERROR_NONE) {
        FILTER_COUNT(node) = 0; /* blast so we don't clear again */
    }

    return error;
}
Exemple #4
0
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;
}
Exemple #5
0
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;
}
Exemple #6
0
/* Reset the commonRefs usage */
void 
commonRef_reset(JNIEnv *env)
{
    debugMonitorEnter(gdata->refLock); {
        int i;

        for (i = 0; i < gdata->objectsByIDsize; i++) {
            RefNode *node;
            
            node = gdata->objectsByID[i];
            while (node != NULL) {
                RefNode *next;
                
                next = node->next;
                deleteNode(env, node);
                node = next;
            }
            gdata->objectsByID[i] = NULL;
        }
        
        /* Toss entire hash table and re-create a new one */
        jvmtiDeallocate(gdata->objectsByID);
        gdata->objectsByID      = NULL;
        gdata->nextSeqNum       = 1; /* 0 used for error indication */
        initializeObjectsByID(HASH_INIT_SIZE);

    } debugMonitorExit(gdata->refLock);
}
Exemple #7
0
static void
freeCommand(HelperCommand *command)
{
    if ( command == NULL )
        return;
    jvmtiDeallocate(command);
}
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;
}
Exemple #9
0
void 
outStream_destroy(PacketOutputStream *stream)
{
    struct PacketData *next;

    if (stream->error || !stream->sent) {
        (void)bagEnumerateOver(stream->ids, releaseID, NULL);
    }

    next = stream->firstSegment.next;
    while (next != NULL) {
        struct PacketData *p = next;
        next = p->next;
        jvmtiDeallocate(p->data);
        jvmtiDeallocate(p);
    }
    bagDestroyBag(stream->ids);
}
Exemple #10
0
static void 
handleUnloadCommandSingle(JNIEnv* env, PacketOutputStream *out, 
                           UnloadCommandSingle *command) 
{
    (void)outStream_writeByte(out, JDWP_EVENT(CLASS_UNLOAD));
    (void)outStream_writeInt(out, command->id);
    (void)outStream_writeString(out, command->classSignature);
    jvmtiDeallocate(command->classSignature);
    command->classSignature = NULL;
}
Exemple #11
0
void 
inStream_destroy(PacketInputStream *stream)
{
    if (stream->packet.type.cmd.data != NULL) {
    jvmtiDeallocate(stream->packet.type.cmd.data);
    } 

    (void)bagEnumerateOver(stream->refs, deleteRef, (void *)getEnv());
    bagDestroyBag(stream->refs);
}
Exemple #12
0
static void 
deleteNode(JNIEnv *env, RefNode *node)
{
    LOG_MISC(("Freeing %d (%x)\n", (int)node->seqNum, node->ref));
    if (node->isStrong) {
        JNI_FUNC_PTR(env,DeleteGlobalRef)(env, node->ref);
    } else {
        JNI_FUNC_PTR(env,DeleteWeakGlobalRef)(env, node->ref);
    }
    jvmtiDeallocate(node);
}
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);
}
Exemple #14
0
/* 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;
}
Exemple #15
0
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);
}
Exemple #16
0
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;
}
Exemple #17
0
/* Allocate and add RefNode to hash table */
static RefNode *
newCommonRef(JNIEnv *env, jobject ref) 
{
    RefNode *node;

    /* Allocate the node and set it up */
    node = createNode(env, ref);
    if ( node == NULL ) {
        return NULL;
    }

    /* See if hash table needs expansion */
    if ( gdata->objectsByIDcount > gdata->objectsByIDsize*HASH_EXPAND_SCALE &&
         gdata->objectsByIDsize < HASH_MAX_SIZE ) {
        RefNode **old;
        int       oldsize;
        int       newsize;
        int       i;
        
        /* Save old information */
        old     = gdata->objectsByID;
        oldsize = gdata->objectsByIDsize;
        /* Allocate new hash table */
        gdata->objectsByID = NULL;
        newsize = oldsize*HASH_EXPAND_SCALE;
        if ( newsize > HASH_MAX_SIZE ) newsize = HASH_MAX_SIZE;
        initializeObjectsByID(newsize);
        /* Walk over old one and hash in all the RefNodes */
        for ( i = 0 ; i < oldsize ; i++ ) {
            RefNode *onode;
            
            onode = old[i];
            while (onode != NULL) {
                RefNode *next;

                next = onode->next;
                hashIn(onode);
                onode = next;
            }
        }
        jvmtiDeallocate(old);
    }

    /* Add to id hashtable */
    hashIn(node);
    return node;
}
Exemple #18
0
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;
}
Exemple #19
0
/* Delete a RefNode allocation, delete weak/global ref and clear tag */
static void 
deleteNode(JNIEnv *env, RefNode *node)
{
    LOG_MISC(("Freeing %d (%x)\n", (int)node->seqNum, node->ref));

    if ( node->ref != NULL ) {
        /* Clear tag */
        (void)JVMTI_FUNC_PTR(gdata->jvmti,SetTag)
                            (gdata->jvmti, node->ref, NULL_OBJECT_ID);
        if (node->isStrong) {
            JNI_FUNC_PTR(env,DeleteGlobalRef)(env, node->ref);
        } else {
            JNI_FUNC_PTR(env,DeleteWeakGlobalRef)(env, node->ref);
        }
    }
    gdata->objectsByIDcount--;
    jvmtiDeallocate(node);
}
Exemple #20
0
static void 
writeClassEvent(JNIEnv *env, PacketOutputStream *out, EventInfo *evinfo)
{
    jbyte classTag;
    jint status;
    char *signature = NULL;
    jvmtiError error;

    classTag = referenceTypeTag(evinfo->clazz);
    error = classSignature(evinfo->clazz, &signature, NULL);
    if (error != JVMTI_ERROR_NONE) {
        EXIT_ERROR(error,"signature");
    }
    status = classStatus(evinfo->clazz);

    (void)outStream_writeObjectRef(env, out, evinfo->thread);
    (void)outStream_writeByte(out, classTag);
    (void)outStream_writeObjectRef(env, out, evinfo->clazz);
    (void)outStream_writeString(out, signature);
    (void)outStream_writeInt(out, map2jdwpClassStatus(status));
    jvmtiDeallocate(signature);
}
Exemple #21
0
static jboolean
dequeue(jdwpPacket *packet) {
    struct PacketList *node = NULL;

    debugMonitorEnter(cmdQueueLock);

    while (!transportError && (cmdQueue == NULL)) {
        debugMonitorWait(cmdQueueLock);
    }

    if (cmdQueue != NULL) {
        node = (struct PacketList *)cmdQueue;
        cmdQueue = node->next;
    }
    debugMonitorExit(cmdQueueLock);

    if (node != NULL) {
        *packet = node->packet;
        jvmtiDeallocate(node);
    }
    return (node != NULL);
}
Exemple #22
0
static void
deleteComponents(void *ptr)
{
    jvmtiDeallocate(ptr);
}
/*
 * Determine if this event is interesting to this handler.
 * Do so by checking each of the handler's filters.
 * Return false if any of the filters fail,
 * true if the handler wants this event.
 * Anyone modifying this function should check
 * eventFilterRestricted_passesUnloadFilter and
 * eventFilter_predictFiltering as well.
 *
 * If shouldDelete is returned true, a count filter has expired
 * and the corresponding node should be deleted.
 */
jboolean
eventFilterRestricted_passesFilter(JNIEnv *env,
                                   char *classname,
                                   EventInfo *evinfo,
                                   HandlerNode *node,
                                   jboolean *shouldDelete)
{
    jthread thread;
    jclass clazz;
    jmethodID method;
    Filter *filter = FILTERS_ARRAY(node);
    int i;

    *shouldDelete = JNI_FALSE;
    thread = evinfo->thread;
    clazz = evinfo->clazz;
    method = evinfo->method;

    /*
     * Suppress most events if they happen in debug threads
     */
    if ((evinfo->ei != EI_CLASS_PREPARE) &&
        (evinfo->ei != EI_GC_FINISH) &&
        (evinfo->ei != EI_CLASS_LOAD) &&
        threadControl_isDebugThread(thread)) {
        return JNI_FALSE;
    }

    for (i = 0; i < FILTER_COUNT(node); ++i, ++filter) {
        switch (filter->modifier) {
            case JDWP_REQUEST_MODIFIER(ThreadOnly):
                if (!isSameObject(env, thread, filter->u.ThreadOnly.thread)) {
                    return JNI_FALSE;
                }
                break;

            case JDWP_REQUEST_MODIFIER(ClassOnly):
                /* Class filters catch events in the specified
                 * class and any subclass/subinterface.
                 */
                if (!JNI_FUNC_PTR(env,IsAssignableFrom)(env, clazz,
                               filter->u.ClassOnly.clazz)) {
                    return JNI_FALSE;
                }
                break;

            /* This is kinda cheating assumming the event
             * fields will be in the same locations, but it is
             * true now.
             */
            case JDWP_REQUEST_MODIFIER(LocationOnly):
                if  (evinfo->method !=
                          filter->u.LocationOnly.method ||
                     evinfo->location !=
                          filter->u.LocationOnly.location ||
                     !isSameObject(env, clazz, filter->u.LocationOnly.clazz)) {
                    return JNI_FALSE;
                }
                break;

            case JDWP_REQUEST_MODIFIER(FieldOnly):
                /* Field watchpoints can be triggered from the
                 * declared class or any subclass/subinterface.
                 */
                if ((evinfo->u.field_access.field !=
                     filter->u.FieldOnly.field) ||
                    !isSameObject(env, evinfo->u.field_access.field_clazz,
                               filter->u.FieldOnly.clazz)) {
                    return JNI_FALSE;
                }
                break;

            case JDWP_REQUEST_MODIFIER(ExceptionOnly):
                /* do we want caught/uncaught exceptions */
                if (!((evinfo->u.exception.catch_clazz == NULL)?
                      filter->u.ExceptionOnly.uncaught :
                      filter->u.ExceptionOnly.caught)) {
                    return JNI_FALSE;
                }

                /* do we care about exception class */
                if (filter->u.ExceptionOnly.exception != NULL) {
                    jclass exception = evinfo->object;

                    /* do we want this exception class */
                    if (!JNI_FUNC_PTR(env,IsInstanceOf)(env, exception,
                            filter->u.ExceptionOnly.exception)) {
                        return JNI_FALSE;
                    }
                }
                break;

            case JDWP_REQUEST_MODIFIER(InstanceOnly): {
                jobject eventInst = eventInstance(evinfo);
                jobject filterInst = filter->u.InstanceOnly.instance;
                /* if no error and doesn't match, don't pass
                 * filter
                 */
                if (eventInst != NULL &&
                      !isSameObject(env, eventInst, filterInst)) {
                    return JNI_FALSE;
                }
                break;
            }
            case JDWP_REQUEST_MODIFIER(Count): {
                JDI_ASSERT(filter->u.Count.count > 0);
                if (--filter->u.Count.count > 0) {
                    return JNI_FALSE;
                }
                *shouldDelete = JNI_TRUE;
                break;
            }

            case JDWP_REQUEST_MODIFIER(Conditional):
/***
                if (...  filter->u.Conditional.exprID ...) {
                    return JNI_FALSE;
                }
***/
                break;

        case JDWP_REQUEST_MODIFIER(ClassMatch): {
            if (!patternStringMatch(classname,
                       filter->u.ClassMatch.classPattern)) {
                return JNI_FALSE;
            }
            break;
        }

        case JDWP_REQUEST_MODIFIER(ClassExclude): {
            if (patternStringMatch(classname,
                      filter->u.ClassExclude.classPattern)) {
                return JNI_FALSE;
            }
            break;
        }

        case JDWP_REQUEST_MODIFIER(Step):
                if (!isSameObject(env, thread, filter->u.Step.thread)) {
                    return JNI_FALSE;
                }
                if (!stepControl_handleStep(env, thread, clazz, method)) {
                    return JNI_FALSE;
                }
                break;

          case JDWP_REQUEST_MODIFIER(SourceNameMatch): {
              char* desiredNamePattern = filter->u.SourceNameOnly.sourceNamePattern;
              if (!searchAllSourceNames(env, clazz,
                           desiredNamePattern) == 1) {
                  /* The name isn't in the SDE; try the sourceName in the ref
                   * type
                   */
                  char *sourceName = 0;
                  jvmtiError error = JVMTI_FUNC_PTR(gdata->jvmti,GetSourceFileName)
                                            (gdata->jvmti, clazz, &sourceName);
                  if (error == JVMTI_ERROR_NONE &&
                      sourceName != 0 &&
                      patternStringMatch(sourceName, desiredNamePattern)) {
                          // got a hit - report the event
                          jvmtiDeallocate(sourceName);
                          break;
                  }
                  // We have no match, we have no source file name,
                  // or we got a JVM TI error. Don't report the event.
                  jvmtiDeallocate(sourceName);
                  return JNI_FALSE;
              }
              break;
          }

        default:
            EXIT_ERROR(AGENT_ERROR_ILLEGAL_ARGUMENT,"Invalid filter modifier");
            return JNI_FALSE;
        }
    }
    return JNI_TRUE;
}
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;
    }
}
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;
}
Exemple #26
0
/*
 * Determine the component class by looking thru all classes for
 * one that has the signature of the component and the same class loadeer
 * as the array.  See JVM spec 5.3.3:
 *     If the component type is a reference type, C is marked as having
 *     been defined by the defining class loader of the component type.
 */
static jdwpError 
getComponentClass(JNIEnv *env, jclass arrayClass, char *componentSignature, 
                jclass *componentClassPtr) 
{
    jobject arrayClassLoader;
    jclass *classes;
    jint count;
    jclass componentClass = NULL;
    jdwpError serror;
    jvmtiError error;

    serror = JDWP_ERROR(NONE);
    
    error = classLoader(arrayClass, &arrayClassLoader);
    if (error != JVMTI_ERROR_NONE) {
        return map2jdwpError(error);
    }
    
    error = allLoadedClasses(&classes, &count);
    if (error != JVMTI_ERROR_NONE) {
        serror = map2jdwpError(error);
    } else {
        int i;
        for (i = 0; (i < count) && (componentClass == NULL); i++) {
            char *signature = NULL;
            jclass clazz = classes[i];
            jboolean match;
            jvmtiError error;

            /* signature must match */
            error = classSignature(clazz, &signature, NULL);
            if (error != JVMTI_ERROR_NONE) {
                serror = map2jdwpError(error);
                break;
            }
            match = strcmp(signature, componentSignature) == 0;
            jvmtiDeallocate(signature);

            /* if signature matches, get class loader to check if
             * it matches 
             */
            if (match) {
                jobject loader;
                error = classLoader(clazz, &loader);
                if (error != JVMTI_ERROR_NONE) {
                    return map2jdwpError(error);
                }
                match = isSameObject(env, loader, arrayClassLoader);
            }

            if (match) {
                componentClass = clazz;
            }
        }
        jvmtiDeallocate(classes);

        *componentClassPtr = componentClass;
    }

    if (serror == JDWP_ERROR(NONE) && componentClass == NULL) {
        /* per JVM spec, component class is always loaded 
         * before array class, so this should never occur.
         */
        serror = JDWP_ERROR(NOT_FOUND);
    }

    return serror;
}
Exemple #27
0
static void JNICALL
cbEarlyException(jvmtiEnv *jvmti_env, JNIEnv *env,
                 jthread thread, jmethodID method, jlocation location,
                 jobject exception,
                 jmethodID catch_method, jlocation catch_location)
{
    jvmtiError error;
    jthrowable currentException;

    LOG_CB(("cbEarlyException: thread=%p", thread));

    if ( gdata->vmDead ) {
        EXIT_ERROR(AGENT_ERROR_INTERNAL,"VM dead at initial Exception event");
    }
    if (!vmInitialized)  {
        LOG_MISC(("VM is not initialized yet"));
        return;
    }

    /*
     * We want to preserve any current exception that might get wiped
     * out during event handling (e.g. JNI calls). We have to rely on
     * space for the local reference on the current frame because
     * doing a PushLocalFrame here might itself generate an exception.
     */

    currentException = JNI_FUNC_PTR(env,ExceptionOccurred)(env);
    JNI_FUNC_PTR(env,ExceptionClear)(env);

    if (initOnUncaught && catch_method == NULL) {

        LOG_MISC(("Initializing on uncaught exception"));
        initialize(env, thread, EI_EXCEPTION);

    } else if (initOnException != NULL) {

        jclass clazz;

        /* Get class of exception thrown */
        clazz = JNI_FUNC_PTR(env,GetObjectClass)(env, exception);
        if ( clazz != NULL ) {
            char *signature = NULL;
            /* initing on throw, check */
            error = classSignature(clazz, &signature, NULL);
            LOG_MISC(("Checking specific exception: looking for %s, got %s",
                      initOnException, signature));
            if ( (error==JVMTI_ERROR_NONE) &&
                    (strcmp(signature, initOnException) == 0)) {
                LOG_MISC(("Initializing on specific exception"));
                initialize(env, thread, EI_EXCEPTION);
            } else {
                error = AGENT_ERROR_INTERNAL; /* Just to cause restore */
            }
            if ( signature != NULL ) {
                jvmtiDeallocate(signature);
            }
        } else {
            error = AGENT_ERROR_INTERNAL; /* Just to cause restore */
        }

        /* If initialize didn't happen, we need to restore things */
        if ( error != JVMTI_ERROR_NONE ) {
            /*
             * Restore exception state from before callback call
             */
            LOG_MISC(("No initialization, didn't find right exception"));
            if (currentException != NULL) {
                JNI_FUNC_PTR(env,Throw)(env, currentException);
            } else {
                JNI_FUNC_PTR(env,ExceptionClear)(env);
            }
        }

    }

    LOG_MISC(("END cbEarlyException"));

}