You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
reads some values from statically-reachable memory, and
modifies the content of the same memory during the test
it can lead to non-determinism error (the Lincheck would not be able to replay the execution trace, because the content of the static memory changed).
[Above by statically-reachable memory we mean any mutable state reachable from static variables.]
Note that during the test statically-reachable memory can be modified both by
static initialization blocks (<clinit>),
and the regular functions from the test.
Thus, in order to fix possible non-determinism errors, we need to track modifications performed by <clinit> blocks, save them into trace, and manually re-perform them during replay (in the same order as in the original execution).
The text was updated successfully, but these errors were encountered:
Todo list for proper support of the static memory restoring:
Static memory snapshot collecting and restoring #418 the leaking this problem: the code below will not work with the lazy snapshot tracking, because detection of this's fields modifications in constructors is implemented incorrectly (I merely check if methodName == "<init>" && fieldOwnerClass == transformingClass then the bytecode instructions are ignored. The correct way would be to check what obj owns the modified fields. And if obj == this we should only then skip these instructions, otherwise track them. However, I don't see how that can be achieved right now, because of Bytecode verification error after instrumentation of constructors (<init> methods) because of leaking this #424
classLincheckTest {
classNode(vara:Int) {
constructor(other:Node) :this(2) { // constructor accepting the same type
other.a =0// in case if other is static variable, the change should be tracked// because `other != this` here, but in my solution it will be missed.
}
}
companionobject {
val staticNode =Node(1)
}
@Operation
funmodify() {
val localNode =Node(staticNode) // here will be a write to staticNode.a = 0, which is missed
}
}
Static memory snapshot collecting and restoring #418 in the constructor calls instrumentation there should be check for sub-classing and not the pure equals. Right now there is no obvious way of doing so during class transformation without loading the class hierarchy (which is discouraged during transformation stage).
System.arraycopy(...) this call is not considered as modification, so overridden values will not be remembered. This call is used in ArrayList::remove(...) for example. It prevents from collections lazy tracking.
referencing fields and modifiying their values via reflection
java afu objects: method calls on atomic field updators (eg. kotlinx.atomicfu.AtomicInt::getAndIncrement() it will compile to a call on java afu object which references plain int and getAndIncrement is not considered as modification)
Currently, if a Lincheck test execution both:
it can lead to non-determinism error (the Lincheck would not be able to replay the execution trace, because the content of the static memory changed).
[Above by statically-reachable memory we mean any mutable state reachable from static variables.]
Note that during the test statically-reachable memory can be modified both by
<clinit>
),Thus, in order to fix possible non-determinism errors, we need to track modifications performed by
<clinit>
blocks, save them into trace, and manually re-perform them during replay (in the same order as in the original execution).The text was updated successfully, but these errors were encountered: