Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F103017681
D28676.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
5 KB
Referenced Files
None
Subscribers
None
D28676.diff
View Options
diff --git a/share/man/man4/ddb.4 b/share/man/man4/ddb.4
--- a/share/man/man4/ddb.4
+++ b/share/man/man4/ddb.4
@@ -26,7 +26,7 @@
.\"
.\" $FreeBSD$
.\"
-.Dd January 26, 2021
+.Dd March 14, 2021
.Dt DDB 4
.Os
.Sh NAME
@@ -1571,6 +1571,19 @@
.Xr sysctl 8
.Va debug.kdb.enter
to 1.
+.Pp
+Output may be interrupted, paused, and resumed with the control
+characters CTRL-C, CTRL-S, and CTRL-Q.
+Because these control characters are received as in-band data from the
+console, there is an input buffer, and once that buffer fills
+.Nm
+must either stop responding to control characters or drop additional
+input while continuing to search for control characters.
+This behavior is controlled by the tunable
+.Xr sysctl 8
+.Va debug.ddb.prioritize_control_input ,
+which defaults to 1.
+The input buffer size is 512 bytes.
.Sh FILES
Header files mentioned in this manual page can be found below
.Pa /usr/include
diff --git a/sys/ddb/db_input.c b/sys/ddb/db_input.c
--- a/sys/ddb/db_input.c
+++ b/sys/ddb/db_input.c
@@ -36,6 +36,7 @@
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/cons.h>
+#include <sys/sysctl.h>
#include <ddb/ddb.h>
#include <ddb/db_output.h>
@@ -54,6 +55,19 @@
static char * db_lc; /* current character */
static char * db_le; /* one past last character */
+/*
+ * Raw input buffer, processed only for certain control characters.
+ */
+#define DB_RAW_SIZE 512
+static char db_raw[DB_RAW_SIZE];
+static u_int db_raw_pos;
+static u_int db_raw_cnt;
+static int db_raw_warned;
+static int ddb_prioritize_control_input = 1;
+SYSCTL_INT(_debug_ddb, OID_AUTO, prioritize_control_input, CTLFLAG_RWTUN,
+ &ddb_prioritize_control_input, 0,
+ "Drop input when the buffer fills in order to keep servicing ^C/^S/^Q");
+
/*
* Simple input line history support.
*/
@@ -65,11 +79,13 @@
#define BLANK ' '
#define BACKUP '\b'
-static int cnmaygetc(void);
static void db_delete(int n, int bwd);
static int db_inputchar(int c);
static void db_putnchars(int c, int count);
static void db_putstring(char *s, int count);
+static int db_raw_pop(void);
+static void db_raw_push(int);
+static int db_raw_space(void);
static void
db_putstring(s, count)
@@ -307,10 +323,50 @@
return (0);
}
+/* Get a character from the console, first checking the raw input buffer. */
+int
+db_getc(void)
+{
+ int c;
+
+ if (db_raw_cnt == 0) {
+ c = cngetc();
+ } else {
+ c = db_raw_pop();
+ if (c == '\r')
+ c = '\n';
+ }
+ return (c);
+}
+
+/* Whether the raw input buffer has space to accept another character. */
static int
-cnmaygetc()
+db_raw_space(void)
+{
+
+ return (db_raw_cnt < DB_RAW_SIZE);
+}
+
+/* Un-get a character from the console by buffering it. */
+static void
+db_raw_push(int c)
{
- return (-1);
+
+ if (!db_raw_space())
+ db_error(NULL);
+ db_raw[(db_raw_pos + db_raw_cnt++) % DB_RAW_SIZE] = c;
+}
+
+/* Drain a character from the raw input buffer. */
+static int
+db_raw_pop(void)
+{
+
+ if (db_raw_cnt == 0)
+ return (-1);
+ db_raw_cnt--;
+ db_raw_warned = 0;
+ return (db_raw[db_raw_pos++ % DB_RAW_SIZE]);
}
int
@@ -339,7 +395,7 @@
db_lc = lstart;
db_le = lstart;
- while (!db_inputchar(cngetc()))
+ while (!db_inputchar(db_getc()))
continue;
db_capture_write(lstart, db_le - db_lbuf_start);
@@ -361,30 +417,54 @@
return (db_le - db_lbuf_start);
}
+static void
+db_do_interrupt(const char *reason)
+{
+
+ /* Do a pager quit too because some commands have jmpbuf handling. */
+ db_disable_pager();
+ db_pager_quit = 1;
+ db_error(reason);
+}
+
void
db_check_interrupt(void)
{
int c;
- c = cnmaygetc();
- switch (c) {
- case -1: /* no character */
- return;
-
- case CTRL('c'):
- db_error((char *)0);
- /*NOTREACHED*/
-
- case CTRL('s'):
- do {
- c = cnmaygetc();
- if (c == CTRL('c'))
- db_error((char *)0);
- } while (c != CTRL('q'));
- break;
+ /*
+ * Check console input for control characters. Non-control input is
+ * buffered. When buffer space is exhausted, either stop responding to
+ * control input or drop further non-control input on the floor.
+ */
+ for (;;) {
+ if (!ddb_prioritize_control_input && !db_raw_space())
+ return;
+ c = cncheckc();
+ switch (c) {
+ case -1: /* no character */
+ return;
+
+ case CTRL('c'):
+ db_do_interrupt("^C");
+ /*NOTREACHED*/
+
+ case CTRL('s'):
+ do {
+ c = cncheckc();
+ if (c == CTRL('c'))
+ db_do_interrupt("^C");
+ } while (c != CTRL('q'));
+ break;
- default:
- /* drop on floor */
- break;
+ default:
+ if (db_raw_space()) {
+ db_raw_push(c);
+ } else if (!db_raw_warned) {
+ db_raw_warned = 1;
+ db_printf("\n--Exceeded input buffer--\n");
+ }
+ break;
+ }
}
}
diff --git a/sys/ddb/db_output.c b/sys/ddb/db_output.c
--- a/sys/ddb/db_output.c
+++ b/sys/ddb/db_output.c
@@ -260,7 +260,7 @@
db_printf("--More--\r");
done = 0;
while (!done) {
- c = cngetc();
+ c = db_getc();
switch (c) {
case 'e':
case 'j':
diff --git a/sys/ddb/ddb.h b/sys/ddb/ddb.h
--- a/sys/ddb/ddb.h
+++ b/sys/ddb/ddb.h
@@ -197,6 +197,7 @@
/* instruction disassembler */
void db_error(const char *s);
int db_expression(db_expr_t *valuep);
+int db_getc(void);
int db_get_variable(db_expr_t *valuep);
void db_iprintf(const char *,...) __printflike(1, 2);
struct proc *db_lookup_proc(db_expr_t addr);
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Wed, Nov 20, 9:22 PM (21 h, 39 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
14747573
Default Alt Text
D28676.diff (5 KB)
Attached To
Mode
D28676: ddb: enable the use of ^C and ^S/^Q
Attached
Detach File
Event Timeline
Log In to Comment