Skip to content

Commit

Permalink
Try ten times to connect to QEMU before giving up.
Browse files Browse the repository at this point in the history
Log QEMU command line.
Detect if QEMU has exited prematurely.
  • Loading branch information
pedrolamarao committed Oct 25, 2023
1 parent cd2073c commit 7132e7a
Showing 1 changed file with 25 additions and 9 deletions.
34 changes: 25 additions & 9 deletions gradle/plugins/src/main/kotlin/multiboot.kt
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ import java.nio.channels.FileChannel.MapMode
import java.nio.file.Files
import java.nio.file.Paths
import java.util.concurrent.ThreadLocalRandom
import java.util.concurrent.TimeUnit
import java.util.concurrent.TimeUnit.MILLISECONDS
import java.util.concurrent.TimeUnit.SECONDS
import javax.inject.Inject
import kotlin.collections.set
Expand Down Expand Up @@ -334,27 +334,43 @@ abstract class MultibootTestImageTask : DefaultTask()
@TaskAction
fun action ()
{
logger.info("${project.path}:${this.name}: executableFile = ${executableFile.get()}")
logger.info("${project.path}:${this.name}: imageFile = ${imageFile.get()}")

val symbols = FileChannel.open( executableFile.asFile.get().toPath() ).use { SymbolTable.parse(it) }
val control = symbols.findByName("_test_control") ?: throw RuntimeException("_test_control not found")
val debug = symbols.findByName("_test_debug") ?: throw RuntimeException("_test_debug not found")
val finish = symbols.findByName("_test_finish") ?: throw RuntimeException("_test_finish not found")
val start = symbols.findByName("_test_start") ?: throw RuntimeException("_test_start not found")

val qemuProcess = ProcessBuilder()
val qemuProcessBuilder = ProcessBuilder()
.command( listOf(qemuExecutable.get()) + qemuArgs.build() )
.redirectError( File(temporaryDir, "qemu.error.txt") )
.redirectOutput( File(temporaryDir, "qemu.out.txt") )
.start()
logger.info("${project.path}:${this.name}: starting QEMU: ${qemuProcessBuilder.command()}")
val qemuProcess = qemuProcessBuilder.start()

logger.info("${project.path}:${this.name}: trying to connect GdbRemote to localhost:${port}...")

qemuProcess.waitFor(750, TimeUnit.MILLISECONDS)
var gdbRemote: GdbRemote? = null
for (i in 0..10) {
try {
gdbRemote = GdbRemote.from(InetSocketAddress("localhost", port))
break
}
catch (e : java.net.ConnectException) {
if (qemuProcess.waitFor(100,MILLISECONDS)) {
throw GradleException("QEMU exited prematurely")
}
}
}

if (gdbRemote == null) {
qemuProcess.destroy()
qemuProcess.waitFor(1000,MILLISECONDS)
throw GradleException("failed to connect to QEMU")
}

try
{
GdbRemote.from( InetSocketAddress("localhost",port) ).use {
gdb ->
gdbRemote.use { gdb ->

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

0 comments on commit 7132e7a

Please sign in to comment.