[DTrace-devel] [PATCH v2] Introduce 'bpflog' runtime option to request BPF verifier log

Eugene Loh eugene.loh at oracle.com
Fri Aug 6 21:56:34 PDT 2021


I still need to digest the email on this patch, but meanwhile I had a 
question below...

On 7/29/21 11:38 PM, Kris Van Hees wrote:
> The default behaviour is to only print the BPF verifier log when a BPF
> program fails to load.  It is sometimes desirable to obtain the BPF
> verifier log for successful prgoram loads to assist in debugging other
> issues with BPF programs.  Specifying -xbpflog on the command line or
> setting this option using a pragma will force printing of the BPF
> verifier log for all program loads.
>   
> diff --git a/libdtrace/dt_bpf.c b/libdtrace/dt_bpf.c
> @@ -406,14 +406,14 @@ dt_bpf_load_prog(dtrace_hdl_t *dtp, const dt_probe_t *prp,
>   	attr.insns_cnt = dp->dtdo_len;
>   	attr.license = BPF_CG_LICENSE;
>   
> -	rc = bpf_load_program_xattr(&attr, NULL, 0);
> -	if (rc >= 0)
> -		return rc;
> +	if (dtp->dt_options[DTRACEOPT_BPFLOG] == DTRACEOPT_UNSET) {
> +		rc = bpf_load_program_xattr(&attr, NULL, 0);
> +		if (rc >= 0)
> +			return rc;
> +
> +		origerrno = errno;
> +	}
>   
> -	/* if failure, note error and rerun with logging */
> -	dt_bpf_error(dtp, "BPF program load for '%s:%s:%s:%s' failed: %s\n",
> -			  pdp->prv, pdp->mod, pdp->fun, pdp->prb,
> -			  strerror(errno));
>   	if (dtp->dt_options[DTRACEOPT_BPFLOGSIZE] != DTRACEOPT_UNSET)
>   		logsz = dtp->dt_options[DTRACEOPT_BPFLOGSIZE];
>   	else
> @@ -422,34 +422,40 @@ dt_bpf_load_prog(dtrace_hdl_t *dtp, const dt_probe_t *prp,
>   	log = dt_zalloc(dtp, logsz);
>   	assert(log != NULL);
>   	rc = bpf_load_program_xattr(&attr, log, logsz);
> +	if (rc < 0) {
> +		dt_bpf_error(dtp, "BPF program load for '%s:%s:%s:%s' failed: "
> +				  "%s\n",
> +			     pdp->prv, pdp->mod, pdp->fun, pdp->prb,
> +			     strerror(origerrno ? origerrno : errno));
> +
> +		/* check whether we have an incomplete BPF log */
> +		if (errno == ENOSPC) {
> +			fprintf(stderr,
> +				"BPF verifier log is incomplete and is not reported.\n"
> +				"Set DTrace option 'bpflogsize' to some greater size for more output.\n"
> +				"(Current size is %ld.)\n", logsz);
> +			goto out;
> +		}
> +	} else if (dtp->dt_options[DTRACEOPT_BPFLOGSIZE] == DTRACEOPT_UNSET)
> +		goto out;

I don't get this.  There is a default bpflogsize.  But if you specify 
-xbpflog by itself, you won't get the log.  You also have to specify 
bpflogsize explicitly?  Why?

> -	/* since it failed once, it should fail again */
> -	assert(rc < 0);
> -
> -	/* check whether we have an incomplete BPF log */
> -	if (errno == ENOSPC) {
> -		fprintf(stderr,
> -		    "BPF verifier log is incomplete and is not reported.\n"
> -		    "Set DTrace option 'bpflogsize' to some greater size for more output.\n"
> -		    "(Current size is %ld.)\n", logsz);
> -	} else {
> -		/*
> -		 * If there is BPF verifier output, print it with a "BPF: "
> -		 * prefix so it is easier to distinguish.
> -		 */
> -		for (p = log; p && *p; p = q) {
> -			q = strchr(p, '\n');
> +	/*
> +	 * If there is BPF verifier output, print it with a "BPF: "
> +	 * prefix so it is easier to distinguish.
> +	 */
> +	for (p = log; p && *p; p = q) {
> +		q = strchr(p, '\n');
>   
> -			if (q)
> -				*q++ = '\0';
> +		if (q)
> +			*q++ = '\0';
>   
> -			fprintf(stderr, "BPF: %s\n", p);
> -		}
> +		fprintf(stderr, "BPF: %s\n", p);
>   	}
>   
> +out:
>   	dt_free(dtp, log);
>   
> -	return -1;
> +	return rc >= 0 ? rc : -1;
>   }



More information about the DTrace-devel mailing list