@@ -20,7 +20,7 @@ import java.nio.channels.FileChannel.MapMode
20
20
import java.nio.file.Files
21
21
import java.nio.file.Paths
22
22
import java.util.concurrent.ThreadLocalRandom
23
- import java.util.concurrent.TimeUnit
23
+ import java.util.concurrent.TimeUnit.MILLISECONDS
24
24
import java.util.concurrent.TimeUnit.SECONDS
25
25
import javax.inject.Inject
26
26
import kotlin.collections.set
@@ -334,27 +334,43 @@ abstract class MultibootTestImageTask : DefaultTask()
334
334
@TaskAction
335
335
fun action ()
336
336
{
337
- logger.info(" ${project.path} :${this .name} : executableFile = ${executableFile.get()} " )
338
- logger.info(" ${project.path} :${this .name} : imageFile = ${imageFile.get()} " )
339
-
340
337
val symbols = FileChannel .open( executableFile.asFile.get().toPath() ).use { SymbolTable .parse(it) }
341
338
val control = symbols.findByName(" _test_control" ) ? : throw RuntimeException (" _test_control not found" )
342
339
val debug = symbols.findByName(" _test_debug" ) ? : throw RuntimeException (" _test_debug not found" )
343
340
val finish = symbols.findByName(" _test_finish" ) ? : throw RuntimeException (" _test_finish not found" )
344
341
val start = symbols.findByName(" _test_start" ) ? : throw RuntimeException (" _test_start not found" )
345
342
346
- val qemuProcess = ProcessBuilder ()
343
+ val qemuProcessBuilder = ProcessBuilder ()
347
344
.command( listOf (qemuExecutable.get()) + qemuArgs.build() )
348
345
.redirectError( File (temporaryDir, " qemu.error.txt" ) )
349
346
.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} ..." )
351
351
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
+ }
353
370
354
371
try
355
372
{
356
- GdbRemote .from( InetSocketAddress (" localhost" ,port) ).use {
357
- gdb ->
373
+ gdbRemote.use { gdb ->
358
374
359
375
// learn server features
360
376
gdb.exchange(" qSupported:hwbreak+;swbreak+;xmlRegisters+" )
0 commit comments