git: 1cbd613f3343 - main - db_pprint: Properly handle complex pointer types

From: Bojan Novković <bnovkov_at_FreeBSD.org>
Date: Sun, 21 Jul 2024 17:32:29 UTC
The branch main has been updated by bnovkov:

URL: https://cgit.FreeBSD.org/src/commit/?id=1cbd613f3343c873ace8a56df2e515626a18ef22

commit 1cbd613f3343c873ace8a56df2e515626a18ef22
Author:     Bojan Novković <bnovkov@FreeBSD.org>
AuthorDate: 2024-07-21 16:51:22 +0000
Commit:     Bojan Novković <bnovkov@FreeBSD.org>
CommitDate: 2024-07-21 17:31:59 +0000

    db_pprint: Properly handle complex pointer types
    
    The existing pretty-printing code fails to properly print complex
    pointer types. This commit fixes this behaviour by traversing the
    chain of CTF types until a base type is encountered.
    
    Approved by: markj (mentor)
    Fixes: c21bc6f3c242
---
 sys/ddb/db_pprint.c | 38 ++++++++++++++++++++++++++++++--------
 1 file changed, 30 insertions(+), 8 deletions(-)

diff --git a/sys/ddb/db_pprint.c b/sys/ddb/db_pprint.c
index 2925caedd49d..0ca2b0bb952c 100644
--- a/sys/ddb/db_pprint.c
+++ b/sys/ddb/db_pprint.c
@@ -45,6 +45,7 @@ static void db_pprint_type(db_addr_t addr, struct ctf_type_v3 *type,
 
 static u_int max_depth = DB_PPRINT_DEFAULT_DEPTH;
 static struct db_ctf_sym_data sym_data;
+static const char *asteriskstr = "*****";
 
 /*
  * Pretty-prints a CTF_INT type.
@@ -248,9 +249,14 @@ db_pprint_ptr(db_addr_t addr, struct ctf_type_v3 *type, u_int depth)
 	const char *qual = "";
 	const char *name;
 	db_addr_t val;
+	uint32_t tid;
 	u_int kind;
+	int ptrcnt;
 
-	ref_type = db_ctf_typeid_to_type(&sym_data, type->ctt_type);
+	ptrcnt = 1;
+	tid = type->ctt_type;
+again:
+	ref_type = db_ctf_typeid_to_type(&sym_data, tid);
 	kind = CTF_V3_INFO_KIND(ref_type->ctt_info);
 	switch (kind) {
 	case CTF_K_STRUCT:
@@ -258,25 +264,41 @@ db_pprint_ptr(db_addr_t addr, struct ctf_type_v3 *type, u_int depth)
 		break;
 	case CTF_K_VOLATILE:
 		qual = "volatile ";
-		break;
+		tid = ref_type->ctt_type;
+		goto again;
 	case CTF_K_CONST:
 		qual = "const ";
-		break;
+		tid = ref_type->ctt_type;
+		goto again;
+	case CTF_K_RESTRICT:
+		qual = "restrict ";
+		tid = ref_type->ctt_type;
+		goto again;
+	case CTF_K_POINTER:
+		ptrcnt++;
+		tid = ref_type->ctt_type;
+		goto again;
+	case CTF_K_TYPEDEF:
+		tid = ref_type->ctt_type;
+		goto again;
 	default:
 		break;
 	}
 
-	val = db_get_value(addr, sizeof(db_addr_t), false);
-	if (depth < max_depth) {
+	ptrcnt = min(ptrcnt, strlen(asteriskstr));
+	val = (addr != 0) ? db_get_value(addr, sizeof(db_addr_t), false) : 0;
+	if (depth < max_depth && (val != 0)) {
 		/* Print contents of memory pointed to by this pointer. */
-		db_pprint_type(addr, ref_type, depth + 1);
+		db_pprint_type(val, ref_type, depth + 1);
 	} else {
 		name = db_ctf_stroff_to_str(&sym_data, ref_type->ctt_name);
 		db_indent = depth;
 		if (name != NULL)
-			db_printf("(%s%s *) 0x%lx", qual, name, (long)val);
+			db_printf("(%s%s %.*s) 0x%lx", qual, name, ptrcnt,
+			    asteriskstr, (long)val);
 		else
-			db_printf("(%s *) 0x%lx", qual, (long)val);
+			db_printf("(%s %.*s) 0x%lx", qual, ptrcnt, asteriskstr,
+			    (long)val);
 	}
 }