From nobody Mon Apr 29 12:36:21 2024 Delivered-To: importer@patchew.org Received-SPF: temperror (zoho.com: Error in retrieving data from DNS) client-ip=208.118.235.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Authentication-Results: mx.zohomail.com; dkim=fail; spf=temperror (zoho.com: Error in retrieving data from DNS) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org Return-Path: Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) by mx.zohomail.com with SMTPS id 1511755950460883.2649372741597; Sun, 26 Nov 2017 20:12:30 -0800 (PST) Received: from localhost ([::1]:59070 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1eJAmI-00084F-GR for importer@patchew.org; Sun, 26 Nov 2017 23:12:18 -0500 Received: from eggs.gnu.org ([2001:4830:134:3::10]:37471) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1eJAlF-00075k-7U for qemu-devel@nongnu.org; Sun, 26 Nov 2017 23:11:15 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1eJAlC-0001Rz-1P for qemu-devel@nongnu.org; Sun, 26 Nov 2017 23:11:13 -0500 Received: from mail-io0-x242.google.com ([2607:f8b0:4001:c06::242]:35750) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1eJAlB-0001RC-QG for qemu-devel@nongnu.org; Sun, 26 Nov 2017 23:11:09 -0500 Received: by mail-io0-x242.google.com with SMTP id i38so34869838iod.2 for ; Sun, 26 Nov 2017 20:11:09 -0800 (PST) Received: from localhost.localdomain (172-97-211-163.cpe.distributel.net. [172.97.211.163]) by smtp.gmail.com with ESMTPSA id e139sm6847896ioe.62.2017.11.26.20.11.08 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Sun, 26 Nov 2017 20:11:08 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id; bh=jvI84tmQfzpZWV4bVu8udQG54TU/QVOFgJptwlH2xqM=; b=DokczOyqn5+HYlA3n3r/I5gkjvT3Sfo9Is3gjdWl+FnyFsbVVp0VQsyMDzzvxvRbDm VROzwE71U49py//LMFPB2laBkBD3NkBYmEd77h8x6KmtuK0IJljoHnHC5HznW6zKNKJg BwmBCTktEkwicd8poHLiLX4/mb44O7umkpC5tzfaZMAYPmpeLUf+kbf86Qq7KPJreNSi 0reBJiDVrhaCVv04LsCnbKs8l7qL/1j9ZSNlmlodZogzDFByI9cXr1wfvoLUA4kxg1Y8 11238v4JYhO6HACjXK/MbnW6Mrw6PU0PQwgZPIaajkzAzY9/SmpVlzZTb02tqx8E3QW7 iTJw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id; bh=jvI84tmQfzpZWV4bVu8udQG54TU/QVOFgJptwlH2xqM=; b=j7uEKfmmyzc5TjyHTgWPqkuBEiqik2nkEDijy6zvtM/nZ674wbcFi73Ck08UqClpbE wgZlq9NrB8mfbYtzriAbLbNL2sguNjH3aOy7Un5BuTGmNcxoG4lGkmM8wWO2E5RsAWVq xpTklW3/g7vcyTBOTyVeBQhpLx+MEHdwLY3eXACmBiNc9b3B3KNRVqCkwFWAphcquQOZ pk5Sda88AY9GYi5I5OTLXKIdC9KhxhYuCXjfYS+iK8Bn6KzeRNs8YdLcrZPAkDPrrMlK PGaWEnviuug+fn3dg09EAIpx2VJL9ijYexoLXjCllSxoMm+aBxb9lcZM4dASA5dTz89D 1hBw== X-Gm-Message-State: AJaThX4lXnfgEvSyCEfO82bE1M9wnKANo+5bT0khxtnI3Qcu/ai6jmSu aytA86jQRc/7Nd3WBZCJEPIXNdea X-Google-Smtp-Source: AGs4zMZRlbFFpWTKw90uuqm8u+qT0fXhzPgVvNrCIT7YYwQ2VF3SDJaM51Yn18FgnSMMNCF0crrk9A== X-Received: by 10.107.155.196 with SMTP id d187mr40020143ioe.220.1511755868759; Sun, 26 Nov 2017 20:11:08 -0800 (PST) From: Doug Gale To: qemu-devel@nongnu.org Date: Sun, 26 Nov 2017 23:10:38 -0500 Message-Id: <20171127041038.22819-1-doug16k@gmail.com> X-Mailer: git-send-email 2.14.1 X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 2607:f8b0:4001:c06::242 Subject: [Qemu-devel] [PATCH] gdbstub: add tracing X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Stefan Hajnoczi , Doug Gale Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZohoMail-DKIM: fail (Header signature does not verify) X-ZohoMail: RDKM_2 RSF_6 Z_629925259 SPT_0 Content-Transfer-Encoding: quoted-printable MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Signed-off-by: Doug Gale --- gdbstub.c | 100 ++++++++++++++++++++++++++++++++++++++-----------------= ---- trace-events | 21 +++++++++++++ 2 files changed, 86 insertions(+), 35 deletions(-) diff --git a/gdbstub.c b/gdbstub.c index 2a94030d3b..a75f319bd0 100644 --- a/gdbstub.c +++ b/gdbstub.c @@ -21,6 +21,7 @@ #include "qemu/error-report.h" #include "qemu/cutils.h" #include "cpu.h" +#include "trace-root.h" #ifdef CONFIG_USER_ONLY #include "qemu.h" #else @@ -287,21 +288,6 @@ static int gdb_signal_to_target (int sig) return -1; } =20 -/* #define DEBUG_GDB */ - -#ifdef DEBUG_GDB -# define DEBUG_GDB_GATE 1 -#else -# define DEBUG_GDB_GATE 0 -#endif - -#define gdb_debug(fmt, ...) do { \ - if (DEBUG_GDB_GATE) { \ - fprintf(stderr, "%s: " fmt, __func__, ## __VA_ARGS__); \ - } \ -} while (0) - - typedef struct GDBRegisterState { int base_reg; int num_regs; @@ -538,12 +524,47 @@ static void hextomem(uint8_t *mem, const char *buf, i= nt len) } } =20 +static void hexdump(const char *buf, int len, + void (*trace_fn)(size_t ofs, char const *text)) +{ + char line_buffer[3 * 16 + 4 + 16 + 1]; + + for (size_t i =3D 0; i < len || (i & 0xF); ++i) { + size_t byte_ofs =3D i & 15; + + if (byte_ofs =3D=3D 0) { + memset(line_buffer, ' ', 3 * 16 + 4 + 16); + line_buffer[3 * 16 + 4 + 16] =3D 0; + } + + size_t col_group =3D (i >> 2) & 3; + size_t hex_col =3D byte_ofs * 3 + col_group; + size_t txt_col =3D 3 * 16 + 4 + byte_ofs; + + if (i < len) { + char value =3D buf[i]; + + line_buffer[hex_col + 0] =3D tohex((value >> 4) & 0xF); + line_buffer[hex_col + 1] =3D tohex((value >> 0) & 0xF); + line_buffer[txt_col + 0] =3D (value >=3D ' ' && value < 127) + ? value + : '.'; + } + + if (byte_ofs =3D=3D 0xF) + trace_fn(i & -16, line_buffer); + } +} + /* return -1 if error, 0 if OK */ -static int put_packet_binary(GDBState *s, const char *buf, int len) +static int put_packet_binary(GDBState *s, const char *buf, int len, bool d= ump) { int csum, i; uint8_t *p; =20 + if (TRACE_GDBSTUB_IO_BINARYREPLY_ENABLED && dump) + hexdump(buf, len, trace_gdbstub_io_binaryreply); + for(;;) { p =3D s->last_packet; *(p++) =3D '$'; @@ -576,9 +597,9 @@ static int put_packet_binary(GDBState *s, const char *b= uf, int len) /* return -1 if error, 0 if OK */ static int put_packet(GDBState *s, const char *buf) { - gdb_debug("reply=3D'%s'\n", buf); + trace_gdbstub_io_reply(buf); =20 - return put_packet_binary(s, buf, strlen(buf)); + return put_packet_binary(s, buf, strlen(buf), false); } =20 /* Encode data using the encoding for 'x' packets. */ @@ -975,8 +996,7 @@ static int gdb_handle_packet(GDBState *s, const char *l= ine_buf) uint8_t *registers; target_ulong addr, len; =20 - - gdb_debug("command=3D'%s'\n", line_buf); + trace_gdbstub_io_command(line_buf); =20 p =3D line_buf; ch =3D *p++; @@ -999,7 +1019,7 @@ static int gdb_handle_packet(GDBState *s, const char *= line_buf) } s->signal =3D 0; gdb_continue(s); - return RS_IDLE; + return RS_IDLE; case 'C': s->signal =3D gdb_signal_to_target (strtoul(p, (char **)&p, 16)); if (s->signal =3D=3D -1) @@ -1045,7 +1065,7 @@ static int gdb_handle_packet(GDBState *s, const char = *line_buf) } cpu_single_step(s->c_cpu, sstep_flags); gdb_continue(s); - return RS_IDLE; + return RS_IDLE; case 'F': { target_ulong ret; @@ -1267,6 +1287,7 @@ static int gdb_handle_packet(GDBState *s, const char = *line_buf) len =3D snprintf((char *)mem_buf, sizeof(buf) / 2, "CPU#%d [%s]", cpu->cpu_index, cpu->halted ? "halted " : "running"); + trace_gdbstub_op_extra_info((char *)mem_buf); memtohex(buf, mem_buf, len); put_packet(s, buf); } @@ -1350,7 +1371,7 @@ static int gdb_handle_packet(GDBState *s, const char = *line_buf) buf[0] =3D 'l'; len =3D memtox(buf + 1, xml + addr, total_len - addr); } - put_packet_binary(s, buf, len + 1); + put_packet_binary(s, buf, len + 1, true); break; } if (is_query_packet(p, "Attached", ':')) { @@ -1407,6 +1428,8 @@ static void gdb_vm_state_change(void *opaque, int run= ning, RunState state) type =3D ""; break; } + trace_gdbstub_op_hit_watchpoint(type, cpu_gdb_index(cpu), + (target_ulong)cpu->watchpoint_hit->vaddr); snprintf(buf, sizeof(buf), "T%02xthread:%02x;%swatch:" TARGET_FMT_lx ";", GDB_SIGNAL_TRAP, cpu_gdb_index(cpu), type, @@ -1421,6 +1444,7 @@ static void gdb_vm_state_change(void *opaque, int run= ning, RunState state) ret =3D GDB_SIGNAL_INT; break; case RUN_STATE_SHUTDOWN: + trace_gdbstub_op_hit_shutdown(); ret =3D GDB_SIGNAL_QUIT; break; case RUN_STATE_IO_ERROR: @@ -1430,6 +1454,7 @@ static void gdb_vm_state_change(void *opaque, int run= ning, RunState state) ret =3D GDB_SIGNAL_ALRM; break; case RUN_STATE_INTERNAL_ERROR: + trace_gdbstub_op_hit_internal_error(); ret =3D GDB_SIGNAL_ABRT; break; case RUN_STATE_SAVE_VM: @@ -1439,6 +1464,7 @@ static void gdb_vm_state_change(void *opaque, int run= ning, RunState state) ret =3D GDB_SIGNAL_XCPU; break; default: + trace_gdbstub_op_hit_unknown(state); ret =3D GDB_SIGNAL_UNKNOWN; break; } @@ -1538,12 +1564,12 @@ static void gdb_read_byte(GDBState *s, int ch) /* Waiting for a response to the last packet. If we see the start of a new command then abandon the previous response. */ if (ch =3D=3D '-') { - gdb_debug("Got NACK, retransmitting\n"); + trace_gdbstub_err_got_nack(); put_buffer(s, (uint8_t *)s->last_packet, s->last_packet_len); } else if (ch =3D=3D '+') { - gdb_debug("Got ACK\n"); + trace_gdbstub_io_got_ack(); } else { - gdb_debug("Got '%c' when expecting ACK/NACK\n", ch); + trace_gdbstub_io_got_unexpected(ch); } =20 if (ch =3D=3D '+' || ch =3D=3D '$') @@ -1566,7 +1592,7 @@ static void gdb_read_byte(GDBState *s, int ch) s->line_sum =3D 0; s->state =3D RS_GETLINE; } else { - gdb_debug("received garbage between packets: 0x%x\n", ch); + trace_gdbstub_err_garbage((uint8_t)ch); } break; case RS_GETLINE: @@ -1582,7 +1608,7 @@ static void gdb_read_byte(GDBState *s, int ch) /* end of command, start of checksum*/ s->state =3D RS_CHKSUM1; } else if (s->line_buf_index >=3D sizeof(s->line_buf) - 1) { - gdb_debug("command buffer overrun, dropping command\n"); + trace_gdbstub_err_overrun(); s->state =3D RS_IDLE; } else { /* unescaped command character */ @@ -1596,7 +1622,7 @@ static void gdb_read_byte(GDBState *s, int ch) s->state =3D RS_CHKSUM1; } else if (s->line_buf_index >=3D sizeof(s->line_buf) - 1) { /* command buffer overrun */ - gdb_debug("command buffer overrun, dropping command\n"); + trace_gdbstub_err_overrun(); s->state =3D RS_IDLE; } else { /* parse escaped character and leave escape state */ @@ -1608,18 +1634,18 @@ static void gdb_read_byte(GDBState *s, int ch) case RS_GETLINE_RLE: if (ch < ' ') { /* invalid RLE count encoding */ - gdb_debug("got invalid RLE count: 0x%x\n", ch); + trace_gdbstub_err_invalid_repeat((uint8_t)ch); s->state =3D RS_GETLINE; } else { /* decode repeat length */ int repeat =3D (unsigned char)ch - ' ' + 3; if (s->line_buf_index + repeat >=3D sizeof(s->line_buf) - = 1) { /* that many repeats would overrun the command buffer = */ - gdb_debug("command buffer overrun, dropping command\n"= ); + trace_gdbstub_err_overrun(); s->state =3D RS_IDLE; } else if (s->line_buf_index < 1) { /* got a repeat but we have nothing to repeat */ - gdb_debug("got invalid RLE sequence\n"); + trace_gdbstub_err_invalid_rle(); s->state =3D RS_GETLINE; } else { /* repeat the last character */ @@ -1634,7 +1660,7 @@ static void gdb_read_byte(GDBState *s, int ch) case RS_CHKSUM1: /* get high hex digit of checksum */ if (!isxdigit(ch)) { - gdb_debug("got invalid command checksum digit\n"); + trace_gdbstub_invalid_checksum((uint8_t)ch); s->state =3D RS_GETLINE; break; } @@ -1645,14 +1671,14 @@ static void gdb_read_byte(GDBState *s, int ch) case RS_CHKSUM2: /* get low hex digit of checksum */ if (!isxdigit(ch)) { - gdb_debug("got invalid command checksum digit\n"); + trace_gdbstub_invalid_checksum((uint8_t)ch); s->state =3D RS_GETLINE; break; } s->line_csum |=3D fromhex(ch); =20 if (s->line_csum !=3D (s->line_sum & 0xff)) { - gdb_debug("got command packet with incorrect checksum\n"); + trace_gdbstub_incorrect_checksum(s->line_sum, s->line_csum= ); /* send NAK reply */ reply =3D '-'; put_buffer(s, &reply, 1); @@ -1686,6 +1712,8 @@ void gdb_exit(CPUArchState *env, int code) } #endif =20 + trace_gdbstub_op_exiting((uint8_t)code); + snprintf(buf, sizeof(buf), "W%02x", (uint8_t)code); put_packet(s, buf); =20 @@ -1944,6 +1972,8 @@ static const TypeInfo char_gdb_type_info =3D { =20 int gdbserver_start(const char *device) { + trace_gdbstub_op_start(device); + GDBState *s; char gdbstub_device_name[128]; Chardev *chr =3D NULL; diff --git a/trace-events b/trace-events index 1d2eb5d3e4..abf068656e 100644 --- a/trace-events +++ b/trace-events @@ -68,6 +68,27 @@ flatview_new(FlatView *view, MemoryRegion *root) "%p (ro= ot %p)" flatview_destroy(FlatView *view, MemoryRegion *root) "%p (root %p)" flatview_destroy_rcu(FlatView *view, MemoryRegion *root) "%p (root %p)" =20 +# gdbstub.c +gdbstub_op_start(char const *device) "Starting gdbstub using device %s" +gdbstub_op_exiting(uint8_t code) "notifying exit with code=3D0x%02x" +gdbstub_op_hit_watchpoint(char const *type, int cpu_gdb_index, uint64_t va= ddr) "Watchpoint hit, type=3D\"%s\" cpu=3D%d, vaddr=3D0x%" PRIx64 "" +gdbstub_op_hit_internal_error(void) "RUN_STATE_INTERNAL_ERROR" +gdbstub_op_hit_shutdown(void) "RUN_STATE_SHUTDOWN" +gdbstub_op_hit_unknown(int state) "Unknown run state=3D0x%x" +gdbstub_op_extra_info(char const *info) "Thread extra info: %s" +gdbstub_io_reply(char const *message) "Sent: %s" +gdbstub_io_binaryreply(size_t ofs, char const *line) "0x%04zx: %s" +gdbstub_io_command(char const *command) "Received: %s" +gdbstub_err_got_nack(void) "Got NACK, retransmitting" +gdbstub_io_got_ack(void) "Got ACK" +gdbstub_io_got_unexpected(char ch) "Got '%c' when expecting ACK/NACK" +gdbstub_err_garbage(char ch) "received garbage between packets: 0x%02x" +gdbstub_err_overrun(void) "command buffer overrun, dropping command" +gdbstub_err_invalid_repeat(char ch) "got invalid RLE count: 0x%02x" +gdbstub_err_invalid_rle(void) "got invalid RLE sequence" +gdbstub_invalid_checksum(char ch) "got invalid command checksum digit: 0x%= 02x" +gdbstub_incorrect_checksum(unsigned char expected, unsigned char got) "got= command packet with incorrect checksum, expected=3D0x%02x, received=3D0x%0= 2x" + ### Guest events, keep at bottom =20 =20 --=20 2.14.1