PERFORCE change 137185 for review

John Birrell jb at FreeBSD.org
Sat Mar 8 19:58:02 UTC 2008


http://perforce.freebsd.org/chv.cgi?CH=137185

Change 137185 by jb at jb_freebsd8 on 2008/03/08 19:57:26

	Add the code to print the type with struct/union field info a bit like
	a debugger would.

Affected files ...

.. //depot/projects/dtrace/src/contrib/opensolaris/lib/libdtrace/common/dt_consume.c#15 edit

Differences ...

==== //depot/projects/dtrace/src/contrib/opensolaris/lib/libdtrace/common/dt_consume.c#15 (text) ====

@@ -810,14 +810,240 @@
 	    nbytes, 50, quiet, 1));
 }
 
-int
+typedef struct dt_type_cbdata {
+	dtrace_hdl_t		*dtp;
+	dtrace_typeinfo_t	dtt;
+	caddr_t			addr;
+	caddr_t			addrend;
+	const char		*name;
+	int			f_type;
+	int			indent;
+	int			type_width;
+	int			name_width;
+	FILE			*fp;
+} dt_type_cbdata_t;
+
+static int	dt_print_type_data(dt_type_cbdata_t *, ctf_id_t);
+
+static int
+dt_print_type_member(const char *name, ctf_id_t type, ulong_t off, void *arg)
+{
+	dt_type_cbdata_t cbdata;
+	dt_type_cbdata_t *cbdatap = arg;
+	ssize_t ssz;
+
+	if ((ssz = ctf_type_size(cbdatap->dtt.dtt_ctfp, type)) <= 0)
+		return (0);
+
+	off /= 8;
+
+	cbdata = *cbdatap;
+	cbdata.name = name;
+	cbdata.addr += off;
+	cbdata.addrend = cbdata.addr + ssz;
+
+	return (dt_print_type_data(&cbdata, type));
+}
+
+static int
+dt_print_type_width(const char *name, ctf_id_t type, ulong_t off, void *arg)
+{
+	char buf[DT_TYPE_NAMELEN];
+	char *p;
+	dt_type_cbdata_t *cbdatap = arg;
+	size_t sz = strlen(name);
+
+	ctf_type_name(cbdatap->dtt.dtt_ctfp, type, buf, sizeof (buf));
+
+	if ((p = strchr(buf, '[')) != NULL)
+		p[-1] = '\0';
+	else
+		p = "";
+
+	sz += strlen(p);
+
+	if (sz > cbdatap->name_width)
+		cbdatap->name_width = sz;
+
+	sz = strlen(buf);
+
+	if (sz > cbdatap->type_width)
+		cbdatap->type_width = sz;
+
+	return (0);
+}
+
+static int
+dt_print_type_data(dt_type_cbdata_t *cbdatap, ctf_id_t type)
+{
+	caddr_t addr = cbdatap->addr;
+	caddr_t addrend = cbdatap->addrend;
+	char buf[DT_TYPE_NAMELEN];
+	char *p;
+	int cnt = 0;
+	uint_t kind = ctf_type_kind(cbdatap->dtt.dtt_ctfp, type);
+	ssize_t ssz = ctf_type_size(cbdatap->dtt.dtt_ctfp, type);
+
+	ctf_type_name(cbdatap->dtt.dtt_ctfp, type, buf, sizeof (buf));
+
+	if ((p = strchr(buf, '[')) != NULL)
+		p[-1] = '\0';
+	else
+		p = "";
+
+	if (cbdatap->f_type) {
+		int type_width = roundup(cbdatap->type_width + 1, 4);
+		int name_width = roundup(cbdatap->name_width + 1, 4);
+
+		name_width -= strlen(cbdatap->name);
+
+		dt_printf(cbdatap->dtp, cbdatap->fp, "%*s%-*s%s%-*s	= ",cbdatap->indent * 4,"",type_width,buf,cbdatap->name,name_width,p);
+	}
+
+	while (addr < addrend) {
+		dt_type_cbdata_t cbdata;
+		ctf_arinfo_t arinfo;
+		ctf_encoding_t cte;
+		void *vp = addr;
+		cbdata = *cbdatap;
+		cbdata.name = "";
+		cbdata.addr = addr;
+		cbdata.addrend = addr + ssz;
+		cbdata.f_type = 0;
+		cbdata.indent++;
+		cbdata.type_width = 0;
+		cbdata.name_width = 0;
+
+		if (cnt > 0)
+			dt_printf(cbdatap->dtp, cbdatap->fp, "%*s", cbdatap->indent * 4,"");
+
+		switch (kind) {
+		case CTF_K_INTEGER:
+			if (ctf_type_encoding(cbdatap->dtt.dtt_ctfp, type, &cte) != 0)
+				return (-1);
+			if ((cte.cte_format & CTF_INT_SIGNED) != 0)
+				switch (cte.cte_bits) {
+				case 8:
+					if (isprint(*((char *) vp)))
+						dt_printf(cbdatap->dtp, cbdatap->fp, "'%c', ", *((char *) vp));
+					dt_printf(cbdatap->dtp, cbdatap->fp, "%d (0x%x);\n", *((char *) vp), *((char *) vp));
+					break;
+				case 16:
+					dt_printf(cbdatap->dtp, cbdatap->fp, "%hd (0x%hx);\n", *((short *) vp), *((u_short *) vp));
+					break;
+				case 32:
+					dt_printf(cbdatap->dtp, cbdatap->fp, "%d (0x%x);\n", *((int *) vp), *((u_int *) vp));
+					break;
+				case 64:
+					dt_printf(cbdatap->dtp, cbdatap->fp, "%jd (0x%jx);\n", *((long long *) vp), *((unsigned long long *) vp));
+					break;
+				default:
+					dt_printf(cbdatap->dtp, cbdatap->fp, "CTF_K_INTEGER: format %x offset %u bits %u\n",cte.cte_format,cte.cte_offset,cte.cte_bits);
+					break;
+				}
+			else
+				switch (cte.cte_bits) {
+				case 8:
+					dt_printf(cbdatap->dtp, cbdatap->fp, "%u (0x%x);\n", *((uint8_t *) vp) & 0xff, *((uint8_t *) vp) & 0xff);
+					break;
+				case 16:
+					dt_printf(cbdatap->dtp, cbdatap->fp, "%hu (0x%hx);\n", *((u_short *) vp), *((u_short *) vp));
+					break;
+				case 32:
+					dt_printf(cbdatap->dtp, cbdatap->fp, "%u (0x%x);\n", *((u_int *) vp), *((u_int *) vp));
+					break;
+				case 64:
+					dt_printf(cbdatap->dtp, cbdatap->fp, "%ju (0x%jx);\n", *((unsigned long long *) vp), *((unsigned long long *) vp));
+					break;
+				default:
+					dt_printf(cbdatap->dtp, cbdatap->fp, "CTF_K_INTEGER: format %x offset %u bits %u\n",cte.cte_format,cte.cte_offset,cte.cte_bits);
+					break;
+				}
+			break;
+		case CTF_K_FLOAT:
+			dt_printf(cbdatap->dtp, cbdatap->fp, "CTF_K_FLOAT: format %x offset %u bits %u\n",cte.cte_format,cte.cte_offset,cte.cte_bits);
+			break;
+		case CTF_K_POINTER:
+			dt_printf(cbdatap->dtp, cbdatap->fp, "%p;\n", *((char *) addr));
+			break;
+		case CTF_K_ARRAY:
+			if (ctf_array_info(cbdatap->dtt.dtt_ctfp, type, &arinfo) != 0)
+				return (-1);
+			dt_printf(cbdatap->dtp, cbdatap->fp, "{\n%*s",cbdata.indent * 4,"");
+			dt_print_type_data(&cbdata, arinfo.ctr_contents);
+			dt_printf(cbdatap->dtp, cbdatap->fp, "%*s};\n",cbdatap->indent * 4,"");
+			break;
+		case CTF_K_FUNCTION:
+			dt_printf(cbdatap->dtp, cbdatap->fp, "CTF_K_FUNCTION:\n");
+			break;
+		case CTF_K_STRUCT:
+			cbdata.f_type = 1;
+			if (ctf_member_iter(cbdatap->dtt.dtt_ctfp, type,
+			    dt_print_type_width, &cbdata) != 0)
+				return (-1);
+			dt_printf(cbdatap->dtp, cbdatap->fp, "{\n");
+			if (ctf_member_iter(cbdatap->dtt.dtt_ctfp, type,
+			    dt_print_type_member, &cbdata) != 0)
+				return (-1);
+			dt_printf(cbdatap->dtp, cbdatap->fp, "%*s};\n",cbdatap->indent * 4,"");
+			break;
+		case CTF_K_UNION:
+			cbdata.f_type = 1;
+			if (ctf_member_iter(cbdatap->dtt.dtt_ctfp, type,
+			    dt_print_type_width, &cbdata) != 0)
+				return (-1);
+			dt_printf(cbdatap->dtp, cbdatap->fp, "{\n");
+			if (ctf_member_iter(cbdatap->dtt.dtt_ctfp, type,
+			    dt_print_type_member, &cbdata) != 0)
+				return (-1);
+			dt_printf(cbdatap->dtp, cbdatap->fp, "%*s};\n",cbdatap->indent * 4,"");
+			break;
+		case CTF_K_ENUM:
+			dt_printf(cbdatap->dtp, cbdatap->fp, "%s;\n", ctf_enum_name(cbdatap->dtt.dtt_ctfp, type, *((int *) vp)));
+			break;
+		case CTF_K_TYPEDEF:
+			dt_print_type_data(&cbdata, ctf_type_reference(cbdatap->dtt.dtt_ctfp,type));
+			break;
+		case CTF_K_VOLATILE:
+			if (cbdatap->f_type)
+				dt_printf(cbdatap->dtp, cbdatap->fp, "volatile ");
+			dt_print_type_data(&cbdata, ctf_type_reference(cbdatap->dtt.dtt_ctfp,type));
+			break;
+		case CTF_K_CONST:
+			if (cbdatap->f_type)
+				dt_printf(cbdatap->dtp, cbdatap->fp, "const ");
+			dt_print_type_data(&cbdata, ctf_type_reference(cbdatap->dtt.dtt_ctfp,type));
+			break;
+		case CTF_K_RESTRICT:
+			if (cbdatap->f_type)
+				dt_printf(cbdatap->dtp, cbdatap->fp, "restrict ");
+			dt_print_type_data(&cbdata, ctf_type_reference(cbdatap->dtt.dtt_ctfp,type));
+			break;
+		default:
+			break;
+		}
+
+		addr += ssz;
+		cnt++;
+	}
+
+	return (0);
+}
+
+static int
 dt_print_type(dtrace_hdl_t *dtp, FILE *fp, caddr_t addr)
 {
+	caddr_t addrend;
+	char *p;
 	dtrace_typeinfo_t dtt;
-	char *p;
+	dt_type_cbdata_t cbdata;
 	int num = 0;
 	int quiet = (dtp->dt_options[DTRACEOPT_QUIET] != DTRACEOPT_UNSET);
+	ssize_t ssz;
 
+	if (!quiet)
+		dt_printf(dtp, fp, "\n");
+
 	/* Get the total number of bytes of data buffered. */
 	size_t nbytes = *((uintptr_t *) addr);
 	addr += sizeof(uintptr_t);
@@ -860,13 +1086,25 @@
 	/* Offset the buffer address to the start of the data... */
 	addr += offset;
 
-	/*
-	 * XXX Here we need code to expand the type and print the data
-	 * elements based on the member types.
-	 */
+	ssz = ctf_type_size(dtt.dtt_ctfp, dtt.dtt_type);
+
+	if (typs != ssz) {
+		printf("Expected type size from buffer (%lu) to match type size looked up now (%ld)\n", (u_long) typs, (long) ssz);
+		return (-1);
+	}
+
+	cbdata.dtp = dtp;
+	cbdata.dtt = dtt;
+	cbdata.name = "";
+	cbdata.addr = addr;
+	cbdata.addrend = addr + nbytes;
+	cbdata.indent = 1;
+	cbdata.f_type = 1;
+	cbdata.type_width = 0;
+	cbdata.name_width = 0;
+	cbdata.fp = fp;
 
-	/* XXX Just print the data for now. */
-	return (dt_print_bytes(dtp, fp, addr, nbytes, 50, quiet, 1));
+	return (dt_print_type_data(&cbdata, dtt.dtt_type));
 }
 
 static int


More information about the p4-projects mailing list