Commit 009749cf authored by Skylot's avatar Skylot

core: ignore errors in debug info parser (fix #176)

parent da94e7b1
package jadx.core.dex.visitors; package jadx.core.dex.visitors;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import jadx.core.dex.instructions.args.ArgType; import jadx.core.dex.instructions.args.ArgType;
import jadx.core.dex.instructions.args.RegisterArg; import jadx.core.dex.instructions.args.RegisterArg;
import jadx.core.dex.nodes.BlockNode; import jadx.core.dex.nodes.BlockNode;
...@@ -7,40 +10,50 @@ import jadx.core.dex.nodes.InsnNode; ...@@ -7,40 +10,50 @@ import jadx.core.dex.nodes.InsnNode;
import jadx.core.dex.nodes.MethodNode; import jadx.core.dex.nodes.MethodNode;
import jadx.core.dex.nodes.parser.DebugInfoParser; import jadx.core.dex.nodes.parser.DebugInfoParser;
import jadx.core.utils.BlockUtils; import jadx.core.utils.BlockUtils;
import jadx.core.utils.ErrorsCounter;
import jadx.core.utils.exceptions.DecodeException;
import jadx.core.utils.exceptions.JadxException; import jadx.core.utils.exceptions.JadxException;
public class DebugInfoVisitor extends AbstractVisitor { public class DebugInfoVisitor extends AbstractVisitor {
private static final Logger LOG = LoggerFactory.getLogger(DebugInfoVisitor.class);
@Override @Override
public void visit(MethodNode mth) throws JadxException { public void visit(MethodNode mth) throws JadxException {
try {
int debugOffset = mth.getDebugInfoOffset(); int debugOffset = mth.getDebugInfoOffset();
if (debugOffset > 0) { if (debugOffset > 0) {
processDebugInfo(mth, debugOffset);
}
} catch (Exception e) {
LOG.error("Error in debug info parser: " + ErrorsCounter.formatErrorMsg(mth, e.getMessage()), e);
} finally {
mth.unloadInsnArr();
}
}
private void processDebugInfo(MethodNode mth, int debugOffset) throws DecodeException {
InsnNode[] insnArr = mth.getInstructions(); InsnNode[] insnArr = mth.getInstructions();
DebugInfoParser debugInfoParser = new DebugInfoParser(mth, debugOffset, insnArr); DebugInfoParser debugInfoParser = new DebugInfoParser(mth, debugOffset, insnArr);
debugInfoParser.process(); debugInfoParser.process();
// set method source line from first instruction
if (insnArr.length != 0) { if (insnArr.length != 0) {
for (InsnNode insn : insnArr) { setMethodSourceLine(mth, insnArr);
if (insn != null) {
int line = insn.getSourceLine();
if (line != 0) {
mth.setSourceLine(line - 1);
}
break;
} }
if (!mth.getReturnType().equals(ArgType.VOID)) {
setLineForReturn(mth, insnArr);
} }
} }
if (!mth.getReturnType().equals(ArgType.VOID)) {
// fix debug info for splitter 'return' instructions /**
* Fix debug info for splitter 'return' instructions
*/
private void setLineForReturn(MethodNode mth, InsnNode[] insnArr) {
for (BlockNode exit : mth.getExitBlocks()) { for (BlockNode exit : mth.getExitBlocks()) {
InsnNode ret = BlockUtils.getLastInsn(exit); InsnNode ret = BlockUtils.getLastInsn(exit);
if (ret == null) { if (ret != null) {
continue;
}
InsnNode oldRet = insnArr[ret.getOffset()]; InsnNode oldRet = insnArr[ret.getOffset()];
if (oldRet == ret) { if (oldRet != ret) {
continue;
}
RegisterArg oldArg = (RegisterArg) oldRet.getArg(0); RegisterArg oldArg = (RegisterArg) oldRet.getArg(0);
RegisterArg newArg = (RegisterArg) ret.getArg(0); RegisterArg newArg = (RegisterArg) ret.getArg(0);
newArg.mergeDebugInfo(oldArg.getType(), oldArg.getName()); newArg.mergeDebugInfo(oldArg.getType(), oldArg.getName());
...@@ -48,6 +61,20 @@ public class DebugInfoVisitor extends AbstractVisitor { ...@@ -48,6 +61,20 @@ public class DebugInfoVisitor extends AbstractVisitor {
} }
} }
} }
mth.unloadInsnArr(); }
/**
* Set method source line from first instruction
*/
private void setMethodSourceLine(MethodNode mth, InsnNode[] insnArr) {
for (InsnNode insn : insnArr) {
if (insn != null) {
int line = insn.getSourceLine();
if (line != 0) {
mth.setSourceLine(line - 1);
}
return;
}
}
} }
} }
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