From patchwork Wed May 22 10:38:24 2013 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Edgar E. Iglesias" X-Patchwork-Id: 245583 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) (using TLSv1 with cipher AES256-SHA (256/256 bits)) (Client did not present a certificate) by ozlabs.org (Postfix) with ESMTPS id AFAC02C00A0 for ; Wed, 22 May 2013 20:41:08 +1000 (EST) Received: from localhost ([::1]:44125 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1Uf6Ti-0007dI-RV for incoming@patchwork.ozlabs.org; Wed, 22 May 2013 06:41:06 -0400 Received: from eggs.gnu.org ([208.118.235.92]:59553) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1Uf6T2-0007Vd-WF for qemu-devel@nongnu.org; Wed, 22 May 2013 06:40:30 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1Uf6Sx-0002Gb-Vm for qemu-devel@nongnu.org; Wed, 22 May 2013 06:40:24 -0400 Received: from mail-ee0-f47.google.com ([74.125.83.47]:40515) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1Uf6Sx-0002GL-Lr for qemu-devel@nongnu.org; Wed, 22 May 2013 06:40:19 -0400 Received: by mail-ee0-f47.google.com with SMTP id t10so1019543eei.34 for ; Wed, 22 May 2013 03:40:18 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=from:to:subject:date:message-id:x-mailer:in-reply-to:references; bh=9zlBaRGwRXI/YDvFHpv90ouW2tgqqWjrsrrWls4pAhM=; b=bfVKjZrzXu3elz5SBcc+3AZcXBUyIFcH52U1G34H8kBg6t0RithdoZKMfZtBRIBzda zhWCRhsQTEF6DbVU1mAV5NFWXUqEe4AUKFSSLnXFzrgufX6j8IXLSHpPO0NHPoHNJdbe OxPwBCeRLwW97hEjzcmeFT9BpCQD4YyUoFnBT4rIjovE7GeB1YPUlOZ/jU1JF+So4sTV uScW/ohpcXx51PcnYzOZC83sw9S7UkURpsZpi3NTgzexKB67rutx+nRd2T7J3GhPrQEE zU2z+VZUl7zo4fPulWYMK+jbEwhAyo4FywbJN4MRIIC5WEx7q7lfeEroBNnvp/BjOgU+ mExQ== X-Received: by 10.14.224.201 with SMTP id x49mr17849692eep.14.1369219218798; Wed, 22 May 2013 03:40:18 -0700 (PDT) Received: from localhost (h59ec325f.selukar.dyn.perspektivbredband.net. [89.236.50.95]) by mx.google.com with ESMTPSA id c41sm5464795eeu.8.2013.05.22.03.40.14 for (version=TLSv1.2 cipher=RC4-SHA bits=128/128); Wed, 22 May 2013 03:40:14 -0700 (PDT) From: edgar.iglesias@gmail.com To: qemu-devel@nongnu.org Date: Wed, 22 May 2013 12:38:24 +0200 Message-Id: <1369219105-9111-2-git-send-email-edgar.iglesias@gmail.com> X-Mailer: git-send-email 1.7.10.4 In-Reply-To: <1369219105-9111-1-git-send-email-edgar.iglesias@gmail.com> References: <1369219105-9111-1-git-send-email-edgar.iglesias@gmail.com> X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] [fuzzy] X-Received-From: 74.125.83.47 Subject: [Qemu-devel] [RFC 1/2] gdbstub: Add gdbserver_break() X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.14 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org From: "Edgar E. Iglesias" Makes it possible to request interruption of the GDB debug session. Signed-off-by: Edgar E. Iglesias --- gdbstub.c | 68 ++++++++++++++++++++++++++++++++++++++---------- include/exec/gdbstub.h | 2 ++ 2 files changed, 56 insertions(+), 14 deletions(-) diff --git a/gdbstub.c b/gdbstub.c index e80e1d3..84232f6 100644 --- a/gdbstub.c +++ b/gdbstub.c @@ -297,6 +297,7 @@ typedef struct GDBState { uint8_t last_packet[MAX_PACKET_LENGTH + 4]; int last_packet_len; int signal; + int client_connected; #ifdef CONFIG_USER_ONLY int fd; int running_state; @@ -2505,12 +2506,56 @@ static int gdb_handle_packet(GDBState *s, const char *line_buf) return RS_IDLE; } +static void gdb_output(GDBState *s, const char *msg, int len) +{ + char buf[MAX_PACKET_LENGTH]; + + buf[0] = 'O'; + if (len > (MAX_PACKET_LENGTH/2) - 1) { + len = (MAX_PACKET_LENGTH/2) - 1; + } + memtohex(buf + 1, (uint8_t *)msg, len); + put_packet(s, buf); +} + void gdb_set_stop_cpu(CPUArchState *env) { gdbserver_state->c_cpu = env; gdbserver_state->g_cpu = env; } +static int gdbserver_has_client(void) +{ + return gdbserver_state && gdbserver_state->client_connected; +} + +int gdbserver_break(const char *msg) +{ + + if (!gdbserver_has_client()) { + return 1; + } + + if (msg) { + gdb_output(gdbserver_state, msg, strlen(msg)); + } + + /* If there's a CPU running, break it's execution. */ + if (cpu_single_env) { + CPUState *cpu = ENV_GET_CPU(cpu_single_env); + cpu_single_env->exception_index = EXCP_DEBUG; + if (cpu->current_tb) { + /* Break out of current TB and request debug action. */ + cpu_loop_exit(cpu_single_env); + } + } +#ifndef CONFIG_USER_ONLY + /* Request global debug action. */ + qemu_system_debug_request(); +#endif + return 0; +} + #ifndef CONFIG_USER_ONLY static void gdb_vm_state_change(void *opaque, int running, RunState state) { @@ -2815,6 +2860,7 @@ gdb_handlesig (CPUArchState *env, int sig) { /* XXX: Connection closed. Should probably wait for another connection before continuing. */ + s->client_connected = false; return sig; } } @@ -2868,7 +2914,7 @@ static void gdb_accept(void) gdb_has_xml = 0; gdbserver_state = s; - + s->client_connected = true; fcntl(fd, F_SETFL, O_NONBLOCK); } @@ -2952,23 +2998,17 @@ static void gdb_chr_event(void *opaque, int event) case CHR_EVENT_OPENED: vm_stop(RUN_STATE_PAUSED); gdb_has_xml = 0; + gdbserver_state->client_connected = true; break; + case CHR_EVENT_CLOSED: { + gdbserver_state->client_connected = false; + break; + } default: break; } } -static void gdb_monitor_output(GDBState *s, const char *msg, int len) -{ - char buf[MAX_PACKET_LENGTH]; - - buf[0] = 'O'; - if (len > (MAX_PACKET_LENGTH/2) - 1) - len = (MAX_PACKET_LENGTH/2) - 1; - memtohex(buf + 1, (uint8_t *)msg, len); - put_packet(s, buf); -} - static int gdb_monitor_write(CharDriverState *chr, const uint8_t *buf, int len) { const char *p = (const char *)buf; @@ -2977,10 +3017,10 @@ static int gdb_monitor_write(CharDriverState *chr, const uint8_t *buf, int len) max_sz = (sizeof(gdbserver_state->last_packet) - 2) / 2; for (;;) { if (len <= max_sz) { - gdb_monitor_output(gdbserver_state, p, len); + gdb_output(gdbserver_state, p, len); break; } - gdb_monitor_output(gdbserver_state, p, max_sz); + gdb_output(gdbserver_state, p, max_sz); p += max_sz; len -= max_sz; } diff --git a/include/exec/gdbstub.h b/include/exec/gdbstub.h index ba20afa..6f29d2a 100644 --- a/include/exec/gdbstub.h +++ b/include/exec/gdbstub.h @@ -47,6 +47,8 @@ int gdbserver_start(int); int gdbserver_start(const char *port); #endif +int gdbserver_break(const char *msg); + /* in gdbstub-xml.c, generated by scripts/feature_to_c.sh */ extern const char *const xml_builtin[][2];