dtrace(1): add -d flag to dump D script post-dt_sugar

By specifying the -d flag, libdtrace will dump the D script after it has
applied syntactical sugar transformations (e.g if/else). This is useful
for both understanding what dt_sugar does, as well as debugging it.

Reviewed by:	markj
Approved by:	markj (mentor)
Sponsored by:	The FreeBSD Foundation
Differential Revision:	https://reviews.freebsd.org/D38732
This commit is contained in:
Christos Margiolis 2023-05-23 17:18:39 +03:00
parent 81877287a9
commit 1e136a9cbd
4 changed files with 28 additions and 10 deletions

View file

@ -20,7 +20,7 @@
.\"
.\" $FreeBSD$
.\"
.Dd September 7, 2021
.Dd February 24, 2023
.Dt DTRACE 1
.Os
.Sh NAME
@ -29,7 +29,7 @@
.Sh SYNOPSIS
.Nm
.Op Fl 32 | Fl 64
.Op Fl aACeFGhHlqSvVwZ
.Op Fl aACdeFGhHlqSvVwZ
.Op Fl b Ar bufsz
.Op Fl c Ar cmd
.Op Fl D Ar name Op Ns = Ns value
@ -195,6 +195,12 @@ option.
For a description of the set of tokens defined by the D compiler when invoking
the C preprocessor, see
.Fl X .
.It Fl d
Dump the D script to standard output, after syntactic transformations have been
applied.
For example, if-statements in D are implemented using such transformations: a
conditional clause in a probe body is replaced at compile-time by a separate
probe predicated on the original condition.
.It Fl D Ar name Op Ns = Ns value
Define
.Ar name

View file

@ -77,7 +77,7 @@ typedef struct dtrace_cmd {
#define E_USAGE 2
static const char DTRACE_OPTSTR[] =
"3:6:aAb:Bc:CD:ef:FGhHi:I:lL:m:n:o:p:P:qs:SU:vVwx:X:Z";
"3:6:aAb:Bc:CdD:ef:FGhHi:I:lL:m:n:o:p:P:qs:SU:vVwx:X:Z";
static char **g_argv;
static int g_argc;
@ -130,7 +130,7 @@ usage(FILE *fp)
{
static const char predact[] = "[[ predicate ] action ]";
(void) fprintf(fp, "Usage: %s [-32|-64] [-aACeFGhHlqSvVwZ] "
(void) fprintf(fp, "Usage: %s [-32|-64] [-aACdeFGhHlqSvVwZ] "
"[-b bufsz] [-c cmd] [-D name[=def]]\n\t[-I path] [-L path] "
"[-o output] [-p pid] [-s script] [-U name]\n\t"
"[-x opt[=val]] [-X a|c|s|t]\n\n"
@ -152,6 +152,7 @@ usage(FILE *fp)
"\t-b set trace buffer size\n"
"\t-c run specified command and exit upon its completion\n"
"\t-C run cpp(1) preprocessor on script files\n"
"\t-d dump script after syntactic transformations\n"
"\t-D define symbol when invoking preprocessor\n"
"\t-e exit after compiling request but prior to enabling probes\n"
"\t-f enable or list probes matching the specified function name\n"
@ -1559,6 +1560,10 @@ main(int argc, char *argv[])
g_cflags |= DTRACE_C_CPP;
break;
case 'd':
g_cflags |= DTRACE_C_SUGAR;
break;
case 'D':
if (dtrace_setopt(g_dtp, "define", optarg) != 0)
dfatal("failed to set -D %s", optarg);

View file

@ -2478,10 +2478,7 @@ dt_compile(dtrace_hdl_t *dtp, int context, dtrace_probespec_t pspec, void *arg,
"not referenced)\n", yypcb->pcb_sargv[argc - 1], argc - 1);
}
/*
* Perform sugar transformations (for "if" / "else") and replace the
* existing clause chain with the new one.
*/
/* Perform sugar transformations. */
if (context == DT_CTX_DPROG) {
dt_node_t *dnp, *next_dnp;
dt_node_t *new_list = NULL;
@ -2492,8 +2489,17 @@ dt_compile(dtrace_hdl_t *dtp, int context, dtrace_probespec_t pspec, void *arg,
next_dnp = dnp->dn_list;
dnp->dn_list = NULL;
if (dnp->dn_kind == DT_NODE_CLAUSE)
if (dnp->dn_kind == DT_NODE_CLAUSE) {
dnp = dt_compile_sugar(dtp, dnp);
if (cflags & DTRACE_C_SUGAR) {
dt_node_t *p;
dt_printd(dnp, stdout, 0);
for (p = dnp->dn_list; p != NULL;
p = p->dn_list)
dt_printd(p, stdout, 0);
}
}
/* append node to the new list */
new_list = dt_node_link(new_list, dnp);
}

View file

@ -119,10 +119,11 @@ typedef struct dtrace_proginfo {
#define DTRACE_C_PSPEC 0x0080 /* Interpret ambiguous specifiers as probes */
#define DTRACE_C_ETAGS 0x0100 /* Prefix error messages with error tags */
#define DTRACE_C_ARGREF 0x0200 /* Do not require all macro args to be used */
#define DTRACE_C_SUGAR 0x0400 /* Dump D script post-dt_sugar */
#define DTRACE_C_DEFARG 0x0800 /* Use 0/"" as value for unspecified args */
#define DTRACE_C_NOLIBS 0x1000 /* Do not process D system libraries */
#define DTRACE_C_CTL 0x2000 /* Only process control directives */
#define DTRACE_C_MASK 0x3bff /* mask of all valid flags to dtrace_*compile */
#define DTRACE_C_MASK 0x3fff /* mask of all valid flags to dtrace_*compile */
extern dtrace_prog_t *dtrace_program_strcompile(dtrace_hdl_t *,
const char *, dtrace_probespec_t, uint_t, int, char *const []);