git: 088a7eef95b1 - main - ddb: add ability to print user registers

Mitchell Horne mhorne at FreeBSD.org
Fri Jan 8 18:53:53 UTC 2021


The branch main has been updated by mhorne:

URL: https://cgit.FreeBSD.org/src/commit/?id=088a7eef95b1f1919fe6eee722a57c4d4e1e0656

commit 088a7eef95b1f1919fe6eee722a57c4d4e1e0656
Author:     mhorne <mhorne at FreeBSD.org>
AuthorDate: 2020-12-18 20:06:46 +0000
Commit:     Mitchell Horne <mhorne at FreeBSD.org>
CommitDate: 2021-01-08 18:53:06 +0000

    ddb: add ability to print user registers
    
    The debugger is always entered after some kind of kernel trap, often a
    breakpoint in kdb_enter(). This means that the most recent trapframe
    will include kernel state at the time of the trap, when often it is
    desirable to the developer to view the contents of the previous
    trapframe. This trapframe often corresponds to the entry from userspace.
    
    The ddb(4) man page claims the ability to display user register state
    via the 'u' modifier to `show registers`, but this appears untrue. It is
    not obvious from a quick search of the history when this feature was
    added, or when it was removed. (Re)implement this feature in
    db_show_regs, noting that it is not necessarily populated with userspace
    state.
    
    Reviewed by:    jhb (earlier version), markj, bcr (manpages)
    MFC after:      2 weeks
    Sponsored by:   The FreeBSD Foundation
    Differential Revision:  https://reviews.freebsd.org/D27705
---
 share/man/man4/ddb.4 | 10 +++-------
 sys/ddb/db_print.c   | 24 +++++++++++++++++++++++-
 2 files changed, 26 insertions(+), 8 deletions(-)

diff --git a/share/man/man4/ddb.4 b/share/man/man4/ddb.4
index 5dab5c42a2ce..91b179e4e6fa 100644
--- a/share/man/man4/ddb.4
+++ b/share/man/man4/ddb.4
@@ -955,14 +955,10 @@ at address
 Display the register set.
 If the
 .Cm u
-modifier is specified, it displays user registers instead of
-kernel registers or the currently saved one.
+modifier is specified, the register contents of the thread's previous
+trapframe are displayed instead.
+Usually, this corresponds to the saved state from userspace.
 .Pp
-.Sy Warning :
-The support of the
-.Cm u
-modifier depends on the machine.
-If not supported, incorrect information will be displayed.
 .\"
 .Pp
 .It Ic show Cm rman Ar addr
diff --git a/sys/ddb/db_print.c b/sys/ddb/db_print.c
index 3ff0b781532d..da929457984d 100644
--- a/sys/ddb/db_print.c
+++ b/sys/ddb/db_print.c
@@ -49,12 +49,32 @@ __FBSDID("$FreeBSD$");
 #include <ddb/db_sym.h>
 
 void
-db_show_regs(db_expr_t _1, bool _2, db_expr_t _3, char *_4)
+db_show_regs(db_expr_t _1, bool _2, db_expr_t _3, char *modif)
 {
+	struct trapframe *oldtf;
 	struct db_variable *regp;
 	db_expr_t value, offset;
 	const char *name;
 
+	/*
+	 * The 'u' modifier instructs us to print the previous trapframe, most
+	 * often containing state from userspace. This is done by temporarily
+	 * switching out kdb_frame.
+	 *
+	 * NB: curthread is used instead of kdb_thread, so that behaviour is
+	 * consistent with regular `show registers`, which always prints
+	 * curthread's trapframe.
+	 */
+	oldtf = kdb_frame;
+	if (modif[0] == 'u') {
+		if (curthread->td_frame == NULL ||
+		    curthread->td_frame == oldtf) {
+			db_printf("previous trapframe unavailable");
+			return;
+		}
+		kdb_frame = curthread->td_frame;
+	}
+
 	for (regp = db_regs; regp < db_eregs; regp++) {
 		if (!db_read_variable(regp, &value))
 			continue;
@@ -70,4 +90,6 @@ db_show_regs(db_expr_t _1, bool _2, db_expr_t _3, char *_4)
 		db_printf("\n");
 	}
 	db_print_loc_and_inst(PC_REGS());
+
+	kdb_frame = oldtf;
 }


More information about the dev-commits-src-all mailing list