Search in sources :

Example 1 with MethodRef

use of com.oracle.truffle.espresso.jdwp.api.MethodRef in project graal by oracle.

the class DebuggerController method captureCallFramesBeforeBlocking.

public CallFrame[] captureCallFramesBeforeBlocking(Object guestThread) {
    List<CallFrame> callFrames = new ArrayList<>();
    Truffle.getRuntime().iterateFrames(new FrameInstanceVisitor<>() {

        @Override
        public Object visitFrame(FrameInstance frameInstance) {
            KlassRef klass;
            MethodRef method;
            RootNode root = getRootNode(frameInstance);
            if (root == null) {
                return null;
            }
            method = getContext().getMethodFromRootNode(root);
            if (method == null) {
                return null;
            }
            klass = method.getDeclaringKlassRef();
            long klassId = ids.getIdAsLong(klass);
            long methodId = ids.getIdAsLong(method);
            byte typeTag = TypeTag.getKind(klass);
            Frame frame = frameInstance.getFrame(FrameInstance.FrameAccess.READ_WRITE);
            // for bytecode-based languages (Espresso) we can read the precise bci from the
            // frame
            long codeIndex = -1;
            try {
                codeIndex = context.readBCIFromFrame(root, frame);
            } catch (Throwable t) {
                JDWP.LOGGER.fine(() -> "Unable to read current BCI from frame in method: " + klass.getNameAsString() + "." + method.getNameAsString());
            }
            if (codeIndex == -1) {
                // fall back to start of the method then
                codeIndex = 0;
            }
            // check if current bci is higher than the first index on the last line,
            // in which case we must report the last line index instead
            long lastLineBCI = method.getBCIFromLine(method.getLastLine());
            if (codeIndex > lastLineBCI) {
                codeIndex = lastLineBCI;
            }
            Node currentNode = frameInstance.getCallNode();
            if (currentNode == null) {
                CallTarget callTarget = frameInstance.getCallTarget();
                if (callTarget instanceof RootCallTarget) {
                    currentNode = ((RootCallTarget) callTarget).getRootNode();
                }
            }
            if (currentNode instanceof RootNode) {
                currentNode = context.getInstrumentableNode((RootNode) currentNode);
            }
            callFrames.add(new CallFrame(context.getIds().getIdAsLong(guestThread), typeTag, klassId, method, methodId, codeIndex, frame, currentNode, root, null, context));
            return null;
        }
    });
    CallFrame[] result = callFrames.toArray(new CallFrame[callFrames.size()]);
    // collect monitor info
    MonitorStackInfo[] ownedMonitorInfos = context.getOwnedMonitors(result);
    HashMap<Object, Integer> entryCounts = new HashMap<>(ownedMonitorInfos.length);
    for (MonitorStackInfo ownedMonitorInfo : ownedMonitorInfos) {
        Object monitor = ownedMonitorInfo.getMonitor();
        entryCounts.put(monitor, context.getMonitorEntryCount(monitor));
    }
    suspendedInfos.put(guestThread, new SuspendedInfo(context, result, guestThread, entryCounts));
    return result;
}
Also used : RootNode(com.oracle.truffle.api.nodes.RootNode) DebugStackFrame(com.oracle.truffle.api.debug.DebugStackFrame) CallFrame(com.oracle.truffle.espresso.jdwp.api.CallFrame) Frame(com.oracle.truffle.api.frame.Frame) HashMap(java.util.HashMap) RootCallTarget(com.oracle.truffle.api.RootCallTarget) CallTarget(com.oracle.truffle.api.CallTarget) RootNode(com.oracle.truffle.api.nodes.RootNode) Node(com.oracle.truffle.api.nodes.Node) ArrayList(java.util.ArrayList) MonitorStackInfo(com.oracle.truffle.espresso.jdwp.api.MonitorStackInfo) FrameInstance(com.oracle.truffle.api.frame.FrameInstance) MethodRef(com.oracle.truffle.espresso.jdwp.api.MethodRef) CallFrame(com.oracle.truffle.espresso.jdwp.api.CallFrame) KlassRef(com.oracle.truffle.espresso.jdwp.api.KlassRef) RootCallTarget(com.oracle.truffle.api.RootCallTarget)

Example 2 with MethodRef

use of com.oracle.truffle.espresso.jdwp.api.MethodRef in project graal by oracle.

the class JDWPContextImpl method locateObjectWaitFrame.

@Override
public CallFrame locateObjectWaitFrame() {
    Object currentThread = asGuestThread(Thread.currentThread());
    KlassRef klass = context.getMeta().java_lang_Object;
    MethodRef method = context.getMeta().java_lang_Object_wait.getMethodVersion();
    return new CallFrame(ids.getIdAsLong(currentThread), TypeTag.CLASS, ids.getIdAsLong(klass), method, ids.getIdAsLong(method), 0, null, null, null, null, null);
}
Also used : MethodRef(com.oracle.truffle.espresso.jdwp.api.MethodRef) CallFrame(com.oracle.truffle.espresso.jdwp.api.CallFrame) KlassRef(com.oracle.truffle.espresso.jdwp.api.KlassRef)

Example 3 with MethodRef

use of com.oracle.truffle.espresso.jdwp.api.MethodRef in project graal by oracle.

the class RequestedJDWPEvents method handleModKind.

private void handleModKind(RequestFilter filter, PacketStream input, byte modKind, JDWPContext context) {
    switch(modKind) {
        case 1:
            int count = input.readInt();
            JDWP.LOGGER.fine(() -> "adding count limit: " + count + " to filter");
            filter.addEventCount(count);
            break;
        case 2:
            JDWP.LOGGER.fine(() -> "unhandled modKind 2");
            break;
        case // limit to specific thread
        3:
            long threadId = input.readLong();
            Object thread = ids.fromId((int) threadId);
            filter.addThread(thread);
            JDWP.LOGGER.fine(() -> "limiting to thread: " + context.getThreadName(thread));
            break;
        case 4:
            long refTypeId = input.readLong();
            final KlassRef finalKlass = (KlassRef) ids.fromId((int) refTypeId);
            filter.addRefTypeLimit(finalKlass);
            JDWP.LOGGER.fine(() -> "RefType limit: " + finalKlass);
            break;
        case // class positive pattern
        5:
            String classPattern = Pattern.quote(input.readString()).replace("*", "\\E.*\\Q");
            try {
                Pattern pattern = Pattern.compile(classPattern);
                filter.addPositivePattern(pattern);
                JDWP.LOGGER.fine(() -> "adding positive refType pattern: " + pattern.pattern());
            } catch (PatternSyntaxException ex) {
                // wrong input pattern
                throw new RuntimeException("should not reach here");
            }
            break;
        case 6:
            classPattern = Pattern.quote(input.readString()).replace("*", "\\E.*\\Q");
            try {
                Pattern pattern = Pattern.compile(classPattern);
                filter.addExcludePattern(pattern);
                JDWP.LOGGER.fine(() -> "adding negative refType pattern: " + pattern.pattern());
            } catch (PatternSyntaxException ex) {
                // wrong input pattern
                throw new RuntimeException("should not reach here");
            }
            break;
        case // location-specific
        7:
            byte typeTag = input.readByte();
            long classId = input.readLong();
            long methodId = input.readLong();
            long bci = input.readLong();
            final KlassRef finalKlass2 = (KlassRef) ids.fromId((int) classId);
            String slashName = finalKlass2.getTypeAsString();
            MethodRef method = (MethodRef) ids.fromId((int) methodId);
            int line = method.bciToLineNumber((int) bci);
            LineBreakpointInfo info = new LineBreakpointInfo(filter, typeTag, classId, methodId, bci, slashName, line);
            filter.addBreakpointInfo(info);
            JDWP.LOGGER.fine(() -> "Adding breakpoint info for location: " + finalKlass2.getNameAsString() + "." + method.getNameAsString() + "." + line);
            break;
        case 8:
            refTypeId = input.readLong();
            KlassRef klass = null;
            if (refTypeId != 0) {
                klass = (KlassRef) ids.fromId((int) refTypeId);
            }
            boolean caught = input.readBoolean();
            boolean unCaught = input.readBoolean();
            ExceptionBreakpointInfo exceptionBreakpointInfo = new ExceptionBreakpointInfo(filter, klass, caught, unCaught);
            filter.addBreakpointInfo(exceptionBreakpointInfo);
            JDWP.LOGGER.fine(() -> "adding exception filter: caught=" + caught + ", uncaught=" + unCaught);
            break;
        case // limit to specific field
        9:
            refTypeId = input.readLong();
            long fieldId = input.readLong();
            klass = (KlassRef) ids.fromId((int) refTypeId);
            FieldRef field = (FieldRef) ids.fromId((int) fieldId);
            FieldBreakpointInfo fieldBreakpointInfo = new FieldBreakpointInfo(filter, klass, field);
            filter.addBreakpointInfo(fieldBreakpointInfo);
            JDWP.LOGGER.fine(() -> "limiting to field: " + field.getNameAsString());
            break;
        case 10:
            threadId = input.readLong();
            thread = ids.fromId((int) threadId);
            int size = input.readInt();
            int depth = input.readInt();
            StepInfo stepInfo = new StepInfo(size, depth, thread);
            filter.setStepInfo(stepInfo);
            JDWP.LOGGER.fine(() -> "Step command: size= " + size + ", depth=" + depth);
            break;
        case 11:
            long thisId = input.readLong();
            JDWP.LOGGER.fine(() -> "adding instance filter for object ID: " + thisId);
            filter.addThisFilterId(thisId);
            break;
        case 12:
            JDWP.LOGGER.fine(() -> "unhandled modKind 12");
            break;
        default:
            break;
    }
}
Also used : Pattern(java.util.regex.Pattern) FieldRef(com.oracle.truffle.espresso.jdwp.api.FieldRef) MethodRef(com.oracle.truffle.espresso.jdwp.api.MethodRef) KlassRef(com.oracle.truffle.espresso.jdwp.api.KlassRef) PatternSyntaxException(java.util.regex.PatternSyntaxException)

Example 4 with MethodRef

use of com.oracle.truffle.espresso.jdwp.api.MethodRef in project graal by oracle.

the class RequestedJDWPEvents method registerEvent.

public CommandResult registerEvent(Packet packet, Commands callback) {
    ArrayList<Callable<Void>> preFutures = new ArrayList<>();
    ArrayList<Callable<Void>> postFutures = new ArrayList<>();
    PacketStream input = new PacketStream(packet);
    JDWPContext context = controller.getContext();
    byte eventKind = input.readByte();
    byte suspendPolicy = input.readByte();
    int modifiers = input.readInt();
    RequestFilter filter = new RequestFilter(packet.id, eventKind, suspendPolicy);
    JDWP.LOGGER.fine(() -> "New event request with ID: " + packet.id + " with kind: " + eventKind + " and modifiers: " + modifiers);
    for (int i = 0; i < modifiers; i++) {
        byte modKind = input.readByte();
        JDWP.LOGGER.fine(() -> "Handling modKind: " + modKind);
        handleModKind(filter, input, modKind, context);
    }
    switch(eventKind) {
        case SINGLE_STEP:
            StepInfo stepInfo = filter.getStepInfo();
            Object thread = stepInfo.getGuestThread();
            switch(stepInfo.getDepth()) {
                case SteppingConstants.INTO:
                    callback.stepInto(thread, filter);
                    break;
                case SteppingConstants.OVER:
                    callback.stepOver(thread, filter);
                    break;
                case SteppingConstants.OUT:
                    callback.stepOut(thread, filter);
                    break;
            }
            break;
        case METHOD_ENTRY:
        case METHOD_EXIT:
        case METHOD_EXIT_WITH_RETURN_VALUE:
            MethodBreakpointInfo methodInfo = new MethodBreakpointInfo(filter);
            methodInfo.addSuspendPolicy(suspendPolicy);
            eventListener.addBreakpointRequest(filter.getRequestId(), methodInfo);
            for (KlassRef klass : filter.getKlassRefPatterns()) {
                for (MethodRef method : klass.getDeclaredMethodRefs()) {
                    method.addMethodHook(methodInfo);
                    methodInfo.addMethod(method);
                }
            }
            filter.addBreakpointInfo(methodInfo);
            break;
        case BREAKPOINT:
            BreakpointInfo info = filter.getBreakpointInfo();
            info.addSuspendPolicy(suspendPolicy);
            eventListener.addBreakpointRequest(filter.getRequestId(), info);
            postFutures.add(callback.createLineBreakpointCommand(info));
            break;
        case EXCEPTION:
            info = filter.getBreakpointInfo();
            if (info == null) {
                // no filtering then, so setup a report all info
                info = new ExceptionBreakpointInfo(filter, null, true, true);
            }
            info.addSuspendPolicy(suspendPolicy);
            eventListener.addBreakpointRequest(filter.getRequestId(), info);
            preFutures.add(callback.createExceptionBreakpoint(info));
            JDWP.LOGGER.fine(() -> "Submitting new exception breakpoint");
            break;
        case CLASS_PREPARE:
            eventListener.addClassPrepareRequest(new ClassPrepareRequest(filter));
            JDWP.LOGGER.fine(() -> "Class prepare request received");
            break;
        case FIELD_ACCESS:
            FieldBreakpointInfo fieldBreakpointInfo = (FieldBreakpointInfo) filter.getBreakpointInfo();
            fieldBreakpointInfo.addSuspendPolicy(suspendPolicy);
            fieldBreakpointInfo.setAccessBreakpoint();
            fieldBreakpointInfo.getField().addFieldBreakpointInfo(fieldBreakpointInfo);
            String location = fieldBreakpointInfo.getKlass().getNameAsString() + "." + fieldBreakpointInfo.getField().getNameAsString();
            JDWP.LOGGER.fine(() -> "Submitting field access breakpoint: " + location);
            break;
        case FIELD_MODIFICATION:
            fieldBreakpointInfo = (FieldBreakpointInfo) filter.getBreakpointInfo();
            fieldBreakpointInfo.addSuspendPolicy(suspendPolicy);
            fieldBreakpointInfo.setModificationBreakpoint();
            fieldBreakpointInfo.getField().addFieldBreakpointInfo(fieldBreakpointInfo);
            location = fieldBreakpointInfo.getKlass().getNameAsString() + "." + fieldBreakpointInfo.getField().getNameAsString();
            JDWP.LOGGER.fine(() -> "Submitting field modification breakpoint: " + location);
            break;
        case THREAD_START:
            eventListener.addThreadStartedRequestId(packet.id, suspendPolicy);
            break;
        case THREAD_DEATH:
            eventListener.addThreadDiedRequestId(packet.id, suspendPolicy);
            break;
        case CLASS_UNLOAD:
            eventListener.addClassUnloadRequestId(packet.id);
            break;
        case // no debuggers should ask for this event
        VM_START:
            eventListener.addVMStartRequest(packet.id);
            break;
        case VM_DEATH:
            eventListener.addVMDeathRequest(packet.id, suspendPolicy);
            break;
        case MONITOR_CONTENDED_ENTER:
            eventListener.addMonitorContendedEnterRequest(packet.id, filter);
            break;
        case MONITOR_CONTENDED_ENTERED:
            eventListener.addMonitorContendedEnteredRequest(packet.id, filter);
            break;
        case MONITOR_WAIT:
            eventListener.addMonitorWaitRequest(packet.id, filter);
            break;
        case MONITOR_WAITED:
            eventListener.addMonitorWaitedRequest(packet.id, filter);
            break;
        default:
            JDWP.LOGGER.fine(() -> "unhandled event kind " + eventKind);
            break;
    }
    // register the request filter for this event
    controller.getEventFilters().addFilter(filter);
    return new CommandResult(toReply(packet), preFutures, postFutures);
}
Also used : ArrayList(java.util.ArrayList) Callable(java.util.concurrent.Callable) JDWPContext(com.oracle.truffle.espresso.jdwp.api.JDWPContext) MethodRef(com.oracle.truffle.espresso.jdwp.api.MethodRef) KlassRef(com.oracle.truffle.espresso.jdwp.api.KlassRef)

Example 5 with MethodRef

use of com.oracle.truffle.espresso.jdwp.api.MethodRef in project graal by oracle.

the class RequestedJDWPEvents method clearRequest.

public CommandResult clearRequest(Packet packet) {
    PacketStream reply = new PacketStream().id(packet.id).replyPacket();
    PacketStream input = new PacketStream(packet);
    byte eventKind = input.readByte();
    int requestId = input.readInt();
    RequestFilter requestFilter = controller.getEventFilters().getRequestFilter(requestId);
    if (requestFilter != null) {
        byte kind = requestFilter.getEventKind();
        if (kind == eventKind) {
            switch(eventKind) {
                case SINGLE_STEP:
                    JDWP.LOGGER.fine(() -> "Clearing step command: " + requestId);
                    controller.clearStepCommand(requestFilter.getStepInfo());
                    break;
                case METHOD_EXIT_WITH_RETURN_VALUE:
                case METHOD_EXIT:
                    MethodBreakpointInfo methodInfo = (MethodBreakpointInfo) requestFilter.getBreakpointInfo();
                    for (MethodRef method : methodInfo.getMethods()) {
                        method.removedMethodHook(requestFilter.getRequestId());
                    }
                    break;
                case BREAKPOINT:
                case METHOD_ENTRY:
                case EXCEPTION:
                    eventListener.removeBreakpointRequest(requestFilter.getRequestId());
                    break;
                case FIELD_ACCESS:
                case FIELD_MODIFICATION:
                    FieldBreakpointInfo info = (FieldBreakpointInfo) requestFilter.getBreakpointInfo();
                    info.getField().removeFieldBreakpointInfo(requestFilter.getRequestId());
                    break;
                case CLASS_PREPARE:
                    eventListener.removeClassPrepareRequest(requestFilter.getRequestId());
                    break;
                case THREAD_START:
                    eventListener.removeThreadStartedRequestId();
                    break;
                case THREAD_DEATH:
                    eventListener.removeThreadDiedRequestId();
                    break;
                case CLASS_UNLOAD:
                    eventListener.addClassUnloadRequestId(packet.id);
                    break;
                case MONITOR_CONTENDED_ENTER:
                    eventListener.removeMonitorContendedEnterRequest(requestId);
                    break;
                case MONITOR_CONTENDED_ENTERED:
                    eventListener.removeMonitorContendedEnteredRequest(requestId);
                    break;
                case MONITOR_WAIT:
                    eventListener.removeMonitorWaitRequest(requestId);
                    break;
                case MONITOR_WAITED:
                    eventListener.removeMonitorWaitedRequest(requestId);
                    break;
                default:
                    JDWP.LOGGER.fine(() -> "unhandled event clear kind " + eventKind);
                    break;
            }
        } else {
            reply.errorCode(ErrorCodes.INVALID_EVENT_TYPE);
        }
    } else {
        reply.errorCode(ErrorCodes.INVALID_EVENT_TYPE);
    }
    return new CommandResult(reply);
}
Also used : MethodRef(com.oracle.truffle.espresso.jdwp.api.MethodRef)

Aggregations

MethodRef (com.oracle.truffle.espresso.jdwp.api.MethodRef)7 KlassRef (com.oracle.truffle.espresso.jdwp.api.KlassRef)6 ArrayList (java.util.ArrayList)3 Breakpoint (com.oracle.truffle.api.debug.Breakpoint)2 RootNode (com.oracle.truffle.api.nodes.RootNode)2 CallFrame (com.oracle.truffle.espresso.jdwp.api.CallFrame)2 CallTarget (com.oracle.truffle.api.CallTarget)1 RootCallTarget (com.oracle.truffle.api.RootCallTarget)1 DebugStackFrame (com.oracle.truffle.api.debug.DebugStackFrame)1 Frame (com.oracle.truffle.api.frame.Frame)1 FrameInstance (com.oracle.truffle.api.frame.FrameInstance)1 Node (com.oracle.truffle.api.nodes.Node)1 FieldRef (com.oracle.truffle.espresso.jdwp.api.FieldRef)1 JDWPContext (com.oracle.truffle.espresso.jdwp.api.JDWPContext)1 MonitorStackInfo (com.oracle.truffle.espresso.jdwp.api.MonitorStackInfo)1 HashMap (java.util.HashMap)1 Callable (java.util.concurrent.Callable)1 Pattern (java.util.regex.Pattern)1 PatternSyntaxException (java.util.regex.PatternSyntaxException)1