Commit 84b9f111 authored by Skylot's avatar Skylot

fix: improve errors handling

parent 2383c401
...@@ -329,10 +329,10 @@ public class ClassGen { ...@@ -329,10 +329,10 @@ public class ClassGen {
} }
} }
private void insertDecompilationProblems(CodeWriter code, AttrNode node) { public void insertDecompilationProblems(CodeWriter code, AttrNode node) {
List<JadxError> errors = node.getAll(AType.JADX_ERROR); List<JadxError> errors = node.getAll(AType.JADX_ERROR);
if (!errors.isEmpty()) { if (!errors.isEmpty()) {
errors.stream().sorted().forEach(err -> { errors.stream().distinct().sorted().forEach(err -> {
code.startLine("/* JADX ERROR: ").add(err.getError()); code.startLine("/* JADX ERROR: ").add(err.getError());
Throwable cause = err.getCause(); Throwable cause = err.getCause();
if (cause != null) { if (cause != null) {
......
...@@ -30,6 +30,7 @@ import jadx.core.utils.InsnUtils; ...@@ -30,6 +30,7 @@ import jadx.core.utils.InsnUtils;
import jadx.core.utils.Utils; import jadx.core.utils.Utils;
import jadx.core.utils.exceptions.CodegenException; import jadx.core.utils.exceptions.CodegenException;
import jadx.core.utils.exceptions.DecodeException; import jadx.core.utils.exceptions.DecodeException;
import jadx.core.utils.exceptions.JadxOverflowException;
public class MethodGen { public class MethodGen {
private static final Logger LOG = LoggerFactory.getLogger(MethodGen.class); private static final Logger LOG = LoggerFactory.getLogger(MethodGen.class);
...@@ -197,8 +198,18 @@ public class MethodGen { ...@@ -197,8 +198,18 @@ public class MethodGen {
.add(mth.getMethodInfo().getReturnType().toString()) .add(mth.getMethodInfo().getReturnType().toString())
.add("\");"); .add("\");");
} else { } else {
RegionGen regionGen = new RegionGen(this); try {
regionGen.makeRegion(code, mth.getRegion()); RegionGen regionGen = new RegionGen(this);
regionGen.makeRegion(code, mth.getRegion());
} catch (StackOverflowError | BootstrapMethodError e) {
mth.addError("Method code generation error", new JadxOverflowException("StackOverflow"));
classGen.insertDecompilationProblems(code, mth);
addInstructions(code);
} catch (Exception e) {
mth.addError("Method code generation error", e);
classGen.insertDecompilationProblems(code, mth);
addInstructions(code);
}
} }
} }
......
package jadx.core.dex.attributes.nodes; package jadx.core.dex.attributes.nodes;
import java.util.Objects;
import org.jetbrains.annotations.NotNull;
import jadx.core.utils.Utils; import jadx.core.utils.Utils;
public class JadxError { public class JadxError implements Comparable<JadxError> {
private final String error; private final String error;
private final Throwable cause; private final Throwable cause;
public JadxError(Throwable cause) {
this(null, cause);
}
public JadxError(String error, Throwable cause) { public JadxError(String error, Throwable cause) {
this.error = error; this.error = Objects.requireNonNull(error);
this.cause = cause; this.cause = cause;
} }
...@@ -25,6 +25,28 @@ public class JadxError { ...@@ -25,6 +25,28 @@ public class JadxError {
} }
@Override @Override
public int compareTo(@NotNull JadxError o) {
return this.error.compareTo(o.getError());
}
@Override
public boolean equals(Object o) {
if (this == o) {
return true;
}
if (o == null || getClass() != o.getClass()) {
return false;
}
JadxError other = (JadxError) o;
return error.equals(other.error);
}
@Override
public int hashCode() {
return error.hashCode();
}
@Override
public String toString() { public String toString() {
StringBuilder str = new StringBuilder(); StringBuilder str = new StringBuilder();
str.append("JadxError: "); str.append("JadxError: ");
......
...@@ -659,7 +659,7 @@ public class MethodNode extends LineAttrNode implements ILoadable, ICodeNode { ...@@ -659,7 +659,7 @@ public class MethodNode extends LineAttrNode implements ILoadable, ICodeNode {
LOG.info("{} in {}", commentStr, this); LOG.info("{} in {}", commentStr, this);
} }
public void addError(String errStr, Exception e) { public void addError(String errStr, Throwable e) {
ErrorsCounter.methodError(this, errStr, e); ErrorsCounter.methodError(this, errStr, e);
} }
...@@ -667,6 +667,20 @@ public class MethodNode extends LineAttrNode implements ILoadable, ICodeNode { ...@@ -667,6 +667,20 @@ public class MethodNode extends LineAttrNode implements ILoadable, ICodeNode {
return mthInfo; return mthInfo;
} }
/**
* Stat method.
* Calculate instructions count as a measure of method size
*/
public long countInsns() {
if (instructions != null) {
return instructions.length;
}
if (blocks != null) {
return blocks.stream().mapToLong(block -> block.getInstructions().size()).sum();
}
return -1;
}
@Override @Override
public int hashCode() { public int hashCode() {
return mthInfo.hashCode(); return mthInfo.hashCode();
......
...@@ -143,7 +143,7 @@ public class DebugInfoApplyVisitor extends AbstractVisitor { ...@@ -143,7 +143,7 @@ public class DebugInfoApplyVisitor extends AbstractVisitor {
public static void applyDebugInfo(MethodNode mth, SSAVar ssaVar, ArgType type, String varName) { public static void applyDebugInfo(MethodNode mth, SSAVar ssaVar, ArgType type, String varName) {
TypeUpdateResult result = mth.root().getTypeUpdate().applyWithWiderAllow(ssaVar, type); TypeUpdateResult result = mth.root().getTypeUpdate().applyWithWiderAllow(ssaVar, type);
if (result == TypeUpdateResult.REJECT) { if (result == TypeUpdateResult.REJECT) {
if (LOG.isDebugEnabled()) { if (Consts.DEBUG) {
LOG.debug("Reject debug info of type: {} and name: '{}' for {}, mth: {}", type, varName, ssaVar, mth); LOG.debug("Reject debug info of type: {} and name: '{}' for {}, mth: {}", type, varName, ssaVar, mth);
} }
} else { } else {
......
...@@ -232,7 +232,9 @@ public class TypeSearch { ...@@ -232,7 +232,9 @@ public class TypeSearch {
int size = candidateTypes.size(); int size = candidateTypes.size();
if (size == 0) { if (size == 0) {
throw new JadxRuntimeException("No candidate types for var: " + ssaVar.getDetailedVarInfo(mth) throw new JadxRuntimeException("No candidate types for var: " + ssaVar.getDetailedVarInfo(mth)
+ "\n assigns: " + assigns + "\n uses: " + uses); + "\n assigns: " + assigns
+ "\n uses: " + uses
+ "\n mth insns count: " + mth.countInsns());
} }
if (size == 1) { if (size == 1) {
varInfo.setTypeResolved(true); varInfo.setTypeResolved(true);
......
Markdown is supported
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