Skip to content

Commit

Permalink
Add tracemem support
Browse files Browse the repository at this point in the history
Also, replace tst.three_arg.sh with tst.tracemem.d:
- to avoid the problematic profile probe (fires irregularly)
- for cleaner post processing
- to check both 2-arg and 3-arg results

Signed-off-by: Eugene Loh <eugene.loh@oracle.com>
Reviewed-by: Kris Van Hees <kris.van.hees@oracle.com>
  • Loading branch information
euloh authored and kvanhees committed Feb 26, 2023
1 parent d26c97e commit bbc7f14
Show file tree
Hide file tree
Showing 11 changed files with 167 additions and 150 deletions.
45 changes: 43 additions & 2 deletions libdtrace/dt_cg.c
Original file line number Diff line number Diff line change
Expand Up @@ -1996,8 +1996,49 @@ dt_cg_act_trace(dt_pcb_t *pcb, dt_node_t *dnp, dtrace_actkind_t kind)
static void
dt_cg_act_tracemem(dt_pcb_t *pcb, dt_node_t *dnp, dtrace_actkind_t kind)
{
dnerror(dnp, D_UNKNOWN, "tracemem() is not implemented (yet)\n");
/* FIXME: Needs implementation */
char n[DT_TYPE_NAMELEN];
dt_node_t *addr = dnp->dn_args;
dt_node_t *nsiz = addr->dn_list;
dt_node_t *dsiz = nsiz->dn_list;
dtrace_hdl_t *dtp = pcb->pcb_hdl;
dt_irlist_t *dlp = &pcb->pcb_ir;
dt_regset_t *drp = pcb->pcb_regs;
uint_t off;

if (dt_node_is_integer(addr) == 0 && dt_node_is_pointer(addr) == 0)
dnerror(addr, D_TRACEMEM_ADDR,
"tracemem( ) argument #1 is incompatible with prototype:\n"
"\tprototype: pointer or integer\n"
"\t argument: %s\n", dt_node_type_name(addr, n, sizeof(n)));

if (dt_node_is_posconst(nsiz) == 0)
dnerror(nsiz, D_TRACEMEM_SIZE,
"tracemem( ) argument #2 must be a non-zero positive integral constant expression\n");

dt_cg_node(addr, dlp, drp);
dt_cg_node(nsiz, dlp, drp);

off = dt_rec_add(dtp, dt_cg_fill_gap, DTRACEACT_TRACEMEM, nsiz->dn_value, 1, NULL,
dsiz ? DTRACE_TRACEMEM_DYNAMIC : DTRACE_TRACEMEM_STATIC);

if (dsiz != NULL)
dt_cg_store_val(pcb, dsiz, DTRACEACT_TRACEMEM, NULL,
dsiz->dn_flags & DT_NF_SIGNED ? DTRACE_TRACEMEM_SSIZE : DTRACE_TRACEMEM_SIZE);

if (dt_regset_xalloc_args(drp) == -1)
longjmp(yypcb->pcb_jmpbuf, EDT_NOREG);

emit(dlp, BPF_MOV_REG(BPF_REG_1, BPF_REG_9));
emit(dlp, BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, off));
emit(dlp, BPF_MOV_REG(BPF_REG_2, nsiz->dn_reg));
dt_regset_free(drp, nsiz->dn_reg);
emit(dlp, BPF_MOV_REG(BPF_REG_3, addr->dn_reg));
dt_regset_free(drp, addr->dn_reg);

dt_regset_xalloc(drp, BPF_REG_0);
emit(dlp, BPF_CALL_HELPER(BPF_FUNC_probe_read));
dt_regset_free_args(drp);
dt_regset_free(drp, BPF_REG_0);
}

static void
Expand Down
13 changes: 11 additions & 2 deletions libdtrace/dt_consume.c
Original file line number Diff line number Diff line change
Expand Up @@ -1005,7 +1005,6 @@ dt_print_bytes(dtrace_hdl_t *dtp, FILE *fp, caddr_t addr,
return dt_print_rawbytes(dtp, fp, addr, nbytes);
}

#ifdef FIXME
static int
dt_print_tracemem(dtrace_hdl_t *dtp, FILE *fp, const dtrace_recdesc_t *rec,
uint_t nrecs, const caddr_t buf)
Expand Down Expand Up @@ -1053,7 +1052,6 @@ dt_print_tracemem(dtrace_hdl_t *dtp, FILE *fp, const dtrace_recdesc_t *rec,

return nconsumed;
}
#endif

int
dt_print_stack(dtrace_hdl_t *dtp, FILE *fp, const char *format,
Expand Down Expand Up @@ -2471,6 +2469,17 @@ dt_consume_one_probe(dtrace_hdl_t *dtp, FILE *fp, char *data, uint32_t size,
if (dt_print_umod(dtp, fp, NULL, recdata) < 0)
return -1;
continue;
case DTRACEACT_TRACEMEM: {
int nrecs;

nrecs = epd->dtdd_nrecs - i;
n = dt_print_tracemem(dtp, fp, rec, nrecs, data);
if (n < 0)
return -1;

i += n - 1;
continue;
}
case DTRACEACT_PRINTF:
func = dtrace_fprintf;
break;
Expand Down
4 changes: 2 additions & 2 deletions test/unittest/tracemem/err.D_TRACEMEM_ADDR.badaddr.d
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
/*
* Oracle Linux DTrace.
* Copyright (c) 2006, 2020, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2006, 2023, Oracle and/or its affiliates. All rights reserved.
* Licensed under the Universal Permissive License v 1.0 as shown at
* http://oss.oracle.com/licenses/upl.
*/
/* @@xfail: dtv2 */

/*
* ASSERTION:
* Test tracemem() with an invalid address argument.
Expand Down
4 changes: 2 additions & 2 deletions test/unittest/tracemem/err.D_TRACEMEM_SIZE.negsize.d
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
/*
* Oracle Linux DTrace.
* Copyright (c) 2006, 2020, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2006, 2023, Oracle and/or its affiliates. All rights reserved.
* Licensed under the Universal Permissive License v 1.0 as shown at
* http://oss.oracle.com/licenses/upl.
*/
/* @@xfail: dtv2 */

/*
* ASSERTION:
* Test tracemem() with a negative size argument.
Expand Down
4 changes: 2 additions & 2 deletions test/unittest/tracemem/err.D_TRACEMEM_SIZE.zerosize.d
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
/*
* Oracle Linux DTrace.
* Copyright (c) 2006, 2020, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2006, 2023, Oracle and/or its affiliates. All rights reserved.
* Licensed under the Universal Permissive License v 1.0 as shown at
* http://oss.oracle.com/licenses/upl.
*/
/* @@xfail: dtv2 */

/*
* ASSERTION:
* Test tracemem() with a zero size argument.
Expand Down
4 changes: 2 additions & 2 deletions test/unittest/tracemem/tst.init_task.d
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
/*
* Oracle Linux DTrace.
* Copyright (c) 2006, 2022, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2006, 2023, Oracle and/or its affiliates. All rights reserved.
* Licensed under the Universal Permissive License v 1.0 as shown at
* http://oss.oracle.com/licenses/upl.
*/
/* @@xfail: dtv2 - requires tracemem() */


/*
* ASSERTION:
Expand Down
136 changes: 0 additions & 136 deletions test/unittest/tracemem/tst.three_arg.sh

This file was deleted.

65 changes: 65 additions & 0 deletions test/unittest/tracemem/tst.tracemem.d
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
/*
* Oracle Linux DTrace.
* Copyright (c) 2023, Oracle and/or its affiliates. All rights reserved.
* Licensed under the Universal Permissive License v 1.0 as shown at
* http://oss.oracle.com/licenses/upl.
*/

/*
* ASSERTION: Results for tracemem() are correct.
*
* SECTION: Actions and Subroutines/tracemem()
*/

#pragma D option quiet

long long *p;

BEGIN {
/* pick some pointer to kernel memory */
p = (long long *) curthread;

/* dump memory at this pointer */
printf("%16.16x %16.16x\n", p[ 0], p[ 1]);
printf("%16.16x %16.16x\n", p[ 2], p[ 3]);
printf("%16.16x %16.16x\n", p[ 4], p[ 5]);
printf("%16.16x %16.16x\n", p[ 6], p[ 7]);
printf("%16.16x %16.16x\n", p[ 8], p[ 9]);
printf("%16.16x %16.16x\n", p[10], p[11]);
printf("%16.16x %16.16x\n", p[12], p[13]);
printf("%16.16x %16.16x\n", p[14], p[15]);
printf("%16.16x %16.16x\n", p[16], p[17]);
printf("%16.16x %16.16x\n", p[18], p[19]);
printf("%16.16x %16.16x\n", p[20], p[21]);
printf("%16.16x %16.16x\n", p[22], p[23]);
printf("%16.16x %16.16x\n", p[24], p[25]);
printf("%16.16x %16.16x\n", p[26], p[27]);
printf("%16.16x %16.16x\n", p[28], p[29]);
printf("%16.16x %16.16x\n", p[30], p[31]);

/* try tracemem() with this same pointer but various sizes */

tracemem(p, 256); /* 256 bytes */

tracemem(p, 256, -1); /* 256 bytes (arg2 < 0) */

tracemem(p, 256, 0); /* 0 bytes */

tracemem(p, 256, 32); /* 32 bytes */

tracemem(p, 256, 64); /* 64 bytes */

tracemem(p, 256, 128); /* 128 bytes */

tracemem(p, 256, 256); /* 256 bytes */

tracemem(p, 256, 320); /* 256 bytes (arg1 <= arg2) */

tracemem(p, 256, (unsigned char) 0x80);
/* 128 bytes */

tracemem(p, 256, (signed char) 0x80);
/* 256 bytes (arg2 < 0) */

exit(0);
}
9 changes: 9 additions & 0 deletions test/unittest/tracemem/tst.tracemem.r
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
256 bytes
256 bytes
32 bytes
64 bytes
128 bytes
256 bytes
256 bytes
128 bytes
256 bytes
30 changes: 30 additions & 0 deletions test/unittest/tracemem/tst.tracemem.r.p
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
#!/usr/bin/gawk -f

# read data against which we will check tracemem() results
BEGIN {
n = 0; # count check results
m = 0; # count tracemem() results
}
NF == 2 {
check[n] = $1; n++;
check[n] = $2; n++;
next;
}

# if we have a blank line, report number of bytes compared, if any
NF == 0 && m > 0 { print 8 * m, "bytes" }

# restart counting tracemem() output
NF == 0 { m = 0; next; }

# comparison function
function mycomp(expect, actual) {
if ( expect != actual )
print "ERROR: expect", expect, "actual", actual;
}

# tracemem output has two sets of 8 bytes each; reverse bytes for comparison
/:/ {
mycomp( check[m++], $9$8$7$6$5$4$3$2);
mycomp( check[m++], $17$16$15$14$13$12$11$10);
}
3 changes: 1 addition & 2 deletions test/unittest/types/tst.complex.d
Original file line number Diff line number Diff line change
@@ -1,10 +1,9 @@
/*
* Oracle Linux DTrace.
* Copyright (c) 2006, 2022, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2006, 2023, Oracle and/or its affiliates. All rights reserved.
* Licensed under the Universal Permissive License v 1.0 as shown at
* http://oss.oracle.com/licenses/upl.
*/
/* @@xfail: dtv2 - requires tracemem() */

/*
* ASSERTION:
Expand Down

0 comments on commit bbc7f14

Please sign in to comment.