Package com.mebigfatguy.fbcontrib.detect
Class LostExceptionStackTrace
- java.lang.Object
-
- edu.umd.cs.findbugs.visitclass.BetterVisitor
-
- edu.umd.cs.findbugs.visitclass.PreorderVisitor
-
- edu.umd.cs.findbugs.visitclass.AnnotationVisitor
-
- edu.umd.cs.findbugs.visitclass.DismantleBytecode
-
- edu.umd.cs.findbugs.BytecodeScanningDetector
-
- com.mebigfatguy.fbcontrib.detect.LostExceptionStackTrace
-
- All Implemented Interfaces:
edu.umd.cs.findbugs.Detector
,edu.umd.cs.findbugs.Priorities
,edu.umd.cs.findbugs.visitclass.Constants2
,org.apache.bcel.classfile.Visitor
,org.apache.bcel.Constants
@CustomUserValue public class LostExceptionStackTrace extends edu.umd.cs.findbugs.BytecodeScanningDetector
looks for methods that catch exceptions, and rethrow another exception without encapsulating the original exception within it. Doing this loses the stack history, and where the original problem occurred. This makes finding and fixing errors difficult.
-
-
Nested Class Summary
Nested Classes Modifier and Type Class Description private static class
LostExceptionStackTrace.CatchInfo
-
Field Summary
Fields Modifier and Type Field Description private static org.apache.bcel.classfile.JavaClass
assertionClass
private edu.umd.cs.findbugs.BugReporter
bugReporter
private java.util.Set<LostExceptionStackTrace.CatchInfo>
catchInfos
private org.apache.bcel.classfile.CodeException[]
exceptions
private java.util.Map<java.lang.Integer,java.lang.Boolean>
exReg
private boolean
lastWasExitPoint
private edu.umd.cs.findbugs.OpcodeStack
stack
private static org.apache.bcel.classfile.JavaClass
throwableClass
-
Fields inherited from class edu.umd.cs.findbugs.visitclass.DismantleBytecode
codeBytes, lineNumberTable, M_BR, M_CP, M_INT, M_PAD, M_R, M_UINT
-
Fields inherited from interface org.apache.bcel.Constants
AALOAD, AASTORE, ACC_ABSTRACT, ACC_ANNOTATION, ACC_BRIDGE, ACC_ENUM, ACC_FINAL, ACC_INTERFACE, ACC_NATIVE, ACC_PRIVATE, ACC_PROTECTED, ACC_PUBLIC, ACC_STATIC, ACC_STRICT, ACC_SUPER, ACC_SYNCHRONIZED, ACC_SYNTHETIC, ACC_SYPER, ACC_TRANSIENT, ACC_VARARGS, ACC_VOLATILE, ACCESS_NAMES, ACONST_NULL, ALOAD, ALOAD_0, ALOAD_1, ALOAD_2, ALOAD_3, ANEWARRAY, ANEWARRAY_QUICK, APPEND_FRAME, APPEND_FRAME_MAX, ARETURN, ARRAYLENGTH, ASTORE, ASTORE_0, ASTORE_1, ASTORE_2, ASTORE_3, ATHROW, ATTR_ANNOTATION_DEFAULT, ATTR_CODE, ATTR_CONSTANT_VALUE, ATTR_DEPRECATED, ATTR_ENCLOSING_METHOD, ATTR_EXCEPTIONS, ATTR_INNER_CLASSES, ATTR_LINE_NUMBER_TABLE, ATTR_LOCAL_VARIABLE_TABLE, ATTR_LOCAL_VARIABLE_TYPE_TABLE, ATTR_PMG, ATTR_RUNTIME_VISIBLE_ANNOTATIONS, ATTR_RUNTIME_VISIBLE_PARAMETER_ANNOTATIONS, ATTR_RUNTIMEIN_VISIBLE_ANNOTATIONS, ATTR_RUNTIMEIN_VISIBLE_PARAMETER_ANNOTATIONS, ATTR_SIGNATURE, ATTR_SOURCE_FILE, ATTR_STACK_MAP, ATTR_STACK_MAP_TABLE, ATTR_SYNTHETIC, ATTR_UNKNOWN, ATTRIBUTE_NAMES, BALOAD, BASTORE, BIPUSH, BREAKPOINT, CALOAD, CASTORE, CHECKCAST, CHECKCAST_QUICK, CHOP_FRAME, CHOP_FRAME_MAX, CLASS_TYPE_NAMES, CONSTANT_Class, CONSTANT_Double, CONSTANT_Fieldref, CONSTANT_Float, CONSTANT_Integer, CONSTANT_InterfaceMethodref, CONSTANT_InvokeDynamic, CONSTANT_Long, CONSTANT_MethodHandle, CONSTANT_Methodref, CONSTANT_MethodType, CONSTANT_NameAndType, CONSTANT_NAMES, CONSTANT_String, CONSTANT_Utf8, CONSTRUCTOR_NAME, CONSUME_STACK, D2F, D2I, D2L, DADD, DALOAD, DASTORE, DCMPG, DCMPL, DCONST_0, DCONST_1, DDIV, DLOAD, DLOAD_0, DLOAD_1, DLOAD_2, DLOAD_3, DMUL, DNEG, DREM, DRETURN, DSTORE, DSTORE_0, DSTORE_1, DSTORE_2, DSTORE_3, DSUB, DUP, DUP_X1, DUP_X2, DUP2, DUP2_X1, DUP2_X2, F2D, F2I, F2L, FADD, FALOAD, FASTORE, FCMPG, FCMPL, FCONST_0, FCONST_1, FCONST_2, FDIV, FLOAD, FLOAD_0, FLOAD_1, FLOAD_2, FLOAD_3, FMUL, FNEG, FREM, FRETURN, FSTORE, FSTORE_0, FSTORE_1, FSTORE_2, FSTORE_3, FSUB, FULL_FRAME, GETFIELD, GETFIELD_QUICK, GETFIELD_QUICK_W, GETFIELD2_QUICK, GETSTATIC, GETSTATIC_QUICK, GETSTATIC2_QUICK, GOTO, GOTO_W, I2B, I2C, I2D, I2F, I2L, I2S, IADD, IALOAD, IAND, IASTORE, ICONST_0, ICONST_1, ICONST_2, ICONST_3, ICONST_4, ICONST_5, ICONST_M1, IDIV, IF_ACMPEQ, IF_ACMPNE, IF_ICMPEQ, IF_ICMPGE, IF_ICMPGT, IF_ICMPLE, IF_ICMPLT, IF_ICMPNE, IFEQ, IFGE, IFGT, IFLE, IFLT, IFNE, IFNONNULL, IFNULL, IINC, ILLEGAL_OPCODE, ILLEGAL_TYPE, ILOAD, ILOAD_0, ILOAD_1, ILOAD_2, ILOAD_3, IMPDEP1, IMPDEP2, IMUL, INEG, INSTANCEOF, INSTANCEOF_QUICK, INT2BYTE, INT2CHAR, INT2SHORT, INTERFACES_IMPLEMENTED_BY_ARRAYS, INVOKEDYNAMIC, INVOKEINTERFACE, INVOKEINTERFACE_QUICK, INVOKENONVIRTUAL, INVOKENONVIRTUAL_QUICK, INVOKESPECIAL, INVOKESTATIC, INVOKESTATIC_QUICK, INVOKESUPER_QUICK, INVOKEVIRTUAL, INVOKEVIRTUAL_QUICK, INVOKEVIRTUAL_QUICK_W, INVOKEVIRTUALOBJECT_QUICK, IOR, IREM, IRETURN, ISHL, ISHR, ISTORE, ISTORE_0, ISTORE_1, ISTORE_2, ISTORE_3, ISUB, ITEM_Bogus, ITEM_Double, ITEM_Float, ITEM_InitObject, ITEM_Integer, ITEM_Long, ITEM_NAMES, ITEM_NewObject, ITEM_Null, ITEM_Object, IUSHR, IXOR, JSR, JSR_W, KNOWN_ATTRIBUTES, L2D, L2F, L2I, LADD, LALOAD, LAND, LASTORE, LCMP, LCONST_0, LCONST_1, LDC, LDC_QUICK, LDC_W, LDC_W_QUICK, LDC2_W, LDC2_W_QUICK, LDIV, LLOAD, LLOAD_0, LLOAD_1, LLOAD_2, LLOAD_3, LMUL, LNEG, LOOKUPSWITCH, LOR, LREM, LRETURN, LSHL, LSHR, LSTORE, LSTORE_0, LSTORE_1, LSTORE_2, LSTORE_3, LSUB, LUSHR, LXOR, MAJOR, MAJOR_1_1, MAJOR_1_2, MAJOR_1_3, MAJOR_1_4, MAJOR_1_5, MAJOR_1_6, MAJOR_1_7, MAJOR_1_8, MAX_ACC_FLAG, MAX_BYTE, MAX_CODE_SIZE, MAX_CP_ENTRIES, MAX_SHORT, MINOR, MINOR_1_1, MINOR_1_2, MINOR_1_3, MINOR_1_4, MINOR_1_5, MINOR_1_6, MINOR_1_7, MINOR_1_8, MONITORENTER, MONITOREXIT, MULTIANEWARRAY, MULTIANEWARRAY_QUICK, NEW, NEW_QUICK, NEWARRAY, NO_OF_OPERANDS, NOP, OPCODE_NAMES, POP, POP2, PRODUCE_STACK, PUSH, PUTFIELD, PUTFIELD_QUICK, PUTFIELD_QUICK_W, PUTFIELD2_QUICK, PUTSTATIC, PUTSTATIC_QUICK, PUTSTATIC2_QUICK, RESERVED, RET, RETURN, SALOAD, SAME_FRAME, SAME_FRAME_EXTENDED, SAME_FRAME_MAX, SAME_LOCALS_1_STACK_ITEM_FRAME, SAME_LOCALS_1_STACK_ITEM_FRAME_EXTENDED, SAME_LOCALS_1_STACK_ITEM_FRAME_MAX, SASTORE, SHORT_TYPE_NAMES, SIPUSH, STATIC_INITIALIZER_NAME, SWAP, SWITCH, T_ADDRESS, T_ARRAY, T_BOOLEAN, T_BYTE, T_CHAR, T_DOUBLE, T_FLOAT, T_INT, T_LONG, T_OBJECT, T_REFERENCE, T_SHORT, T_UNKNOWN, T_VOID, TABLESWITCH, TYPE_NAMES, TYPE_OF_OPERANDS, UNDEFINED, UNPREDICTABLE, WIDE
-
-
Constructor Summary
Constructors Constructor Description LostExceptionStackTrace(edu.umd.cs.findbugs.BugReporter bugReporter)
constructs a LEST detector given the reporter to report bugs on
-
Method Summary
All Methods Static Methods Instance Methods Concrete Methods Modifier and Type Method Description private void
addCatchBlock(int start, int finish)
add a catch block info record for the catch block that is guessed to be in the range of start to finishorg.apache.bcel.classfile.CodeException[]
collectExceptions(org.apache.bcel.classfile.CodeException... exs)
collects all the valid exception objects (ones where start and finish are before the targetboolean
isPossibleExBuilder(int excReg)
returns whether the method called might be a method that builds an exception using the original exception.private static boolean
isPre14Class(org.apache.bcel.classfile.JavaClass cls)
returns whether the class in question was compiled with a jdk less than 1.4boolean
prescreen(org.apache.bcel.classfile.Code code, org.apache.bcel.classfile.Method method)
looks for methods that contain a catch block and an ATHROW opcodeprivate void
removeIndeterminateHandlers(int pc)
private void
removePreviousHandlers(int pc)
void
sawOpcode(int seen)
implements the visitor to find throwing alternative exceptions from a catch block, without forwarding along the original exceptionprivate boolean
updateExceptionRegister(LostExceptionStackTrace.CatchInfo ci, int seen, int pc)
looks to update the catchinfo block with the register used for the exception variable.void
visitClassContext(edu.umd.cs.findbugs.ba.ClassContext classContext)
implements the visitor to make sure the jdk is 1.4 or bettervoid
visitCode(org.apache.bcel.classfile.Code obj)
implements the visitor to filter out methods that don't throw exceptions-
Methods inherited from class edu.umd.cs.findbugs.BytecodeScanningDetector
getClassContext, report, shouldVisitCode
-
Methods inherited from class edu.umd.cs.findbugs.visitclass.DismantleBytecode
afterOpcode, areOppositeBranches, atCatchBlock, beforeOpcode, getBranchFallThrough, getBranchOffset, getBranchTarget, getClassConstantOperand, getClassDescriptorOperand, getCodeByte, getConstantRefOperand, getDefaultSwitchOffset, getDottedClassConstantOperand, getFieldDescriptorOperand, getIntConstant, getLongConstant, getMaxPC, getMethodDescriptorOperand, getNameConstantOperand, getNextCodeByte, getNextOpcode, getNextPC, getOpcode, getPC, getPrevOpcode, getRefConstantOperand, getRefFieldIsStatic, getRegisterOperand, getSigConstantOperand, getStringConstantOperand, getSwitchLabels, getSwitchOffsets, getXClassOperand, getXFieldOperand, getXMethodOperand, isBranch, isMethodCall, isRegisterLoad, isRegisterStore, isRegisterStore, isReturn, isShift, isSwitch, isWideOpcode, printOpCode, sawBranchTo, sawClass, sawDouble, sawField, sawFloat, sawIMethod, sawInt, sawLong, sawMethod, sawRegister, sawString, visit
-
Methods inherited from class edu.umd.cs.findbugs.visitclass.AnnotationVisitor
getAnnotationParameterAsString, getAnnotationParameterAsStringArray, visitAnnotation, visitAnnotation, visitParameterAnnotation, visitParameterAnnotation, visitSyntheticParameterAnnotation
-
Methods inherited from class edu.umd.cs.findbugs.visitclass.PreorderVisitor
amVisitingMainMethod, asUnsignedByte, doVisitMethod, getClassDescriptor, getClassName, getCode, getConstantPool, getDottedClassName, getDottedFieldSig, getDottedMethodSig, getDottedSuperclassName, getField, getFieldDescriptor, getFieldIsStatic, getFieldName, getFieldSig, getFullyQualifiedFieldName, getFullyQualifiedMethodName, getMethod, getMethodDescriptor, getMethodName, getMethodSig, getMethodVisitOrder, getNumberArguments, getNumberMethodArguments, getPackageName, getSizeOfSurroundingTryBlock, getSizeOfSurroundingTryBlock, getSourceFile, getStringFromIndex, getSuperclassName, getSurroundingCaughtExceptions, getSurroundingCaughtExceptions, getSurroundingTryBlock, getSurroundingTryBlock, getThisClass, getXClass, getXField, getXMethod, hasInterestingClass, hasInterestingMethod, isVisitMethodsInCallOrder, setupVisitorForClass, setVisitMethodsInCallOrder, shouldVisit, toString, visitAfter, visitAfter, visitAnnotationDefault, visitAnnotationEntry, visitConstantPool, visitEnclosingMethod, visitingField, visitingMethod, visitInnerClasses, visitJavaClass, visitLineNumberTable, visitLocalVariableTable, visitStackMapTable, visitStackMapTableEntry
-
Methods inherited from class edu.umd.cs.findbugs.visitclass.BetterVisitor
clone, report, visit, visit, visit, visit, visit, visit, visit, visit, visit, visit, visit, visit, visit, visit, visit, visit, visit, visit, visit, visit, visit, visit, visit, visit, visit, visit, visit, visit, visit, visit, visit, visit, visit, visit, visitCodeException, visitConstantClass, visitConstantDouble, visitConstantFieldref, visitConstantFloat, visitConstantInteger, visitConstantInterfaceMethodref, visitConstantLong, visitConstantMethodref, visitConstantNameAndType, visitConstantString, visitConstantUtf8, visitConstantValue, visitDeprecated, visitExceptionTable, visitField, visitInnerClass, visitLineNumber, visitLocalVariable, visitLocalVariableTypeTable, visitMethod, visitSignature, visitSourceFile, visitStackMap, visitStackMapEntry, visitSynthetic, visitUnknown
-
-
-
-
Field Detail
-
throwableClass
private static org.apache.bcel.classfile.JavaClass throwableClass
-
assertionClass
private static org.apache.bcel.classfile.JavaClass assertionClass
-
bugReporter
private final edu.umd.cs.findbugs.BugReporter bugReporter
-
stack
private edu.umd.cs.findbugs.OpcodeStack stack
-
exceptions
private org.apache.bcel.classfile.CodeException[] exceptions
-
catchInfos
private java.util.Set<LostExceptionStackTrace.CatchInfo> catchInfos
-
exReg
private java.util.Map<java.lang.Integer,java.lang.Boolean> exReg
-
lastWasExitPoint
private boolean lastWasExitPoint
-
-
Method Detail
-
visitClassContext
public void visitClassContext(edu.umd.cs.findbugs.ba.ClassContext classContext)
implements the visitor to make sure the jdk is 1.4 or better- Specified by:
visitClassContext
in interfaceedu.umd.cs.findbugs.Detector
- Overrides:
visitClassContext
in classedu.umd.cs.findbugs.BytecodeScanningDetector
- Parameters:
classContext
- the context object of the currently parsed class
-
prescreen
public boolean prescreen(org.apache.bcel.classfile.Code code, org.apache.bcel.classfile.Method method)
looks for methods that contain a catch block and an ATHROW opcode- Parameters:
code
- the context object of the current code blockmethod
- the context object of the current method- Returns:
- if the class throws exceptions
-
visitCode
public void visitCode(org.apache.bcel.classfile.Code obj)
implements the visitor to filter out methods that don't throw exceptions- Specified by:
visitCode
in interfaceorg.apache.bcel.classfile.Visitor
- Overrides:
visitCode
in classedu.umd.cs.findbugs.visitclass.PreorderVisitor
- Parameters:
obj
- the context object of the currently parsed code block
-
collectExceptions
public org.apache.bcel.classfile.CodeException[] collectExceptions(org.apache.bcel.classfile.CodeException... exs)
collects all the valid exception objects (ones where start and finish are before the target- Parameters:
exs
- the exceptions from the class file- Returns:
- the filtered exceptions
-
sawOpcode
public void sawOpcode(int seen)
implements the visitor to find throwing alternative exceptions from a catch block, without forwarding along the original exception- Overrides:
sawOpcode
in classedu.umd.cs.findbugs.visitclass.DismantleBytecode
-
isPossibleExBuilder
public boolean isPossibleExBuilder(int excReg) throws java.lang.ClassNotFoundException
returns whether the method called might be a method that builds an exception using the original exception. It does so by looking to see if the method returns an exception, and if one of the parameters is the original exception- Parameters:
excReg
- the register of the original exception caught- Returns:
- whether this method call could be an exception builder method
- Throws:
java.lang.ClassNotFoundException
- if the class of the return type can't be found
-
isPre14Class
private static boolean isPre14Class(org.apache.bcel.classfile.JavaClass cls)
returns whether the class in question was compiled with a jdk less than 1.4- Parameters:
cls
- the class to check- Returns:
- whether the class is compiled with a jdk less than 1.4
-
removePreviousHandlers
private void removePreviousHandlers(int pc)
-
removeIndeterminateHandlers
private void removeIndeterminateHandlers(int pc)
-
updateExceptionRegister
private boolean updateExceptionRegister(LostExceptionStackTrace.CatchInfo ci, int seen, int pc)
looks to update the catchinfo block with the register used for the exception variable. If their is a local variable table, but the local variable can't be found return false, signifying an empty catch block.- Parameters:
ci
- the catchinfo record for the catch starting at this pcseen
- the opcode of the currently visited instructionpc
- the current pc- Returns:
- whether the catch block is empty
-
addCatchBlock
private void addCatchBlock(int start, int finish)
add a catch block info record for the catch block that is guessed to be in the range of start to finish- Parameters:
start
- the handler pcfinish
- the guessed end of the catch block
-
-