Package edu.umd.cs.findbugs.detect
Class FindImproperSynchronization
- 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
-
- edu.umd.cs.findbugs.bcel.OpcodeStackDetector
-
- edu.umd.cs.findbugs.detect.FindImproperSynchronization
-
- All Implemented Interfaces:
Detector,Priorities,org.apache.bcel.classfile.Visitor
public class FindImproperSynchronization extends OpcodeStackDetector
-
-
Nested Class Summary
Nested Classes Modifier and Type Class Description private static classFindImproperSynchronization.BugInfo-
Nested classes/interfaces inherited from class edu.umd.cs.findbugs.bcel.OpcodeStackDetector
OpcodeStackDetector.WithCustomJumpInfo
-
-
Field Summary
-
Fields inherited from class edu.umd.cs.findbugs.bcel.OpcodeStackDetector
stack
-
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 edu.umd.cs.findbugs.Priorities
EXP_PRIORITY, HIGH_PRIORITY, IGNORE_PRIORITY, LOW_PRIORITY, NORMAL_PRIORITY
-
-
Constructor Summary
Constructors Constructor Description FindImproperSynchronization(BugReporter bugReporter)
-
Method Summary
All Methods Static Methods Instance Methods Concrete Methods Modifier and Type Method Description private voidanalyzeAssignments(org.apache.bcel.classfile.Method obj, ClassContext classContext)private voidanalyzeAssignments(org.apache.bcel.classfile.Method obj, ClassContext classContext, XField specificField)private voidanalyzeAssignmentsInHierarchy(XField collectionLockObject)private voidanalyzeWrappedField(org.apache.bcel.classfile.Method currentMethod, ClassContext classContext, Location location, org.apache.bcel.generic.InstructionHandle handle, XField assignedField, java.lang.Integer stackOffsetForWrapperMethodParameter)Analyze a wrapping method call and check if this the creation of a binding collection.private java.lang.StringbuildMethodsMessage(java.util.Collection<XMethod> methods)private voidcheckLockUsageInHierarchy(XField field, XMethod exposingMethod)private voidclearState()private java.util.Set<XMethod>findExposureInHierarchy(XField lockObject)private java.util.Set<XMethod>findLockUsageInHierarchy(XField field)private static java.lang.IntegergetStackOffset(MethodDescriptor methodDescriptor)private booleanisCollection(XField field)private booleanisCollection(org.apache.bcel.generic.Type type)private static booleanisImmutableReturner(java.lang.String signature)private booleanisInherited(XField lockObject)Check if the lock object is inherited from the current class.private booleanisInitializerMethod(java.lang.String methodName)private booleanisMethodCall(org.apache.bcel.generic.Instruction instruction)private booleanisPackagePrivate(XField field)private static booleanisWrapperImplementation(MethodDescriptor methodDescriptor)private voidreportAccessibleBackingCollectionBug(XField lock, MultiMap<XField,FindImproperSynchronization.BugInfo> possibleBugs, XField backingCollection, MultiMap<XField,XMethod> collectionAccessors)private voidreportAccessibleObjectBug(XField lock, java.util.Collection<XMethod> definedLockAccessors, java.util.Map<XField,XMethod> synchronizedMethods)private voidreportBadCollectionObjectBugs(XField lock, MultiMap<XField,FindImproperSynchronization.BugInfo> possibleBugs, XField backingCollection)private voidreportExposingLockObjectBugs(XField lock, java.util.Collection<XMethod> lockUsingMethods, java.util.Collection<XMethod> exposingMethods)private voidreportInheritedBackingCollectionBug(XField lock, MultiMap<XField,FindImproperSynchronization.BugInfo> possibleBugs, XField backingCollection)private voidreportInheritedObjectBugs(XField lock, java.util.Collection<XMethod> synchronizedMethods)private voidreportObjectBugs(XField lock, java.util.Collection<XMethod> synchronizedMethods)voidsawOpcode(int seen)By default, this method will not be called when stack is TOP.voidvisit(org.apache.bcel.classfile.Field obj)voidvisit(org.apache.bcel.classfile.Method obj)voidvisitAfter(org.apache.bcel.classfile.JavaClass obj)-
Methods inherited from class edu.umd.cs.findbugs.bcel.OpcodeStackDetector
afterOpcode, beforeOpcode, getStack, isUsingCustomUserValue, visitCode
-
Methods inherited from class edu.umd.cs.findbugs.BytecodeScanningDetector
getClassContext, report, shouldVisitCode, visitClassContext
-
Methods inherited from class edu.umd.cs.findbugs.visitclass.DismantleBytecode
areOppositeBranches, atCatchBlock, getBranchFallThrough, getBranchOffset, getBranchTarget, getClassConstantOperand, getClassDescriptorOperand, getCodeByte, getConstantRefOperand, getDefaultSwitchOffset, getDottedClassConstantOperand, getFieldDescriptorOperand, getIntConstant, getLongConstant, getMaxPC, getMethodDescriptorOperand, getNameConstantOperand, getNextCodeByte, getNextOpcode, getNextPC, getOpcode, getPC, getPrevOpcode, getRefFieldIsStatic, getRegisterOperand, getSigConstantOperand, getStringConstantOperand, getSwitchLabels, getSwitchOffsets, getXClassOperand, getXFieldOperand, getXMethodOperand, isBranch, isIf, isMethodCall, isRegisterLoad, isRegisterStore, isRegisterStore, isReturn, isShift, isSwitch, isWideOpcode, normalizeNullComparison, printOpCode, sawBranchTo, sawClass, sawDouble, sawField, sawFloat, sawIMethod, sawInt, sawLong, sawMethod, sawRegister, sawString, visit
-
Methods inherited from class edu.umd.cs.findbugs.visitclass.AnnotationVisitor
getAnnotationParameterAsEnum, 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, getDottedMethodSig, getDottedSuperclassName, getField, getFieldDescriptor, getFieldIsStatic, getFieldName, getFieldSig, getFullyQualifiedFieldName, getFullyQualifiedMethodName, getMethod, getMethodDescriptor, getMethodName, getMethodSig, getMethodVisitOrder, getNumberArguments, getNumberMethodArguments, getPackageName, getSizeOfSurroundingTryBlock, getSizeOfSurroundingTryBlock, getSourceFile, getStringFromIndex, getSuperclassName, getSurroundingCaughtExceptions, getSurroundingCaughtExceptions, getSurroundingCaughtExceptionTypes, getSurroundingTryBlock, getSurroundingTryBlock, getThisClass, getXClass, getXField, getXMethod, hasInterestingClass, hasInterestingMethod, isVisitMethodsInCallOrder, setupVisitorForClass, setVisitMethodsInCallOrder, shouldVisit, toString, visitAfter, visitAnnotationDefault, visitAnnotationEntry, visitBootstrapMethods, visitConstantInvokeDynamic, visitConstantMethodHandle, visitConstantMethodType, visitConstantModule, visitConstantPackage, visitConstantPool, visitEnclosingMethod, visitingField, visitingMethod, visitInnerClasses, visitJavaClass, visitLineNumberTable, visitLocalVariableTable, visitMethodParameters, visitParameterAnnotationEntry, visitStackMap, visitStackMapEntry
-
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, visitCodeException, visitConstantClass, visitConstantDouble, visitConstantFieldref, visitConstantFloat, visitConstantInteger, visitConstantInterfaceMethodref, visitConstantLong, visitConstantMethodref, visitConstantNameAndType, visitConstantString, visitConstantUtf8, visitConstantValue, visitDeprecated, visitExceptionTable, visitField, visitInnerClass, visitLineNumber, visitLocalVariable, visitLocalVariableTypeTable, visitMethod, visitSignature, visitSourceFile, visitSynthetic, visitUnknown
-
Methods inherited from class java.lang.Object
equals, finalize, getClass, hashCode, notify, notifyAll, wait, wait, wait
-
Methods inherited from interface org.apache.bcel.classfile.Visitor
visitConstantDynamic, visitMethodParameter, visitModule, visitModuleExports, visitModuleMainClass, visitModuleOpens, visitModulePackages, visitModuleProvides, visitModuleRequires, visitNestHost, visitNestMembers, visitRecord, visitRecordComponent, visitStackMapType
-
-
-
-
Field Detail
-
WRAPPER_IMPLEMENTATIONS
private static final java.util.Map<MethodDescriptor,java.lang.Integer> WRAPPER_IMPLEMENTATIONS
-
IMMUTABLE_RETURNERS
private static final java.util.Set<java.lang.String> IMMUTABLE_RETURNERS
-
bugReporter
private final BugReporter bugReporter
-
exposingMethods
private final java.util.Set<XMethod> exposingMethods
-
synchronizedMethods
private final java.util.Set<XMethod> synchronizedMethods
-
declaredInheritedFieldAccessingMethods
private final MultiMap<XField,XMethod> declaredInheritedFieldAccessingMethods
-
potentialObjectBugContainingMethods
private final MultiMap<XField,XMethod> potentialObjectBugContainingMethods
-
potentialInheritedBugContainingMethods
private final MultiMap<XField,XMethod> potentialInheritedBugContainingMethods
-
badBackingCollections
private final java.util.Set<XField> badBackingCollections
-
inheritableBackingCollections
private final java.util.Set<XField> inheritableBackingCollections
-
declaredCollectionLockObjects
private final MultiMap<XField,FindImproperSynchronization.BugInfo> declaredCollectionLockObjects
-
inheritedCollectionLockObjects
private final MultiMap<XField,FindImproperSynchronization.BugInfo> inheritedCollectionLockObjects
-
collectionAccessorsInHierarchy
private final MultiMap<XField,XMethod> collectionAccessorsInHierarchy
-
-
Constructor Detail
-
FindImproperSynchronization
public FindImproperSynchronization(BugReporter bugReporter)
-
-
Method Detail
-
isWrapperImplementation
private static boolean isWrapperImplementation(MethodDescriptor methodDescriptor)
-
getStackOffset
private static java.lang.Integer getStackOffset(MethodDescriptor methodDescriptor)
-
isImmutableReturner
private static boolean isImmutableReturner(java.lang.String signature)
-
visit
public void visit(org.apache.bcel.classfile.Method obj)
- Overrides:
visitin classBetterVisitor
-
visit
public void visit(org.apache.bcel.classfile.Field obj)
- Overrides:
visitin classBetterVisitor
-
sawOpcode
public void sawOpcode(int seen)
Description copied from class:OpcodeStackDetectorBy default, this method will not be called when stack is TOP. To change this behavior, override
#beforeOpcode(int)and change to return true even if stack is TOP.see Using FindBugs for Research to learn lattice and what TOP means.
- Specified by:
sawOpcodein classOpcodeStackDetector- See Also:
OpcodeStackDetector.beforeOpcode(int)
-
visitAfter
public void visitAfter(org.apache.bcel.classfile.JavaClass obj)
- Overrides:
visitAfterin classPreorderVisitor
-
isCollection
private boolean isCollection(org.apache.bcel.generic.Type type)
-
isCollection
private boolean isCollection(XField field)
-
isMethodCall
private boolean isMethodCall(org.apache.bcel.generic.Instruction instruction)
-
isPackagePrivate
private boolean isPackagePrivate(XField field)
-
isInitializerMethod
private boolean isInitializerMethod(java.lang.String methodName)
-
isInherited
private boolean isInherited(XField lockObject)
Check if the lock object is inherited from the current class. To ensure no false positives, we compare only the outer class name if the lock object is contained in an inner class. Only checking equality is enough, since the lock object is a field declared in a class. That means if the declaring class of the lock object is the same as the current class, the lock object is not inherited.- Parameters:
lockObject- the lock object to check for inheritance- Returns:
- true if the lock object is inherited from the current class, false otherwise
-
analyzeWrappedField
private void analyzeWrappedField(org.apache.bcel.classfile.Method currentMethod, ClassContext classContext, Location location, org.apache.bcel.generic.InstructionHandle handle, XField assignedField, java.lang.Integer stackOffsetForWrapperMethodParameter)Analyze a wrapping method call and check if this the creation of a binding collection. There are specific methods that use their parameters to create a new collections, but they maintain a reference to the original collection. When a collection is wrapped by such a method and the result is assigned to a field, the wrapped collections becomes a backing collection.- Parameters:
currentMethod- the method in which the wrapping method call is locatedclassContext- the class context of the currently analyzed class, in which the wrapping method call is locatedlocation- the location of the wrapping method callhandle- the instruction handle of the wrapping method callassignedField- the field to which the result of the wrapping method call is assignedstackOffsetForWrapperMethodParameter- the stack offset of the wrapped collection parameter of the wrapping method call
-
analyzeAssignments
private void analyzeAssignments(org.apache.bcel.classfile.Method obj, ClassContext classContext) throws CFGBuilderException- Throws:
CFGBuilderException
-
analyzeAssignments
private void analyzeAssignments(org.apache.bcel.classfile.Method obj, ClassContext classContext, XField specificField) throws CFGBuilderException- Throws:
CFGBuilderException
-
analyzeAssignmentsInHierarchy
private void analyzeAssignmentsInHierarchy(XField collectionLockObject)
-
checkLockUsageInHierarchy
private void checkLockUsageInHierarchy(XField field, XMethod exposingMethod)
-
findExposureInHierarchy
private java.util.Set<XMethod> findExposureInHierarchy(XField lockObject) throws java.lang.ClassNotFoundException
- Throws:
java.lang.ClassNotFoundException
-
findLockUsageInHierarchy
private java.util.Set<XMethod> findLockUsageInHierarchy(XField field) throws java.lang.ClassNotFoundException
- Throws:
java.lang.ClassNotFoundException
-
buildMethodsMessage
private java.lang.String buildMethodsMessage(java.util.Collection<XMethod> methods)
-
reportExposingLockObjectBugs
private void reportExposingLockObjectBugs(XField lock, java.util.Collection<XMethod> lockUsingMethods, java.util.Collection<XMethod> exposingMethods)
-
reportAccessibleObjectBug
private void reportAccessibleObjectBug(XField lock, java.util.Collection<XMethod> definedLockAccessors, java.util.Map<XField,XMethod> synchronizedMethods)
-
reportInheritedObjectBugs
private void reportInheritedObjectBugs(XField lock, java.util.Collection<XMethod> synchronizedMethods)
-
reportObjectBugs
private void reportObjectBugs(XField lock, java.util.Collection<XMethod> synchronizedMethods)
-
reportAccessibleBackingCollectionBug
private void reportAccessibleBackingCollectionBug(XField lock, MultiMap<XField,FindImproperSynchronization.BugInfo> possibleBugs, XField backingCollection, MultiMap<XField,XMethod> collectionAccessors)
-
reportInheritedBackingCollectionBug
private void reportInheritedBackingCollectionBug(XField lock, MultiMap<XField,FindImproperSynchronization.BugInfo> possibleBugs, XField backingCollection)
-
reportBadCollectionObjectBugs
private void reportBadCollectionObjectBugs(XField lock, MultiMap<XField,FindImproperSynchronization.BugInfo> possibleBugs, XField backingCollection)
-
clearState
private void clearState()
-
-