On 09/11/2014 03:13 PM, Peter Maydell wrote: >> The long story: Qemu generates an exception_with_syndrome instruction >> when it realizes the instruction it's trying to translate is invalid. >> That instruction in turn modifies cs->exception_index and calls >> cpu_loop_exit. >> Normally, the value in cs->exception_index would cause do_interrupt to set >> the PC to point to the corresponding exception handler. >> However, since we're masking out IRQs, the PC will never be set correctly. >> Even worse, since Qemu will have generated an internal exception >> to return control back to the remote Gdb *after* it generated the syndrome >> one, >> its code will appear after the call to cpu_loop_exit. >> Since the PC won't have changed, we'll try to excecute >> the same translation block as before, thus calling cpu_loop_exit >> again, and so on.
This suggests that target-arm (64 or 32-bit?) isn't implementing illegal instruction traping in the way that I'd expect. In particular, I'd expect the invalid exception to be recognized, and then the cpu loop exited, before the single-step exception could overwrite it. E.g. how things work on alpha: $ cat z.s .globl _start _start: nop .long (1 << 26) nop $ alphaev67-linux-as -o z.o z.s $ alphaev67-linux-ld -Ttext-segment 0xfffffc0000100000 -o z z.o $ ./run/bin/qemu-system-alpha -kernel z -S -gdb tcp::12345 & $ alphaev67-linux-gdb ./z Set a breakpoint at _start, continue, swap over to qemu monitor and enable logging of int,op,in_asm. Now single-step a couple of times and we get: IN: 0xfffffc0000100078: nop OP: ld_i32 tmp0,env,$0xfffffffffffffffc movi_i32 tmp1,$0x0 brcond_i32 tmp0,tmp1,ne,$0x0 ---- 0xfffffc0000100078 movi_i64 pc,$0xfffffc000010007c movi_i32 tmp0,$0x10002 movi_i32 tmp1,$0x0 call excp,$0x0,$0,env,tmp0,tmp1 set_label $0x0 exit_tb $0x7f54d4fee013 Notice here that we end the single-step of the insn with a call to excp with 0x10002=EXCP_DEBUG. IN: 0xfffffc000010007c: .long 0x4000000 OP: ld_i32 tmp0,env,$0xfffffffffffffffc movi_i32 tmp1,$0x0 brcond_i32 tmp0,tmp1,ne,$0x0 ---- 0xfffffc000010007c movi_i64 pc,$0xfffffc0000100080 movi_i32 tmp0,$0x7 movi_i32 tmp1,$0x0 call excp,$0x0,$0,env,tmp0,tmp1 set_label $0x0 exit_tb $0x7f54d4fee013 Notice here that we end the single-step of the invalid insn with a call to excp with 7=EXCP_OPCDEC. We never attempt to single-step, because we know that single-step isn't going to be reachable. INT 1: opcdec(0) pc=fffffc0000100080 sp=fffffc0000010000 IN: Pal_OpcDec 0xfffffc0000000380: hw_mfpr t7,0 But gdb does in fact stop at the very next insn, which is of course the PALcode (bios) OPCDEC exception entry point. >> +#define SSTEP_EXCEPTION 0x8 /* Don't mask out exception-related >> IRQs. Set only if >> + * we have to process an exception while >> single- >> + * stepping (such as when >> single-stepping an invalid >> + * instruction). >> + */ I'm really not sure what you're doing with this, or why you'd need it. Probably target-arm wants fixing in some way, but I don't have time to look into it this evening. r~