Commit 97f737fc authored by Egor Ushakov's avatar Egor Ushakov
Browse files

trace only one current thread

parent 163f15a6
Branches unavailable Tags unavailable
No related merge requests found
Showing with 79 additions and 51 deletions
+79 -51
...@@ -284,10 +284,10 @@ public abstract class Breakpoint<P extends JavaBreakpointProperties> implements ...@@ -284,10 +284,10 @@ public abstract class Breakpoint<P extends JavaBreakpointProperties> implements
private void runAction(EvaluationContextImpl context, LocatableEvent event) { private void runAction(EvaluationContextImpl context, LocatableEvent event) {
DebugProcessImpl debugProcess = context.getDebugProcess(); DebugProcessImpl debugProcess = context.getDebugProcess();
if (getProperties().isTRACING_START() && Registry.is("debugger.call.tracing")) { if (getProperties().isTRACING_START() && Registry.is("debugger.call.tracing")) {
CallTracer.get(debugProcess).start(context); CallTracer.get(debugProcess).start(context.getSuspendContext().getThread());
} }
if (getProperties().isTRACING_END() && Registry.is("debugger.call.tracing")) { if (getProperties().isTRACING_END() && Registry.is("debugger.call.tracing")) {
CallTracer.get(debugProcess).stop(); CallTracer.get(debugProcess).stop(event.thread());
} }
if (isLogEnabled() || isLogExpressionEnabled() || isLogStack()) { if (isLogEnabled() || isLogExpressionEnabled() || isLogStack()) {
StringBuilder buf = new StringBuilder(); StringBuilder buf = new StringBuilder();
......
...@@ -3,7 +3,7 @@ package com.intellij.debugger.ui.breakpoints; ...@@ -3,7 +3,7 @@ package com.intellij.debugger.ui.breakpoints;
import com.intellij.debugger.engine.*; import com.intellij.debugger.engine.*;
import com.intellij.debugger.engine.evaluation.EvaluateException; import com.intellij.debugger.engine.evaluation.EvaluateException;
import com.intellij.debugger.engine.evaluation.EvaluationContextImpl; import com.intellij.debugger.impl.DebuggerContextImpl;
import com.intellij.debugger.impl.DebuggerUtilsEx; import com.intellij.debugger.impl.DebuggerUtilsEx;
import com.intellij.debugger.impl.PrioritizedTask; import com.intellij.debugger.impl.PrioritizedTask;
import com.intellij.debugger.jdi.StackFrameProxyImpl; import com.intellij.debugger.jdi.StackFrameProxyImpl;
...@@ -24,9 +24,12 @@ import com.sun.jdi.request.EventRequest; ...@@ -24,9 +24,12 @@ import com.sun.jdi.request.EventRequest;
import com.sun.jdi.request.EventRequestManager; import com.sun.jdi.request.EventRequestManager;
import com.sun.jdi.request.MethodEntryRequest; import com.sun.jdi.request.MethodEntryRequest;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
/** /**
* @author egor * @author egor
...@@ -37,67 +40,46 @@ public class CallTracer { ...@@ -37,67 +40,46 @@ public class CallTracer {
private final EventRequestManager myRequestManager; private final EventRequestManager myRequestManager;
private final DebugProcessImpl myDebugProcess; private final DebugProcessImpl myDebugProcess;
private final List<MethodEntryRequest> myEntryRequests = new ArrayList<>(1); private final Map<ThreadReference, ThreadRequest> myThreadRequests = new ConcurrentHashMap<>();
private int myStartIndent = 0;
public CallTracer(DebugProcessImpl debugProcess) { public CallTracer(DebugProcessImpl debugProcess) {
myDebugProcess = debugProcess; myDebugProcess = debugProcess;
myRequestManager = debugProcess.getRequestsManager().getVMRequestManager(); myRequestManager = debugProcess.getRequestsManager().getVMRequestManager();
} }
public void start(EvaluationContextImpl context) { public void start(@Nullable ThreadReferenceProxyImpl thread) {
int indent = 0;
try { try {
ThreadReferenceProxyImpl thread = context.getSuspendContext().getThread();
if (thread != null) { if (thread != null) {
indent = thread.frameCount(); start(thread.getThreadReference(), thread.frameCount());
} }
} }
catch (EvaluateException e) { catch (EvaluateException e) {
LOG.error(e); LOG.error(e);
} }
start(indent);
} }
private void start(int startIndent) { private void start(@NotNull ThreadReference thread, int startIndent) {
DebuggerManagerThreadImpl.assertIsManagerThread(); DebuggerManagerThreadImpl.assertIsManagerThread();
if (myEntryRequests.isEmpty()) { myThreadRequests.computeIfAbsent(thread, t -> new ThreadRequest(t, startIndent));
myStartIndent = startIndent;
TraceSettings traceSettings = TraceSettings.getInstance();
ClassFilter[] classFilters = traceSettings.getClassFilters();
ClassFilter[] exclusionFilters = traceSettings.getClassExclusionFilters();
if (DebuggerUtilsEx.getEnabledNumber(classFilters) == 0) {
addEntryRequest(null, exclusionFilters);
}
else {
for (ClassFilter filter : classFilters) {
if (filter.isEnabled()) {
addEntryRequest(filter, exclusionFilters);
}
}
}
}
} }
private void addEntryRequest(ClassFilter filter, ClassFilter[] exclusionFilters) { public void stop(@NotNull ThreadReference thread) {
MethodEntryRequest request = myRequestManager.createMethodEntryRequest(); DebuggerManagerThreadImpl.assertIsManagerThread();
request.setSuspendPolicy(EventRequest.SUSPEND_EVENT_THREAD); // to be able to detect frameCount inside the event handler ThreadRequest request = myThreadRequests.remove(thread);
myDebugProcess.getRequestsManager() if (request != null) {
.addClassFilters(request, filter != null ? new ClassFilter[]{filter} : ClassFilter.EMPTY_ARRAY, exclusionFilters); request.stop();
myEntryRequests.add(request); }
DebugProcessEvents.enableRequestWithHandler(request, this::accept);
} }
public void stop() { public void stopAll() {
DebuggerManagerThreadImpl.assertIsManagerThread(); DebuggerManagerThreadImpl.assertIsManagerThread();
if (!myEntryRequests.isEmpty()) { List<ThreadRequest> requests = new ArrayList<>(myThreadRequests.values());
myEntryRequests.forEach(myRequestManager::deleteEventRequest); myThreadRequests.clear();
myEntryRequests.clear(); requests.forEach(ThreadRequest::stop);
}
} }
private boolean isActive() { private boolean isActive() {
return !myEntryRequests.isEmpty(); return !myThreadRequests.isEmpty();
} }
private void accept(Event event) { private void accept(Event event) {
...@@ -105,15 +87,18 @@ public class CallTracer { ...@@ -105,15 +87,18 @@ public class CallTracer {
MethodEntryEvent methodEntryEvent = (MethodEntryEvent)event; MethodEntryEvent methodEntryEvent = (MethodEntryEvent)event;
try { try {
ThreadReference thread = methodEntryEvent.thread(); ThreadReference thread = methodEntryEvent.thread();
for (SuspendContextImpl context : myDebugProcess.getSuspendManager().getEventContexts()) { ThreadRequest request = myThreadRequests.get(thread);
ThreadReferenceProxyImpl contextThread = context.getThread(); if (request != null) {
if (context.isEvaluating() && contextThread != null && contextThread.getThreadReference().equals(thread)) { for (SuspendContextImpl context : myDebugProcess.getSuspendManager().getEventContexts()) {
return; // evaluating - skip ThreadReferenceProxyImpl contextThread = context.getThread();
if (context.isEvaluating() && contextThread != null && contextThread.getThreadReference().equals(thread)) {
return; // evaluating - skip
}
} }
int indent = thread.frameCount() - request.myStartIndent;
String indentString = indent < 0 ? "-" : StringUtil.repeat(" ", indent);
myDebugProcess.printToConsole("\n" + indentString + methodEntryEvent.method() + " thread " + thread.uniqueID());
} }
int indent = thread.frameCount() - myStartIndent;
String indentString = indent < 0 ? "-" : StringUtil.repeat(" ", indent);
myDebugProcess.printToConsole("\n" + indentString + methodEntryEvent.method() + " thread " + thread.uniqueID());
} }
catch (IncompatibleThreadStateException e) { catch (IncompatibleThreadStateException e) {
LOG.error(e); LOG.error(e);
...@@ -131,6 +116,42 @@ public class CallTracer { ...@@ -131,6 +116,42 @@ public class CallTracer {
return tracer; return tracer;
} }
private class ThreadRequest {
private final List<MethodEntryRequest> myEntryRequests = new ArrayList<>(1);
private final int myStartIndent;
private ThreadRequest(ThreadReference thread, int startIndent) {
myStartIndent = startIndent;
TraceSettings traceSettings = TraceSettings.getInstance();
ClassFilter[] classFilters = traceSettings.getClassFilters();
ClassFilter[] exclusionFilters = traceSettings.getClassExclusionFilters();
if (DebuggerUtilsEx.getEnabledNumber(classFilters) == 0) {
addEntryRequest(null, exclusionFilters, thread);
}
else {
for (ClassFilter filter : classFilters) {
if (filter.isEnabled()) {
addEntryRequest(filter, exclusionFilters, thread);
}
}
}
}
private void addEntryRequest(ClassFilter filter, ClassFilter[] exclusionFilters, ThreadReference thread) {
MethodEntryRequest request = myRequestManager.createMethodEntryRequest();
request.setSuspendPolicy(EventRequest.SUSPEND_EVENT_THREAD); // to be able to detect frameCount inside the event handler
request.addThreadFilter(thread);
myDebugProcess.getRequestsManager()
.addClassFilters(request, filter != null ? new ClassFilter[]{filter} : ClassFilter.EMPTY_ARRAY, exclusionFilters);
myEntryRequests.add(request);
DebugProcessEvents.enableRequestWithHandler(request, CallTracer.this::accept);
}
void stop() {
myEntryRequests.forEach(myRequestManager::deleteEventRequest);
}
}
public static class CallTracerToggleAction extends DumbAwareToggleAction { public static class CallTracerToggleAction extends DumbAwareToggleAction {
@Override @Override
public void update(@NotNull AnActionEvent e) { public void update(@NotNull AnActionEvent e) {
...@@ -156,14 +177,21 @@ public class CallTracer { ...@@ -156,14 +177,21 @@ public class CallTracer {
if (process != null) { if (process != null) {
CallTracer tracer = get(process); CallTracer tracer = get(process);
process.getManagerThread().schedule(PrioritizedTask.Priority.HIGH, () -> { process.getManagerThread().schedule(PrioritizedTask.Priority.HIGH, () -> {
DebuggerContextImpl debuggerContext = process.getDebuggerContext();
ThreadReferenceProxyImpl threadProxy = debuggerContext.getThreadProxy();
if (state) { if (state) {
StackFrameProxyImpl frame = process.getDebuggerContext().getFrameProxy(); StackFrameProxyImpl frame = debuggerContext.getFrameProxy();
if (frame != null) { if (frame != null && threadProxy != null) {
tracer.start(frame.getIndexFromBottom()); tracer.start(threadProxy.getThreadReference(), frame.getIndexFromBottom());
} }
} }
else { else {
tracer.stop(); if (threadProxy != null) {
tracer.stop(threadProxy.getThreadReference());
}
else {
tracer.stopAll();
}
} }
}); });
} }
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment