]> git.proxmox.com Git - qemu.git/commitdiff
Rework debug exception processing for gdb use
authorJan Kiszka <jan.kiszka@siemens.com>
Fri, 25 Jun 2010 14:56:56 +0000 (16:56 +0200)
committerAurelien Jarno <aurelien@aurel32.net>
Thu, 22 Jul 2010 03:52:09 +0000 (05:52 +0200)
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>
cpus.c
kvm-all.c

diff --git a/cpus.c b/cpus.c
index 03ebcb0c61f9d2b1af0f181aef161fcdb4186bbe..b09f5e3b508d2300f69a1c220eb495a06726c463 100644 (file)
--- a/cpus.c
+++ b/cpus.c
@@ -141,6 +141,13 @@ static int any_cpu_has_work(void)
     return 0;
 }
 
+static void cpu_debug_handler(CPUState *env)
+{
+    gdb_set_stop_cpu(env);
+    debug_requested = EXCP_DEBUG;
+    vm_stop(EXCP_DEBUG);
+}
+
 #ifndef _WIN32
 static int io_thread_fd = -1;
 
@@ -236,6 +243,8 @@ static void qemu_event_increment(void)
 #ifndef CONFIG_IOTHREAD
 int qemu_init_main_loop(void)
 {
+    cpu_set_debug_excp_handler(cpu_debug_handler);
+
     return qemu_event_init();
 }
 
@@ -326,6 +335,8 @@ int qemu_init_main_loop(void)
 {
     int ret;
 
+    cpu_set_debug_excp_handler(cpu_debug_handler);
+
     ret = qemu_event_init();
     if (ret)
         return ret;
@@ -770,8 +781,6 @@ static int qemu_cpu_exec(CPUState *env)
 
 bool cpu_exec_all(void)
 {
-    int ret = 0;
-
     if (next_cpu == NULL)
         next_cpu = first_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())
             break;
-        if (cpu_can_run(env))
-            ret = qemu_cpu_exec(env);
-        else if (env->stop)
-            break;
-
-        if (ret == EXCP_DEBUG) {
-            gdb_set_stop_cpu(env);
-            debug_requested = EXCP_DEBUG;
+        if (cpu_can_run(env)) {
+            if (qemu_cpu_exec(env) == EXCP_DEBUG) {
+                break;
+            }
+        } else if (env->stop) {
             break;
         }
     }
index 93803023004aeedfda3248a8be2f0f656d2904d5..7635f2f8948725a0d1604cdf508d808f7041e6e1 100644 (file)
--- a/kvm-all.c
+++ b/kvm-all.c
@@ -924,8 +924,6 @@ int kvm_cpu_exec(CPUState *env)
             DPRINTF("kvm_exit_debug\n");
 #ifdef KVM_CAP_SET_GUEST_DEBUG
             if (kvm_arch_debug(&run->debug.arch)) {
-                gdb_set_stop_cpu(env);
-                vm_stop(EXCP_DEBUG);
                 env->exception_index = EXCP_DEBUG;
                 return 0;
             }