svn commit: r351238 - head/sys/gdb
Conrad Meyer
cem at FreeBSD.org
Mon Aug 19 22:57:04 UTC 2019
Author: cem
Date: Mon Aug 19 22:57:03 2019
New Revision: 351238
URL: https://svnweb.freebsd.org/changeset/base/351238
Log:
gdb(4): Pack 'info threads' responses into fewer packets
We suffer at least one round trip ACK latency every command / packet that
GDB has to send and receive, and the response format for 'info threads'
supports packing many threads IDs into a single packet, so do so.
Adds and uses a new API, gdb_txbuf_has_capacity(), which checks for a
certain number of bytes available in the outgoing txbuf.
On an example amd64 VM, the number of RTTs to transmit this list is reduced
by a factor of 110x. This is especially beneficial with recent GDB, which
seems to request the list at least twice during attach.
Modified:
head/sys/gdb/gdb_int.h
head/sys/gdb/gdb_main.c
head/sys/gdb/gdb_packet.c
Modified: head/sys/gdb/gdb_int.h
==============================================================================
--- head/sys/gdb/gdb_int.h Mon Aug 19 22:53:05 2019 (r351237)
+++ head/sys/gdb/gdb_int.h Mon Aug 19 22:57:03 2019 (r351238)
@@ -62,6 +62,7 @@ void gdb_tx_begin(char);
int gdb_tx_end(void);
int gdb_tx_mem(const unsigned char *, size_t);
void gdb_tx_reg(int);
+bool gdb_txbuf_has_capacity(size_t);
int gdb_rx_bindata(unsigned char *data, size_t datalen, size_t *amt);
int gdb_search_mem(const unsigned char *addr, size_t size,
const unsigned char *pat, size_t patlen, const unsigned char **found);
Modified: head/sys/gdb/gdb_main.c
==============================================================================
--- head/sys/gdb/gdb_main.c Mon Aug 19 22:53:05 2019 (r351237)
+++ head/sys/gdb/gdb_main.c Mon Aug 19 22:57:03 2019 (r351238)
@@ -123,6 +123,45 @@ gdb_do_mem_search(void)
gdb_tx_err(EIO);
}
+static void
+gdb_do_threadinfo(struct thread **thr_iter)
+{
+ static struct thread * const done_sentinel = (void *)(uintptr_t)1;
+ static const size_t tidsz_hex = sizeof(lwpid_t) * 2;
+ size_t tds_sent;
+
+ if (*thr_iter == NULL) {
+ gdb_tx_err(ENXIO);
+ return;
+ }
+
+ if (*thr_iter == done_sentinel) {
+ gdb_tx_begin('l');
+ *thr_iter = NULL;
+ goto sendit;
+ }
+
+ gdb_tx_begin('m');
+
+ for (tds_sent = 0;
+ *thr_iter != NULL && gdb_txbuf_has_capacity(tidsz_hex + 1);
+ *thr_iter = kdb_thr_next(*thr_iter), tds_sent++) {
+ if (tds_sent > 0)
+ gdb_tx_char(',');
+ gdb_tx_varhex((*thr_iter)->td_tid);
+ }
+
+ /*
+ * Can't send EOF and "some" in same packet, so set a sentinel to send
+ * EOF when GDB asks us next.
+ */
+ if (*thr_iter == NULL && tds_sent > 0)
+ *thr_iter = done_sentinel;
+
+sendit:
+ gdb_tx_end();
+}
+
static int
gdb_trap(int type, int code)
{
@@ -268,23 +307,9 @@ gdb_trap(int type, int code)
case 'q': /* General query. */
if (gdb_rx_equal("fThreadInfo")) {
thr_iter = kdb_thr_first();
- gdb_tx_begin('m');
- gdb_tx_hex((long)thr_iter->td_tid, 8);
- gdb_tx_end();
+ gdb_do_threadinfo(&thr_iter);
} else if (gdb_rx_equal("sThreadInfo")) {
- if (thr_iter == NULL) {
- gdb_tx_err(ENXIO);
- break;
- }
- thr_iter = kdb_thr_next(thr_iter);
- if (thr_iter != NULL) {
- gdb_tx_begin('m');
- gdb_tx_hex((long)thr_iter->td_tid, 8);
- gdb_tx_end();
- } else {
- gdb_tx_begin('l');
- gdb_tx_end();
- }
+ gdb_do_threadinfo(&thr_iter);
} else if (gdb_rx_equal("Search:memory:")) {
gdb_do_mem_search();
} else if (!gdb_cpu_query())
Modified: head/sys/gdb/gdb_packet.c
==============================================================================
--- head/sys/gdb/gdb_packet.c Mon Aug 19 22:53:05 2019 (r351237)
+++ head/sys/gdb/gdb_packet.c Mon Aug 19 22:57:03 2019 (r351238)
@@ -327,6 +327,12 @@ gdb_tx_reg(int regnum)
gdb_tx_mem(regp, regsz);
}
+bool
+gdb_txbuf_has_capacity(size_t req)
+{
+ return (((char *)gdb_txbuf + sizeof(gdb_txbuf) - gdb_txp) >= req);
+}
+
/* Read binary data up until the end of the packet or until we have datalen decoded bytes */
int
gdb_rx_bindata(unsigned char *data, size_t datalen, size_t *amt)
More information about the svn-src-all
mailing list