In versions 3.6, 3.6.1, 3.6.2, and 3.6.3, the C code that implements repository scan primitive 1030 methods (the scan methods that produce allObjects* and related method results as GsBitmaps) contains a timing bug, in which initialization is done before the GcLock is acquired. This may result in old lifetimes of pages being read into the cache, and corrupting the SPC; if this happens, other Gems on the cache may see page cache faults. The highest risk comes if the scan operation has to wait for the GcLock; that is, another process is holding the GcLock when the scan is requested.
In versions 3.5.x, and 3.6.x versions, the C code that implements the repository scan primitive method 896 (listObjects* and similar methods that return results as Array), contain less significant timing issue, that may potentially cause related problems.
If you see page cache faults and are using the problematic methods, restart the stone as soon as possible; this should clear the fault. In some cases, you may need to restore from backup and transaction logs to recover.
The risk is low in v3.5.x; while the code includes a potential timing hole, no problems have been reported,
In v3.6, 3.6.1, 3.6.2, or 3.6.3, using methods that invoke primitive 896 is much safer, and it is recommended to use these until it is possible to upgrade to a version in which this bug is fixed.
The problematic primitive, prim 1030, is in Repository>>_scanWithMaxThreads:witForLock:pageBUfSize:percentCpuActiveLimit:scanKind:with: The following methods ultimately use this primtive:
(If class is not mentioned: method is on class Repository)
_doScan:fast:with:
allInstances:
fastListInstances:toDirectory:
SortedCollection(class)>>findAllSortedCollectionsForUser:
listInstances:toDirectory:
listInstancesToHiddenSet:
allInstances:threads:
allObjectsInObjectSecurityPolicies:
listObjectsInSegments:
allObjectsInObjectSecurityPolicies:threds:
allObjectsLargerThan:
allObjectsLargerThan:threads:
allReferences:
listReferences:
listReferences:withLimit:
Object>>findReferencesWithLimit:
Object>>findAllReferences
Object>>findReferences
allReferences:threads:
allReferencesByParentClass:
fastAllnstances:
fastListInstancesToHiddenSet:
listInstancesToHiddenSet:withMaxThreads:maxCpuUsage:
fastAllObjectsInObjectSecurityPolicies:
fastAllObjectsLargerThan:
fastAllReferences:
fastListReferences:
fastAllReferencesByParentClass:
fastAllReferencesToInstancesOfClasses:
Primitive 896, in Repository>>_scanPomWithMaxThreads:waitForLock:pageBufSize:percentCpuActiveLimit:identSet:limit:scanKind:toDirectory:, have a much lower risk of problems. The following methods are low risk:
_listObjectsInObjectSecurityPolicies:limit:scanKind:toDirectory:
fastListObjectsInObjectSecurityPolicies:toDirectory:
fastListObjectsInObjectSecurityPolicies:withLimit:
fastListObjectsInObjectSecurityPolicies:
fastListObjectsInObjectSecurityPolicyToHiddenSet:
listObjectsInObjectSEcurityPolicies:toDirectory:
listObjectsInSegments:toDirectory:
listObjectsInObjectSecurityPolicies:withLimit:
listObjectsInObjectSecurityPolicies:
listObjectsInSegments:withLimit:
listObjectsInObjectSecurityPolicyToHiddenSet:
listObjectsInSegmentToHiddenSet:
allObjectsLargerThan:limit:
countInstances:withMaxThreads:maxCpuUsage:
countInstances:
fastCountInstances:
listInstances:limit:toDirectory:withMaxThreads:maxCpuUsage:memoryOnly:
fastListInstances:limit:
fastListInstances:
listInstances:limit:
listInstances:
Class>>allInstances
Module>>migrateInstancesTo:
listInstances:limit:toDirectory:withMaxThreads:maxCpuUsage:
listInstancesInMemory:
(Class>>allInstances)
Class>>instancesInMemory
Module>>allInstancesInMemory
Module>>migrateInstancesTo:
listInstancesInPageOrder:toFile:withMaxThreads:maxCpuUsage:
fastListInstancesInPageOrder:toFile:
listInstancesInPageOrder:toFile:
Last updated: 5/2/22