Skip to content

Commit 8efc87a

Browse files
committed
Changes needed to benchmark tracing
1 parent 04a82a1 commit 8efc87a

File tree

8 files changed

+65
-25
lines changed

8 files changed

+65
-25
lines changed

src/main/kotlin/be/ugent/topl/mio/concolic/Analyse.kt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ data class SymbolicValueMapping(val primitive: String, val arg: Int, val value:
1616

1717
data class ConcolicAnalysisResult(val paths: List<SymbolicValueMapping>)
1818

19-
fun analyse(wdcliPath: String, wasmFile: String, jsonSnapshot: String, maxInstructions: Int = 50, maxSymbolicVariables: Int = -1, maxIterations: Int = -1, stopPc: Int = -1): ConcolicAnalysisResult {
19+
fun analyse(wdcliPath: String, wasmFile: String, jsonSnapshot: String, maxInstructions: Int = 50, maxSymbolicVariables: Int = -1, maxIterations: Int = -1, stopPc: Int = -1): ConcolicAnalysisResult? {
2020
val woodState = WOODState.fromLine(jsonSnapshot)
2121
val messages = woodState.toBinary(io = false, overrides = false).map { it.trim('\n', ' ') }
2222
for (msg in messages) {
@@ -47,7 +47,7 @@ fun analyse(wdcliPath: String, wasmFile: String, jsonSnapshot: String, maxInstru
4747
println(line)
4848
}
4949
println("Error occurred while running the following command: \"${command.joinToString(" ")}\"")
50-
throw Exception("Failed to get result from analysis")
50+
return null
5151
}
5252

5353
fun process(r: ConcolicAnalysisResult): MultiverseNode {

src/main/kotlin/be/ugent/topl/mio/debugger/Debugger.kt

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -19,17 +19,17 @@ open class Debugger(private val connection: Connection, start: Boolean = true, p
1919
private val requestQueue: Queue<Int> = LinkedList()
2020
var printListener: ((String) -> Unit)? = null
2121
private val messageQueue = MessageQueue {
22-
for (msg in it) {
22+
/*for (msg in it) {
2323
if (msg.startsWith("EMU: ")) {
2424
this.printListener?.invoke(msg.substring(5))
2525
}
26-
}
26+
}*/
2727
}
2828
private val readThread = thread(start) {
2929
while (!Thread.currentThread().isInterrupted) {
3030
while (connection.bytesAvailable() == 0) {
3131
try {
32-
Thread.sleep(10)
32+
Thread.sleep(5)
3333
} catch (_: InterruptedException) {
3434
Thread.currentThread().interrupt()
3535
break
@@ -38,6 +38,7 @@ open class Debugger(private val connection: Connection, start: Boolean = true, p
3838

3939
val readBuffer = ByteArray(connection.bytesAvailable())
4040
connection.read(readBuffer)
41+
//print(String(readBuffer))
4142
messageQueue.push(String(readBuffer), true)
4243

4344
while (true) {
@@ -48,16 +49,17 @@ open class Debugger(private val connection: Connection, start: Boolean = true, p
4849
if (checkpointMessage == null)
4950
break;
5051

52+
break // ignore checkpoints
5153
val payloadStr = checkpointMessage.second.groups[1]!!.value
5254

5355
try {
5456
val checkpoint = ObjectMapper().registerKotlinModule().readValue(payloadStr, Checkpoint::class.java)
5557
//println(checkpoint)
5658

5759
if (checkpoint.instructions_executed == 0 && checkpoints.size > 0) {
58-
if (checkpoint.snapshot.pc != checkpoints.last()!!.snapshot.pc) {
60+
/*if (checkpoint.snapshot.pc != checkpoints.last()!!.snapshot.pc) {
5961
throw RuntimeException("Received a checkpoint with a different pc but with 0 executed instructions since the last checkpoint!")
60-
}
62+
}*/
6163
System.err.println("WARNING: Received a checkpoint that we already have!")
6264
continue
6365
}
@@ -213,7 +215,7 @@ open class Debugger(private val connection: Connection, start: Boolean = true, p
213215
}
214216
fun stepUntil(cond: (WOODDumpResponse) -> Boolean) {
215217
stepInto()
216-
while (!cond(checkpoints.last()!!.snapshot)) {
218+
while (!cond(snapshotFull().second)) {
217219
stepInto()
218220
}
219221
}
@@ -241,6 +243,7 @@ open class Debugger(private val connection: Connection, start: Boolean = true, p
241243
}
242244

243245
fun printCheckpoints(binaryInfo: WasmInfo? = null) {
246+
return
244247
println("Checkpoints:")
245248
for (checkpoint in checkpoints) {
246249
if (checkpoint == null) {

src/main/kotlin/be/ugent/topl/mio/debugger/MultiverseDebugger.kt

Lines changed: 16 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -299,7 +299,8 @@ class MultiverseDebugger(
299299
if (graph.currentNode.children.isEmpty() && change > 0 && checkpoint?.fidx_called != null) {
300300
val newNode = if (isAfterChoicePoint(checkpoint.snapshot.pc!!)) {
301301
PrimitiveNode(wasmBinary.metadata.primitive_fidx_mapping[checkpoint.fidx_called], checkpoint.args!![0]).apply {
302-
values.add(checkpoint.snapshot.stack!!.last().value.toInt())
302+
values.add(checkpoint.returns!!.first())
303+
//values.add(checkpoint.snapshot.stack!!.last().value.toInt())
303304
}
304305
} else {
305306
DeterministicPrimitiveNode(wasmBinary.metadata.primitive_fidx_mapping[checkpoint.fidx_called], checkpoint.args!!)
@@ -315,7 +316,8 @@ class MultiverseDebugger(
315316
// Don't add new nodes if we are walking on an existing graph section.
316317
if (graph.currentNode.children.isNotEmpty()) {
317318
if (checkpoint != null && isAfterChoicePoint(checkpoint.snapshot.pc!!)) {
318-
val stackValue = checkpoint.snapshot.stack!!.last()
319+
//val stackValue = checkpoint.snapshot.stack!!.last()
320+
val stackValue = WasmStackValue(0, "", checkpoint.returns!!.first().toLong())
319321
val intValue = stackValue.value.toInt()
320322
if (graph.currentNode is PrimitiveNode) {
321323
if (!graph.currentNode.values.contains(intValue)) {
@@ -362,7 +364,13 @@ class MultiverseDebugger(
362364
return pc in wasmBinary.metadata.after_choicepoints
363365
}
364366

365-
fun predictFuture(maxInstructions: Int = 50, maxSymbolicVariables: Int = -1, maxIterations: Int = -1, stopPc: Int = -1): Boolean {
367+
enum class AnalysisOutcome {
368+
Failed,
369+
NoPaths,
370+
Success
371+
}
372+
373+
fun predictFuture(maxInstructions: Int = 50, maxSymbolicVariables: Int = -1, maxIterations: Int = -1, stopPc: Int = -1): AnalysisOutcome {
366374
val result = analyse(
367375
symbolicWdcliPath,
368376
wasmBinary.file.absolutePath,
@@ -372,16 +380,19 @@ class MultiverseDebugger(
372380
maxIterations,
373381
stopPc
374382
)
383+
if (result == null) {
384+
return AnalysisOutcome.Failed
385+
}
375386
if (result.paths.isEmpty()) {
376-
return false
387+
return AnalysisOutcome.NoPaths
377388
}
378389

379390
val concolicGraphRoot = processPaths(result.paths)
380391
// Remove current future and add newly predicted future, otherwise you will get a split timeline between the
381392
// previously predicted future and the newly predicted future.
382393
graph.replaceCurrentNode(concolicGraphRoot)
383394
graphUpdated()
384-
return true
395+
return AnalysisOutcome.Success
385396
}
386397

387398
// TODO: Remove/move/improve

src/main/kotlin/be/ugent/topl/mio/ui/GraphPanel.kt

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,7 @@ class GraphPanel(private val graph: MultiverseGraph) : JPanel(),
6262

6363
drawPaths(g, width - 100, graph.rootNode)
6464
//drawGraphNew(g)
65-
println("Height ${leafCounter.getLeafCount(graph.rootNode)}")
65+
//println("Height ${leafCounter.getLeafCount(graph.rootNode)}")
6666
}
6767

6868
val leafCounter = LeafCounter(graph)
@@ -130,6 +130,12 @@ class GraphPanel(private val graph: MultiverseGraph) : JPanel(),
130130
x += node.edgeLength
131131
}
132132

133+
/*println(associatedScrollPane?.horizontalScrollBar!!.value)
134+
if (x < associatedScrollPane?.horizontalScrollBar!!.value) {
135+
println("Cull")
136+
return Pair(Point(0, 0), 0)
137+
}*/
138+
133139
val result = drawGraph(g, currentNode, x + currentNode.edgeLength, y)
134140
renderedWidth = Integer.max(renderedWidth, x + node.edgeLength + 500)
135141
var newPoint = result.first
@@ -341,6 +347,7 @@ class GraphPanel(private val graph: MultiverseGraph) : JPanel(),
341347
val delta = Point(e.x - startPos.x, e.y - startPos.y)
342348
associatedScrollPane?.horizontalScrollBar?.value -= delta.x
343349
associatedScrollPane?.verticalScrollBar?.value -= delta.y
350+
//repaint()
344351
}
345352

346353
override fun mouseMoved(e: MouseEvent) {

src/main/kotlin/be/ugent/topl/mio/ui/InteractiveDebugger.kt

Lines changed: 18 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ class InteractiveDebugger(
4141
private val wasmFile: String = "/home/maarten/Documents/School/Thesis/thesis-git/wardbg/simple-sym-test.wasm",
4242
private val config: DebuggerConfig
4343
) : JFrame("WARDuino Debugger") {
44-
private val binaryInfo = getBinaryInfo(symbolicWdcliPath, File(wasmFile).absolutePath)
44+
private val binaryInfo = getBinaryInfo(config.wdcliPath, File(wasmFile).absolutePath)
4545
private val debugger = MultiverseDebugger(
4646
connection,
4747
WasmBinary(File(wasmFile), binaryInfo),
@@ -387,8 +387,8 @@ class InteractiveDebugger(
387387
}
388388

389389
//val snapshot = debugger.currentSnapshot!!
390-
val snapshot = debugger.checkpoints.last()!!.snapshot
391-
//val snapshot = debugger.snapshotFull().second
390+
//val snapshot = debugger.checkpoints.last()!!.snapshot
391+
val snapshot = debugger.snapshotFull().second
392392
watchWindow.update(snapshot)
393393

394394
if (sourceMapping == null)
@@ -474,6 +474,7 @@ class MultiversePanel(private val multiverseDebugger: MultiverseDebugger, config
474474
private val mockPanel = OverridesPanel()
475475
private val concolicButton = JButton("Suggest interesting paths")
476476
private var maxInstructions = 50
477+
private var maxSymbolicVars = 50
477478
private val concolicOptionsButton = JButton().apply {
478479
val gearIcon = FlatSVGIcon(MultiverseDebugger::javaClass.javaClass.getResource("/settings-gear.svg"))
479480
gearIcon.colorFilter = FlatSVGIcon.ColorFilter()
@@ -483,6 +484,9 @@ class MultiversePanel(private val multiverseDebugger: MultiverseDebugger, config
483484
JOptionPane.showInputDialog("Instruction limit", maxInstructions)?.let {
484485
maxInstructions = it.toInt()
485486
}
487+
JOptionPane.showInputDialog("Max symbolic variables", maxInstructions)?.let {
488+
maxSymbolicVars = it.toInt()
489+
}
486490
}
487491
}
488492
private val customButton = JButton("Mock").apply {
@@ -512,10 +516,15 @@ class MultiversePanel(private val multiverseDebugger: MultiverseDebugger, config
512516
concolicButton.addActionListener {
513517
val w = BlockingWindow(null, "Analysing program")
514518
w.location = Point(this.location.x + this.width/2 - w.width/2, this.location.y + this.height/2 - w.height/2)
515-
w.run({ multiverseDebugger.predictFuture(maxInstructions) }) { graphChanged ->
516-
if (!graphChanged) {
519+
w.run({
520+
multiverseDebugger.predictFuture(maxInstructions, maxSymbolicVars)
521+
}) { graphChanged ->
522+
if (graphChanged == MultiverseDebugger.AnalysisOutcome.NoPaths) {
517523
JOptionPane.showMessageDialog(this, "No future branching paths could be found")
518524
}
525+
else if (graphChanged == MultiverseDebugger.AnalysisOutcome.Failed) {
526+
JOptionPane.showMessageDialog(this, "Program analysis failed!")
527+
}
519528
}
520529
}
521530

@@ -723,6 +732,7 @@ class MultiversePanel(private val multiverseDebugger: MultiverseDebugger, config
723732
}
724733

725734
fun graphChanged() {
735+
//graphPanel.leafCounter.calculateLeafCounts()
726736
graphPanel.repaint()
727737
graphPanel.revalidate()
728738
//customButton.isEnabled = multiverseDebugger.graph.currentNode is PrimitiveNode
@@ -765,6 +775,9 @@ class WatchWindow : JTable() {
765775
fun update(snapshot: WOODDumpResponse) {
766776
tableModel.rowCount = 0
767777
tableModel.addRow(arrayOf("pc", "i32", String.format("0x%x", snapshot.pc)))
778+
if (snapshot.globals == null) {
779+
return
780+
}
768781
for (global in snapshot.globals!!) {
769782
tableModel.addRow(arrayOf("global ${global.idx}", global.type, global.value))
770783
}

src/main/kotlin/be/ugent/topl/mio/ui/LeafCounter.kt

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -11,21 +11,24 @@ class LeafCounter(private val graph: MultiverseGraph) {
1111
println("Calculating leaf counts")
1212
val time = System.currentTimeMillis()
1313
cachedHeights.clear()
14+
val completedNodes = mutableSetOf<MultiverseNode>()
1415
val stack = mutableListOf(graph.rootNode)
1516
while (stack.isNotEmpty()) {
1617
val currentNode = stack.last()
1718
if (currentNode.children.isEmpty()) {
18-
cachedHeights[currentNode] = 1
19+
//cachedHeights[currentNode] = 1
20+
completedNodes.add(currentNode)
1921
}
2022
// We already calculated the height of our children -> calculate our height!
21-
else if (cachedHeights.contains(currentNode.children.first())) {
23+
else if (completedNodes.contains(currentNode.children.first())) {
2224
var heightSum = 0
2325
for (child in currentNode.children) {
24-
heightSum += cachedHeights[child]!!
26+
heightSum += cachedHeights.getOrDefault(child, 1)
2527
}
2628
cachedHeights[currentNode] = heightSum
29+
completedNodes.add(currentNode)
2730
}
28-
if (cachedHeights.containsKey(currentNode)) {
31+
if (completedNodes.contains(currentNode)) {
2932
stack.removeLast()
3033
}
3134
stack.addAll(currentNode.children)
@@ -34,6 +37,6 @@ class LeafCounter(private val graph: MultiverseGraph) {
3437
}
3538

3639
fun getLeafCount(node: MultiverseNode): Int {
37-
return cachedHeights[node]!!
40+
return cachedHeights.getOrDefault(node, 1)
3841
}
3942
}

src/main/kotlin/be/ugent/topl/mio/woodstate/WOODState.kt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -156,6 +156,7 @@ data class Checkpoint(
156156
val instructions_executed: Int,
157157
val fidx_called: Int?,
158158
val args: List<Int>?,
159+
val returns: List<Int>?,
159160
val snapshot: WOODDumpResponse
160161
)
161162

src/test/kotlin/DebuggerTestBase.kt

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,9 @@ abstract class DebuggerTestBase {
1616
val connection = if (emulator) ProcessConnection(wdcliPath, getFile(file).path, "--no-socket") else SerialConnection(config.port ?: throw RuntimeException("Port was not configured!"))
1717
val debugger = Debugger(connection)
1818
if (!emulator) {
19-
debugger.updateModule(getFile(file).absolutePath)
19+
debugger.pause()
20+
debugger.reset()
21+
//debugger.updateModule(getFile(file).absolutePath)
2022
} else {
2123
debugger.pause()
2224
}

0 commit comments

Comments
 (0)