Fix some warnings in the debugger code

This commit is contained in:
Ben Gruver 2015-02-08 16:13:41 -08:00
parent 6649a75532
commit 4a9e7df53e
3 changed files with 78 additions and 39 deletions

View File

@ -39,8 +39,10 @@ import com.intellij.debugger.engine.evaluation.*;
import com.intellij.debugger.engine.events.DebuggerCommandImpl;
import com.intellij.debugger.impl.DebuggerContextImpl;
import com.intellij.debugger.jdi.StackFrameProxyImpl;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.fileTypes.LanguageFileType;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.Computable;
import com.intellij.psi.JavaCodeFragment;
import com.intellij.psi.JavaRecursiveElementVisitor;
import com.intellij.psi.PsiElement;
@ -55,6 +57,7 @@ import org.jf.smalidea.psi.impl.SmaliInstruction;
import org.jf.smalidea.psi.impl.SmaliMethod;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.util.Map;
public class SmaliCodeFragmentFactory extends DefaultCodeFragmentFactory {
@ -185,10 +188,16 @@ public class SmaliCodeFragmentFactory extends DefaultCodeFragmentFactory {
final JavaCodeFragment codeFragment = super.createCodeFragment(textWithImports, originalContext, project);
codeFragment.accept(new JavaRecursiveElementVisitor() {
@Override
public void visitLocalVariable(final PsiLocalVariable variable) {
final String name = variable.getName();
if (registerMap.containsKey(name)) {
debuggerContext.getDebugProcess().getManagerThread().invoke(new DebuggerCommandImpl() {
DebugProcessImpl process = debuggerContext.getDebugProcess();
if (process == null) {
return;
}
process.getManagerThread().invoke(new DebuggerCommandImpl() {
@Override protected void action() throws Exception {
int registerNumber = Integer.parseInt(name.substring(1));
if (name.charAt(0) == 'p') {
@ -206,14 +215,10 @@ public class SmaliCodeFragmentFactory extends DefaultCodeFragmentFactory {
variable.putUserData(CodeFragmentFactoryContextWrapper.LABEL_VARIABLE_VALUE_KEY, value);
}
});
}
}
});
int offset = variablesText.length() - 1;
final PsiElement newContext = codeFragment.findElementAt(offset);
@ -224,24 +229,24 @@ public class SmaliCodeFragmentFactory extends DefaultCodeFragmentFactory {
}
public Value evaluateRegister(EvaluationContextImpl context, final SmaliMethod smaliMethod, final int registerNum,
final String type) {
final String type) throws EvaluateException {
final StackFrameProxyImpl frameProxy = context.getFrameProxy();
if (frameProxy == null) {
return null;
}
// the jdi apis don't provide any way to get the value of an arbitrary register, so we use reflection
// the jdi APIs don't provide any way to get the value of an arbitrary register, so we use reflection
// to create a LocalVariable instance for the register
final Value[] ret = new Value[1];
DebugProcessImpl debugProcess = context.getDebugProcess();
debugProcess.getManagerThread().invoke(
new DebuggerCommandImpl() {
@Override protected void action() throws Exception {
VirtualMachine vm = frameProxy.getVirtualMachine().getVirtualMachine();
Method method = frameProxy.location().method();
Location currentLocation = frameProxy.location();
if (currentLocation == null) {
return null;
}
Method method = currentLocation.method();
try {
final Constructor<LocalVariableImpl> localVariableConstructor = LocalVariableImpl.class.getDeclaredConstructor(
VirtualMachine.class, Method.class, Integer.TYPE, Location.class, Location.class, String.class,
String.class, String.class);
@ -256,17 +261,29 @@ public class SmaliCodeFragmentFactory extends DefaultCodeFragmentFactory {
LocalVariable localVariable = localVariableConstructor.newInstance(vm,
method,
mapRegisterForArt(smaliMethod, registerNum),
frameProxy.location().method().locationOfCodeIndex(0),
mapRegister(frameProxy.getStackFrame().virtualMachine(), smaliMethod, registerNum),
method.locationOfCodeIndex(0),
endLocation,
String.format("v%d", registerNum), type, null);
ret[0] = frameProxy.getStackFrame().getValue(localVariable);
return frameProxy.getStackFrame().getValue(localVariable);
} catch (NoSuchMethodException e) {
return null;
} catch (InstantiationException e) {
return null;
} catch (IllegalAccessException e) {
return null;
} catch (InvocationTargetException e) {
return null;
}
}
);
return ret[0];
private static int mapRegister(final VirtualMachine vm, final SmaliMethod smaliMethod, final int register) {
if (vm.version().equals("1.5.0")) {
return mapRegisterForDalvik(smaliMethod, register);
} else {
return mapRegisterForArt(smaliMethod, register);
}
}
private static int mapRegisterForArt(final SmaliMethod smaliMethod, final int register) {
@ -288,5 +305,27 @@ public class SmaliCodeFragmentFactory extends DefaultCodeFragmentFactory {
}
});
}
private static int mapRegisterForDalvik(final SmaliMethod smaliMethod, final int register) {
return ApplicationManager.getApplication().runReadAction(new Computable<Integer>() {
@Override public Integer compute() {
if (smaliMethod.getModifierList().hasModifierProperty("static")) {
return register;
}
int totalRegisters = smaliMethod.getRegisterCount();
int parameterRegisters = smaliMethod.getParameterRegisterCount();
// For dalvik, p0 is mapped to register 1, and register 0 is mapped to register 1000
if (register == (totalRegisters - parameterRegisters)) {
return 0;
}
if (register == 0) {
return 1000;
}
return register;
}
});
}
}

View File

@ -40,16 +40,15 @@ import com.intellij.xdebugger.impl.actions.DebuggerActionHandler;
import com.sun.jdi.request.StepRequest;
import org.jetbrains.annotations.NotNull;
import java.lang.reflect.Method;
public class SmaliDebuggerSupport extends JavaDebuggerSupport {
private static boolean useModifiedMethod;
{
static {
try {
Method method = DebuggerSession.class.getMethod("stepOver", boolean.class, int.class);
DebuggerSession.class.getMethod("stepOver", boolean.class, int.class);
useModifiedMethod = true;
} catch (NoSuchMethodException ex) {
useModifiedMethod = false;
}
}

View File

@ -34,10 +34,11 @@ package org.jf.smalidea.debugging;
import com.intellij.debugger.PositionManager;
import com.intellij.debugger.PositionManagerFactory;
import com.intellij.debugger.engine.DebugProcess;
import org.jetbrains.annotations.NotNull;
public class SmaliPositionManagerFactory extends PositionManagerFactory {
@Override
public PositionManager createPositionManager(DebugProcess process) {
public PositionManager createPositionManager(@NotNull DebugProcess process) {
return new SmaliPositionManager(process);
}
}