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;
}
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);
}
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;
}
}
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);
}
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);
}
Aggregations