From 4a9e7df53e6c4b4fe047eec058d2220ea4ab959c Mon Sep 17 00:00:00 2001 From: Ben Gruver Date: Sun, 8 Feb 2015 16:13:41 -0800 Subject: [PATCH] Fix some warnings in the debugger code --- .../debugging/SmaliCodeFragmentFactory.java | 107 ++++++++++++------ .../debugging/SmaliDebuggerSupport.java | 7 +- .../SmaliPositionManagerFactory.java | 3 +- 3 files changed, 78 insertions(+), 39 deletions(-) diff --git a/smalidea/src/main/java/org/jf/smalidea/debugging/SmaliCodeFragmentFactory.java b/smalidea/src/main/java/org/jf/smalidea/debugging/SmaliCodeFragmentFactory.java index bb45ce96..5d0024e0 100644 --- a/smalidea/src/main/java/org/jf/smalidea/debugging/SmaliCodeFragmentFactory.java +++ b/smalidea/src/main/java/org/jf/smalidea/debugging/SmaliCodeFragmentFactory.java @@ -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,49 +229,61 @@ 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() { + VirtualMachine vm = frameProxy.getVirtualMachine().getVirtualMachine(); + Location currentLocation = frameProxy.location(); + if (currentLocation == null) { + return null; + } - @Override protected void action() throws Exception { - VirtualMachine vm = frameProxy.getVirtualMachine().getVirtualMachine(); - Method method = frameProxy.location().method(); + Method method = currentLocation.method(); - final Constructor localVariableConstructor = LocalVariableImpl.class.getDeclaredConstructor( - VirtualMachine.class, Method.class, Integer.TYPE, Location.class, Location.class, String.class, - String.class, String.class); - localVariableConstructor.setAccessible(true); + try { + final Constructor localVariableConstructor = LocalVariableImpl.class.getDeclaredConstructor( + VirtualMachine.class, Method.class, Integer.TYPE, Location.class, Location.class, String.class, + String.class, String.class); + localVariableConstructor.setAccessible(true); - Constructor locationConstructor = LocationImpl.class.getDeclaredConstructor( - VirtualMachine.class, Method.class, Long.TYPE); - locationConstructor.setAccessible(true); + Constructor locationConstructor = LocationImpl.class.getDeclaredConstructor( + VirtualMachine.class, Method.class, Long.TYPE); + locationConstructor.setAccessible(true); - // TODO: use frameProxy.location().method().locationOfCodeIndex() here - Location endLocation = locationConstructor.newInstance(vm, method, Integer.MAX_VALUE); + // TODO: use frameProxy.location().method().locationOfCodeIndex() here + Location endLocation = locationConstructor.newInstance(vm, method, Integer.MAX_VALUE); - LocalVariable localVariable = localVariableConstructor.newInstance(vm, - method, - mapRegisterForArt(smaliMethod, registerNum), - frameProxy.location().method().locationOfCodeIndex(0), - endLocation, - String.format("v%d", registerNum), type, null); + LocalVariable localVariable = localVariableConstructor.newInstance(vm, + method, + 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() { + @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; + } + }); + } } diff --git a/smalidea/src/main/java/org/jf/smalidea/debugging/SmaliDebuggerSupport.java b/smalidea/src/main/java/org/jf/smalidea/debugging/SmaliDebuggerSupport.java index a5105fee..f822fd1f 100644 --- a/smalidea/src/main/java/org/jf/smalidea/debugging/SmaliDebuggerSupport.java +++ b/smalidea/src/main/java/org/jf/smalidea/debugging/SmaliDebuggerSupport.java @@ -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; } } diff --git a/smalidea/src/main/java/org/jf/smalidea/debugging/SmaliPositionManagerFactory.java b/smalidea/src/main/java/org/jf/smalidea/debugging/SmaliPositionManagerFactory.java index 3d261096..d78b57c8 100644 --- a/smalidea/src/main/java/org/jf/smalidea/debugging/SmaliPositionManagerFactory.java +++ b/smalidea/src/main/java/org/jf/smalidea/debugging/SmaliPositionManagerFactory.java @@ -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); } }