Dtrace: add optional size argument to tracemem().

Merge change from illumos:

1455 DTrace tracemem() should take an optional size argument

Our local enhancements to dt_print_bytes were equivalent to
those in illumos but we made it match the illumos version
to ease further code merges.

For now leave out tst.smallsize.d and tst.smallsize.d.out
since those don't seem to work cleanly on FreeBSD.

This change bumps the DT_VERS_* number to 1.7.1 in accordance
to what is done in illumos.

Illumos Revision:	13457:571b0355c2e3

Reference:
https://www.illumos.org/issues/1455

Tested by:	Fabian Keil
Obtained from:	Illumos
MFC after:	1 month
This commit is contained in:
Pedro F. Giffuni 2013-03-24 19:12:08 +00:00
commit f2e66d30b8
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=248690
10 changed files with 1469 additions and 23 deletions

View File

@ -0,0 +1,29 @@
/*
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
* Common Development and Distribution License (the "License").
* You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* or http://www.opensolaris.org/os/licensing.
* See the License for the specific language governing permissions
* and limitations under the License.
*
* When distributing Covered Code, include this CDDL HEADER in each
* file and include the License file at usr/src/OPENSOLARIS.LICENSE.
* If applicable, add the following below this CDDL HEADER, with the
* fields enclosed by brackets "[]" replaced with your own identifying
* information: Portions Copyright [yyyy] [name of copyright owner]
*
* CDDL HEADER END
*/
/*
* Copyright (c) 2011, Joyent, Inc. All rights reserved.
*/
BEGIN
{
tracemem(`dtrace_zero, 256, 0, "fishpong");
}

View File

@ -0,0 +1,30 @@
/*
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
* Common Development and Distribution License (the "License").
* You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* or http://www.opensolaris.org/os/licensing.
* See the License for the specific language governing permissions
* and limitations under the License.
*
* When distributing Covered Code, include this CDDL HEADER in each
* file and include the License file at usr/src/OPENSOLARIS.LICENSE.
* If applicable, add the following below this CDDL HEADER, with the
* fields enclosed by brackets "[]" replaced with your own identifying
* information: Portions Copyright [yyyy] [name of copyright owner]
*
* CDDL HEADER END
*/
/*
* Copyright (c) 2011, Joyent, Inc. All rights reserved.
*/
BEGIN
{
tracemem(`dtrace_zero, 256, "fishpong");
exit(0);
}

View File

@ -20,20 +20,26 @@
*/
/*
* Copyright 2006 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
* Copyright (c) 2011, Joyent, Inc. All rights reserved.
*/
#pragma ident "%Z%%M% %I% %E% SMI"
/*
* ASSERTION:
* Test tracemem() with too many arguments.
*
* SECTION: Actions and Subroutines/tracemem()
*/
#pragma D option quiet
BEGIN
{
tracemem(123, 456, 789);
i = -10;
}
tick-10ms
/i++ < 150/
{
printf("%d:", i);
tracemem(`dtrace_zero, 128, i);
printf("\n");
}
tick-10ms
/i >= 150/
{
exit(0);
}

File diff suppressed because it is too large Load Diff

View File

@ -685,7 +685,8 @@ dt_action_tracemem(dtrace_hdl_t *dtp, dt_node_t *dnp, dtrace_stmtdesc_t *sdp)
dtrace_actdesc_t *ap = dt_stmt_action(dtp, sdp);
dt_node_t *addr = dnp->dn_args;
dt_node_t *size = dnp->dn_args->dn_list;
dt_node_t *max = dnp->dn_args->dn_list;
dt_node_t *size;
char n[DT_TYPE_NAMELEN];
@ -697,17 +698,37 @@ dt_action_tracemem(dtrace_hdl_t *dtp, dt_node_t *dnp, dtrace_stmtdesc_t *sdp)
dt_node_type_name(addr, n, sizeof (n)));
}
if (dt_node_is_posconst(size) == 0) {
dnerror(size, D_TRACEMEM_SIZE, "tracemem( ) argument #2 must "
if (dt_node_is_posconst(max) == 0) {
dnerror(max, D_TRACEMEM_SIZE, "tracemem( ) argument #2 must "
"be a non-zero positive integral constant expression\n");
}
if ((size = max->dn_list) != NULL) {
if (size->dn_list != NULL) {
dnerror(size, D_TRACEMEM_ARGS, "tracemem ( ) prototype "
"mismatch: expected at most 3 args\n");
}
if (!dt_node_is_scalar(size)) {
dnerror(size, D_TRACEMEM_DYNSIZE, "tracemem ( ) "
"dynamic size (argument #3) must be of "
"scalar type\n");
}
dt_cg(yypcb, size);
ap->dtad_difo = dt_as(yypcb);
ap->dtad_difo->dtdo_rtype = dt_int_rtype;
ap->dtad_kind = DTRACEACT_TRACEMEM_DYNSIZE;
ap = dt_stmt_action(dtp, sdp);
}
dt_cg(yypcb, addr);
ap->dtad_difo = dt_as(yypcb);
ap->dtad_kind = DTRACEACT_DIFEXPR;
ap->dtad_kind = DTRACEACT_TRACEMEM;
ap->dtad_difo->dtdo_rtype.dtdt_flags |= DIF_TF_BYREF;
ap->dtad_difo->dtdo_rtype.dtdt_size = size->dn_value;
ap->dtad_difo->dtdo_rtype.dtdt_size = max->dn_value;
}
static void

View File

@ -832,7 +832,7 @@ dt_print_stddev(dtrace_hdl_t *dtp, FILE *fp, caddr_t addr,
/*ARGSUSED*/
int
dt_print_bytes(dtrace_hdl_t *dtp, FILE *fp, caddr_t addr,
size_t nbytes, int width, int quiet, int raw)
size_t nbytes, int width, int quiet, int forceraw)
{
/*
* If the byte stream is a series of printable characters, followed by
@ -845,7 +845,10 @@ dt_print_bytes(dtrace_hdl_t *dtp, FILE *fp, caddr_t addr,
if (nbytes == 0)
return (0);
if (raw || dtp->dt_options[DTRACEOPT_RAWBYTES] != DTRACEOPT_UNSET)
if (forceraw)
goto raw;
if (dtp->dt_options[DTRACEOPT_RAWBYTES] != DTRACEOPT_UNSET)
goto raw;
for (i = 0; i < nbytes; i++) {
@ -2019,6 +2022,7 @@ dt_consume_cpu(dtrace_hdl_t *dtp, FILE *fp, int cpu, dtrace_bufdesc_t *buf,
int quiet = (dtp->dt_options[DTRACEOPT_QUIET] != DTRACEOPT_UNSET);
int rval, i, n;
dtrace_epid_t last = DTRACE_EPIDNONE;
uint64_t tracememsize = 0;
dtrace_probedata_t data;
uint64_t drops;
caddr_t addr;
@ -2187,6 +2191,12 @@ dt_consume_cpu(dtrace_hdl_t *dtp, FILE *fp, int cpu, dtrace_bufdesc_t *buf,
}
}
if (act == DTRACEACT_TRACEMEM_DYNSIZE &&
rec->dtrd_size == sizeof (uint64_t)) {
tracememsize = *((unsigned long long *)addr);
continue;
}
rval = (*rfunc)(&data, rec, arg);
if (rval == DTRACE_CONSUME_NEXT)
@ -2358,6 +2368,23 @@ dt_consume_cpu(dtrace_hdl_t *dtp, FILE *fp, int cpu, dtrace_bufdesc_t *buf,
goto nextrec;
}
if (act == DTRACEACT_TRACEMEM) {
if (tracememsize == 0 ||
tracememsize > rec->dtrd_size) {
tracememsize = rec->dtrd_size;
}
n = dt_print_bytes(dtp, fp, addr,
tracememsize, 33, quiet, 1);
tracememsize = 0;
if (n < 0)
return (-1);
goto nextrec;
}
switch (rec->dtrd_size) {
case sizeof (uint64_t):
n = dt_printf(dtp, fp,

View File

@ -189,6 +189,8 @@ typedef enum {
D_TRACE_DYN, /* trace() argument has dynamic type */
D_TRACEMEM_ADDR, /* tracemem() address bad type */
D_TRACEMEM_SIZE, /* tracemem() size bad type */
D_TRACEMEM_ARGS, /* tracemem() illegal number of args */
D_TRACEMEM_DYNSIZE, /* tracemem() dynamic size bad type */
D_STACK_PROTO, /* stack() prototype mismatch */
D_STACK_SIZE, /* stack() size argument bad type */
D_USTACK_FRAMES, /* ustack() frames arg bad type */

View File

@ -116,8 +116,9 @@
#define DT_VERS_1_6_2 DT_VERSION_NUMBER(1, 6, 2)
#define DT_VERS_1_6_3 DT_VERSION_NUMBER(1, 6, 3)
#define DT_VERS_1_7 DT_VERSION_NUMBER(1, 7, 0)
#define DT_VERS_LATEST DT_VERS_1_7
#define DT_VERS_STRING "Sun D 1.7"
#define DT_VERS_1_7_1 DT_VERSION_NUMBER(1, 7, 1)
#define DT_VERS_LATEST DT_VERS_1_7_1
#define DT_VERS_STRING "Sun D 1.7.1"
const dt_version_t _dtrace_versions[] = {
DT_VERS_1_0, /* D API 1.0.0 (PSARC 2001/466) Solaris 10 FCS */
@ -134,6 +135,7 @@ const dt_version_t _dtrace_versions[] = {
DT_VERS_1_6_2, /* D API 1.6.2 */
DT_VERS_1_6_3, /* D API 1.6.3 */
DT_VERS_1_7, /* D API 1.7 */
DT_VERS_1_7_1, /* D API 1.7.1 */
0
};
@ -461,7 +463,7 @@ static const dt_ident_t _dtrace_globals[] = {
&dt_idops_func, "void(@)" },
{ "tracemem", DT_IDENT_ACTFUNC, 0, DT_ACT_TRACEMEM,
DT_ATTR_STABCMN, DT_VERS_1_0,
&dt_idops_func, "void(@, size_t)" },
&dt_idops_func, "void(@, size_t, ...)" },
{ "trunc", DT_IDENT_ACTFUNC, 0, DT_ACT_TRUNC, DT_ATTR_STABCMN,
DT_VERS_1_0, &dt_idops_func, "void(...)" },
{ "typeref", DT_IDENT_FUNC, 0, DIF_SUBR_TYPEREF, DT_ATTR_STABCMN, DT_VERS_1_1,

View File

@ -6015,6 +6015,7 @@ dtrace_probe(dtrace_id_t id, uintptr_t arg0, uintptr_t arg1,
dtrace_buffer_t *aggbuf = &state->dts_aggbuffer[cpuid];
dtrace_vstate_t *vstate = &state->dts_vstate;
dtrace_provider_t *prov = probe->dtpr_provider;
uint64_t tracememsize = 0;
int committed = 0;
caddr_t tomax;
@ -6466,6 +6467,11 @@ dtrace_probe(dtrace_id_t id, uintptr_t arg0, uintptr_t arg1,
case DTRACEACT_PRINTA:
case DTRACEACT_SYSTEM:
case DTRACEACT_FREOPEN:
case DTRACEACT_TRACEMEM:
break;
case DTRACEACT_TRACEMEM_DYNSIZE:
tracememsize = val;
break;
case DTRACEACT_SYM:
@ -6537,6 +6543,12 @@ dtrace_probe(dtrace_id_t id, uintptr_t arg0, uintptr_t arg1,
if (dp->dtdo_rtype.dtdt_flags & DIF_TF_BYREF) {
uintptr_t end = valoffs + size;
if (tracememsize != 0 &&
valoffs + tracememsize < end) {
end = valoffs + tracememsize;
tracememsize = 0;
}
if (!dtrace_vcanload((void *)(uintptr_t)val,
&dp->dtdo_rtype, &mstate, vstate))
continue;
@ -10147,6 +10159,8 @@ dtrace_ecb_action_add(dtrace_ecb_t *ecb, dtrace_actdesc_t *desc)
/*FALLTHROUGH*/
case DTRACEACT_LIBACT:
case DTRACEACT_DIFEXPR:
case DTRACEACT_TRACEMEM:
case DTRACEACT_TRACEMEM_DYNSIZE:
if (dp == NULL)
return (EINVAL);

View File

@ -418,8 +418,10 @@ typedef struct dtrace_difv {
#define DTRACEACT_PRINTF 3 /* printf() action */
#define DTRACEACT_PRINTA 4 /* printa() action */
#define DTRACEACT_LIBACT 5 /* library-controlled action */
#define DTRACEACT_PRINTM 6 /* printm() action */
#define DTRACEACT_PRINTT 7 /* printt() action */
#define DTRACEACT_TRACEMEM 6 /* tracemem() action */
#define DTRACEACT_TRACEMEM_DYNSIZE 7 /* dynamic tracemem() size */
#define DTRACEACT_PRINTM 8 /* printm() action (BSD) */
#define DTRACEACT_PRINTT 9 /* printt() action (BSD) */
#define DTRACEACT_PROC 0x0100
#define DTRACEACT_USTACK (DTRACEACT_PROC + 1)