Skip to content

Commit 9fde094

Browse files
committed
Added removal of access$get and access$set synthetic field access trace points.
1 parent f51afaf commit 9fde094

File tree

4 files changed

+64
-4
lines changed

4 files changed

+64
-4
lines changed

src/jvm/main/org/jetbrains/kotlinx/lincheck/strategy/managed/TracePoint.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -73,7 +73,7 @@ internal class SwitchEventTracePoint(
7373
internal abstract class CodeLocationTracePoint(
7474
iThread: Int, actorId: Int,
7575
callStackTrace: CallStackTrace,
76-
val stackTraceElement: StackTraceElement
76+
var stackTraceElement: StackTraceElement
7777
) : TracePoint(iThread, actorId, callStackTrace) {
7878

7979
protected abstract fun toStringCompact(): String

src/jvm/main/org/jetbrains/kotlinx/lincheck/strategy/managed/TraceReporter.kt

Lines changed: 23 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -380,10 +380,31 @@ internal fun constructTraceGraph(
380380
return traceGraphNodesSections.map { it.first() }
381381
}
382382

383-
private fun compressTrace(trace: List<TracePoint>) =
383+
private fun compressTrace(trace: List<TracePoint>) {
384+
removeSyntheticFieldAccessTracePoints(trace)
384385
HashSet<Int>().let { removed ->
385-
trace.apply { forEach { it.callStackTrace = compressCallStackTrace(it.callStackTrace, removed) } }
386+
trace.apply { forEach { it.callStackTrace = compressCallStackTrace(it.callStackTrace, removed) } }
386387
}
388+
}
389+
390+
/**
391+
* Remove access$get and access$set, which is used when a lambda argument accesses a private field for example.
392+
* This is different from fun$access, which is addressed in [compressCallStackTrace].
393+
*/
394+
private fun removeSyntheticFieldAccessTracePoints(trace: List<TracePoint>) {
395+
trace
396+
.filter { it is ReadTracePoint || it is WriteTracePoint }
397+
.forEach { point ->
398+
val lastCall = point.callStackTrace.last()
399+
if (lastCall.tracePoint.methodName.contains("access\$get")
400+
|| lastCall.tracePoint.methodName.contains("access\$set")) {
401+
val secondLast = lastCall.tracePoint.callStackTrace.last()
402+
if (point is ReadTracePoint) point.stackTraceElement = secondLast.tracePoint.stackTraceElement
403+
if (point is WriteTracePoint) point.stackTraceElement = secondLast.tracePoint.stackTraceElement
404+
point.callStackTrace = point.callStackTrace.dropLast(1)
405+
}
406+
}
407+
}
387408

388409
/**
389410
* Merges fun$default(...) calls.

src/jvm/test/org/jetbrains/kotlinx/lincheck_test/representation/AccessFunctionRepresentationTest.kt

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,4 +37,15 @@ class AccessFunctionRepresentationTest: BaseRunConcurrentRepresentationTest<Unit
3737

3838
fun runn(r: () -> Unit) {
3939
r()
40-
}
40+
}
41+
42+
class AccessFieldRepresentationTest: BaseRunConcurrentRepresentationTest<Unit>("access_field_representation_test.txt") {
43+
44+
@Volatile
45+
private var a = 0
46+
47+
override fun block() {
48+
runn { a++ }
49+
check(false)
50+
}
51+
}
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
= Concurrent test failed =
2+
3+
java.lang.IllegalStateException: Check failed.
4+
at org.jetbrains.kotlinx.lincheck_test.representation.AccessFieldRepresentationTest.block(AccessFunctionRepresentationTest.kt:49)
5+
at org.jetbrains.kotlinx.lincheck_test.representation.AccessFieldRepresentationTest.block(AccessFunctionRepresentationTest.kt:42)
6+
at org.jetbrains.kotlinx.lincheck_test.representation.BaseRunConcurrentRepresentationTest$testRunWithModelChecker$result$1$1.invoke(RunConcurrentRepresentationTests.kt:40)
7+
at java.base/java.lang.Thread.run(Thread.java:840)
8+
9+
The following interleaving leads to the error:
10+
| --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
11+
| Thread 1 |
12+
| --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
13+
| AccessFieldRepresentationTest#1.block(): threw IllegalStateException at BaseRunConcurrentRepresentationTest$testRunWithModelChecker$result$1$1.invoke(RunConcurrentRepresentationTests.kt:40) |
14+
| --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
15+
16+
Detailed trace:
17+
| --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
18+
| Thread 1 |
19+
| --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
20+
| AccessFieldRepresentationTest#1.block(): threw IllegalStateException at BaseRunConcurrentRepresentationTest$testRunWithModelChecker$result$1$1.invoke(RunConcurrentRepresentationTests.kt:40) |
21+
| block(): threw IllegalStateException at AccessFieldRepresentationTest.block(AccessFunctionRepresentationTest.kt:42) |
22+
| AccessFunctionRepresentationTestKt.runn(block$1) at AccessFieldRepresentationTest.block(AccessFunctionRepresentationTest.kt:48) |
23+
| block$1.invoke() at AccessFunctionRepresentationTestKt.runn(AccessFunctionRepresentationTest.kt:39) |
24+
| invoke() at AccessFieldRepresentationTest$block$1.invoke(AccessFunctionRepresentationTest.kt:48) |
25+
| AccessFieldRepresentationTest#1.a ➜ 1 at AccessFieldRepresentationTest$block$1.invoke(AccessFunctionRepresentationTest.kt:48) |
26+
| AccessFieldRepresentationTest#1.a = 2 at AccessFieldRepresentationTest$block$1.invoke(AccessFunctionRepresentationTest.kt:48) |
27+
| result: IllegalStateException #1 |
28+
| --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |

0 commit comments

Comments
 (0)