mirror of https://gitee.com/openkylin/qemu.git
Rework debug exception processing for gdb use
Guest debugging is currently broken under CONFIG_IOTHREAD. The reason is inconsistent or even lacking signaling the debug events from the source VCPU to the main loop and the gdbstub. This patch addresses the issue by pushing this signaling into a CPUDebugExcpHandler: cpu_debug_handler is registered as first handler, thus will be executed last after potential breakpoint emulation handlers. It sets informs the gdbstub about the debug event source, requests a debug exit of the main loop and stops the current VCPU. This mechanism works both for TCG and KVM, with and without IO-thread. Signed-off-by: Jan Kiszka <jan.kiszka@siemens.com> Acked-by: Paolo Bonzini <pbonzini@redhat.com> Reviewed-by: Marcelo Tosatti <mtosatti@redhat.com> Signed-off-by: Aurelien Jarno <aurelien@aurel32.net>
This commit is contained in:
parent
472fb0c479
commit
3c638d0690
26
cpus.c
26
cpus.c
|
@ -141,6 +141,13 @@ static int any_cpu_has_work(void)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void cpu_debug_handler(CPUState *env)
|
||||||
|
{
|
||||||
|
gdb_set_stop_cpu(env);
|
||||||
|
debug_requested = EXCP_DEBUG;
|
||||||
|
vm_stop(EXCP_DEBUG);
|
||||||
|
}
|
||||||
|
|
||||||
#ifndef _WIN32
|
#ifndef _WIN32
|
||||||
static int io_thread_fd = -1;
|
static int io_thread_fd = -1;
|
||||||
|
|
||||||
|
@ -236,6 +243,8 @@ static void qemu_event_increment(void)
|
||||||
#ifndef CONFIG_IOTHREAD
|
#ifndef CONFIG_IOTHREAD
|
||||||
int qemu_init_main_loop(void)
|
int qemu_init_main_loop(void)
|
||||||
{
|
{
|
||||||
|
cpu_set_debug_excp_handler(cpu_debug_handler);
|
||||||
|
|
||||||
return qemu_event_init();
|
return qemu_event_init();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -326,6 +335,8 @@ int qemu_init_main_loop(void)
|
||||||
{
|
{
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
|
cpu_set_debug_excp_handler(cpu_debug_handler);
|
||||||
|
|
||||||
ret = qemu_event_init();
|
ret = qemu_event_init();
|
||||||
if (ret)
|
if (ret)
|
||||||
return ret;
|
return ret;
|
||||||
|
@ -770,8 +781,6 @@ static int qemu_cpu_exec(CPUState *env)
|
||||||
|
|
||||||
bool cpu_exec_all(void)
|
bool cpu_exec_all(void)
|
||||||
{
|
{
|
||||||
int ret = 0;
|
|
||||||
|
|
||||||
if (next_cpu == NULL)
|
if (next_cpu == NULL)
|
||||||
next_cpu = first_cpu;
|
next_cpu = first_cpu;
|
||||||
for (; next_cpu != NULL && !exit_request; next_cpu = next_cpu->next_cpu) {
|
for (; next_cpu != NULL && !exit_request; next_cpu = next_cpu->next_cpu) {
|
||||||
|
@ -782,14 +791,11 @@ bool cpu_exec_all(void)
|
||||||
|
|
||||||
if (qemu_alarm_pending())
|
if (qemu_alarm_pending())
|
||||||
break;
|
break;
|
||||||
if (cpu_can_run(env))
|
if (cpu_can_run(env)) {
|
||||||
ret = qemu_cpu_exec(env);
|
if (qemu_cpu_exec(env) == EXCP_DEBUG) {
|
||||||
else if (env->stop)
|
break;
|
||||||
break;
|
}
|
||||||
|
} else if (env->stop) {
|
||||||
if (ret == EXCP_DEBUG) {
|
|
||||||
gdb_set_stop_cpu(env);
|
|
||||||
debug_requested = EXCP_DEBUG;
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -924,8 +924,6 @@ int kvm_cpu_exec(CPUState *env)
|
||||||
DPRINTF("kvm_exit_debug\n");
|
DPRINTF("kvm_exit_debug\n");
|
||||||
#ifdef KVM_CAP_SET_GUEST_DEBUG
|
#ifdef KVM_CAP_SET_GUEST_DEBUG
|
||||||
if (kvm_arch_debug(&run->debug.arch)) {
|
if (kvm_arch_debug(&run->debug.arch)) {
|
||||||
gdb_set_stop_cpu(env);
|
|
||||||
vm_stop(EXCP_DEBUG);
|
|
||||||
env->exception_index = EXCP_DEBUG;
|
env->exception_index = EXCP_DEBUG;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue