Skip to content

Commit a636bdb

Browse files
authored
Try ten times to connect to QEMU before giving up. (#176)
* Try ten times to connect to QEMU before giving up. Log QEMU command line. Detect if QEMU has exited prematurely. * Try apt update before apt install.
1 parent cd2073c commit a636bdb

File tree

2 files changed

+27
-11
lines changed

2 files changed

+27
-11
lines changed

.github/workflows/ubuntu.yml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -74,7 +74,7 @@ jobs:
7474
- name: "Install Ninja"
7575
uses: seanmiddleditch/gha-setup-ninja@v3
7676
- name: "Install QEMU system emulators"
77-
run: sudo apt install -y qemu-system
77+
run: sudo apt update && sudo apt install -y qemu-system
7878
- name: "Invoke Gradle"
7979
uses: gradle/gradle-build-action@v2
8080
with:
@@ -102,7 +102,7 @@ jobs:
102102
- name: "Install Ninja"
103103
uses: seanmiddleditch/gha-setup-ninja@v3
104104
- name: "Install QEMU system emulators"
105-
run: sudo apt install -y qemu-system
105+
run: sudo apt update && sudo apt install -y qemu-system
106106
- name: "Invoke Gradle"
107107
uses: gradle/gradle-build-action@v2
108108
with:

gradle/plugins/src/main/kotlin/multiboot.kt

Lines changed: 25 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ import java.nio.channels.FileChannel.MapMode
2020
import java.nio.file.Files
2121
import java.nio.file.Paths
2222
import java.util.concurrent.ThreadLocalRandom
23-
import java.util.concurrent.TimeUnit
23+
import java.util.concurrent.TimeUnit.MILLISECONDS
2424
import java.util.concurrent.TimeUnit.SECONDS
2525
import javax.inject.Inject
2626
import kotlin.collections.set
@@ -334,27 +334,43 @@ abstract class MultibootTestImageTask : DefaultTask()
334334
@TaskAction
335335
fun action ()
336336
{
337-
logger.info("${project.path}:${this.name}: executableFile = ${executableFile.get()}")
338-
logger.info("${project.path}:${this.name}: imageFile = ${imageFile.get()}")
339-
340337
val symbols = FileChannel.open( executableFile.asFile.get().toPath() ).use { SymbolTable.parse(it) }
341338
val control = symbols.findByName("_test_control") ?: throw RuntimeException("_test_control not found")
342339
val debug = symbols.findByName("_test_debug") ?: throw RuntimeException("_test_debug not found")
343340
val finish = symbols.findByName("_test_finish") ?: throw RuntimeException("_test_finish not found")
344341
val start = symbols.findByName("_test_start") ?: throw RuntimeException("_test_start not found")
345342

346-
val qemuProcess = ProcessBuilder()
343+
val qemuProcessBuilder = ProcessBuilder()
347344
.command( listOf(qemuExecutable.get()) + qemuArgs.build() )
348345
.redirectError( File(temporaryDir, "qemu.error.txt") )
349346
.redirectOutput( File(temporaryDir, "qemu.out.txt") )
350-
.start()
347+
logger.info("${project.path}:${this.name}: starting QEMU: ${qemuProcessBuilder.command()}")
348+
val qemuProcess = qemuProcessBuilder.start()
349+
350+
logger.info("${project.path}:${this.name}: trying to connect GdbRemote to localhost:${port}...")
351351

352-
qemuProcess.waitFor(750, TimeUnit.MILLISECONDS)
352+
var gdbRemote: GdbRemote? = null
353+
for (i in 0..10) {
354+
try {
355+
gdbRemote = GdbRemote.from(InetSocketAddress("localhost", port))
356+
break
357+
}
358+
catch (e : java.net.ConnectException) {
359+
if (qemuProcess.waitFor(100,MILLISECONDS)) {
360+
throw GradleException("QEMU exited prematurely")
361+
}
362+
}
363+
}
364+
365+
if (gdbRemote == null) {
366+
qemuProcess.destroy()
367+
qemuProcess.waitFor(1000,MILLISECONDS)
368+
throw GradleException("failed to connect to QEMU")
369+
}
353370

354371
try
355372
{
356-
GdbRemote.from( InetSocketAddress("localhost",port) ).use {
357-
gdb ->
373+
gdbRemote.use { gdb ->
358374

359375
// learn server features
360376
gdb.exchange("qSupported:hwbreak+;swbreak+;xmlRegisters+")

0 commit comments

Comments
 (0)