[DTrace-devel] [PATCH 1/2] usdt: is-enabled probe support
Nick Alcock
nick.alcock at oracle.com
Wed Apr 19 15:44:12 UTC 2023
This implementation is in many ways similar to v1's, but contains one
significant simplification: rather than is-enabled probes appearing to
the user as a function that returns a 1 or 0, they appear as a function
that returns void and takes the address of a local variable: the
_IS_ENABLED macros use the GCC statement-expression extension
to declare and initialize a distinct local for each use of the
is-enabled probe:
({ uint32_t enabled = 0; \
__dtraceenabled_foo___bar(&enabled); \
enabled; })
The is-enabled trampoline writes a 1 into this local variable. This
allows the dt_link code to discard all the architecture-dependent code
dealing with return value handling and treat is-enabled probes just like
other USDT probes: it still tracks whether is-enabled probes are used,
but barely uses the info for anything but DOF-version validation.
The downside of this approach, of course, is that users need the
statement-expression extension to work, and that old is-enabled probes
from DTrace v1 aren't going to work without regeneration with dtrace
-G. Neither of these seem likely to be serious problems in practice. (An
upcoming commit will prevent v1 is-enabled probes from being mistaken
for v2 probes.)
We use #pragma system_header to suppress -pedantic warnings about
use of the extension.
Internally, there are tiny changes in the dtprobed and dt_pid
uprobe-registration-and-creation layers to put is-enabled probes in a
different uprobe group to prevent their names clashing with USDT probes
with the same name (dt_pid_is_enabled/ rather than dt_pid/). Normal USDT
probes enable the correspondinng is-enabled probe, if any, when they are
enabled: those probes have custom trampoline that copy a 64-bit-wide 1
into the first function parameter (and have truncated paramter-copying
code that avoids preserving any parameter but the first, because there
will never be any more).
Unanswered questions:
- is any of the stuff in dt_prov_usdt unnecessary? There's quite a lot
of boilerplate I am unsure of the need for.
- the is-enabled probes somehow get enabled even if I forget to
fix up the provider name to prvname_is_enabled in enable().
I have no idea how, but it makes me wonder if the special "USDT
enabling auto-enables the corresponding is-enabled probe" code is
actually needed.
Please ignore the code duplication between trampoline() and
trampoline_is_enabled(): this is temporary to make it easier to make
changes for getting globbed systemwide probing working later on.
Signed-off-by: Nick Alcock <nick.alcock at oracle.com>
---
dtprobed/dtprobed.c | 8 +-
libcommon/uprobes.c | 27 ++--
libcommon/uprobes.h | 22 +--
libdtrace/dt_cg.c | 34 ++++-
libdtrace/dt_cg.h | 3 +-
libdtrace/dt_link.c | 188 +++++++------------------
libdtrace/dt_pid.c | 31 ++--
libdtrace/dt_program.c | 28 ++--
libdtrace/dt_prov_fbt.c | 4 +-
libdtrace/dt_prov_uprobe.c | 178 ++++++++++++++++++++---
test/unittest/usdt/tst.enable.d | 3 +-
test/unittest/usdt/tst.enable_and.d | 3 +-
test/unittest/usdt/tst.enable_and_2.d | 3 +-
test/unittest/usdt/tst.enable_or_2.d | 3 +-
test/unittest/usdt/tst.enable_return.d | 3 +-
test/unittest/usdt/tst.enable_stmt.d | 3 +-
test/unittest/usdt/tst.enabled.sh | 3 +-
17 files changed, 326 insertions(+), 218 deletions(-)
diff --git a/dtprobed/dtprobed.c b/dtprobed/dtprobed.c
index af647d92d3355..3725dba2fe1c6 100644
--- a/dtprobed/dtprobed.c
+++ b/dtprobed/dtprobed.c
@@ -1,6 +1,6 @@
/*
* Oracle Linux DTrace; DOF-consumption and USDT-probe-creation daemon.
- * Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2022, 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.
*/
@@ -323,15 +323,13 @@ create_probe(pid_t pid, dof_parsed_t *provider, dof_parsed_t *probe,
{
const char *mod, *fun, *prb;
- if (tp->tracepoint.is_enabled)
- return; /* Not yet implemented. */
-
mod = probe->probe.name;
fun = mod + strlen(mod) + 1;
prb = fun + strlen(fun) + 1;
free(uprobe_create_from_addr(pid, tp->tracepoint.addr,
- provider->provider.name, mod, fun, prb));
+ tp->tracepoint.is_enabled, provider->provider.name,
+ mod, fun, prb));
}
/*
diff --git a/libcommon/uprobes.c b/libcommon/uprobes.c
index 8a45a1f2a2b9c..8c3cc6280e9a1 100644
--- a/libcommon/uprobes.c
+++ b/libcommon/uprobes.c
@@ -1,6 +1,6 @@
/*
* Oracle Linux DTrace.
- * Copyright (c) 2019, 2022, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2019, 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.
*/
@@ -209,13 +209,13 @@ uprobe_decode_name(const char *name)
}
char *
-uprobe_name(dev_t dev, ino_t ino, uint64_t addr, int isret)
+uprobe_name(dev_t dev, ino_t ino, uint64_t addr, int isret, int is_enabled)
{
char *name;
- if (asprintf(&name, "dt_pid/%c_%llx_%llx_%lx", isret ? 'r' : 'p',
- (unsigned long long)dev, (unsigned long long)ino,
- (unsigned long)addr) < 0)
+ if (asprintf(&name, "dt_pid%s/%c_%llx_%llx_%lx", is_enabled?"_is_enabled":"",
+ isret ? 'r' : 'p', (unsigned long long)dev,
+ (unsigned long long)ino, (unsigned long)addr) < 0)
return NULL;
return name;
@@ -229,7 +229,7 @@ uprobe_name(dev_t dev, ino_t ino, uint64_t addr, int isret)
*/
char *
uprobe_create_named(dev_t dev, ino_t ino, uint64_t addr, const char *spec, int isret,
- const char *prv, const char *mod, const char *fun,
+ int is_enabled, const char *prv, const char *mod, const char *fun,
const char *prb)
{
int fd = -1;
@@ -261,7 +261,7 @@ uprobe_create_named(dev_t dev, ino_t ino, uint64_t addr, const char *spec, int i
return NULL;
}
- name = uprobe_name(dev, ino, addr, isret);
+ name = uprobe_name(dev, ino, addr, isret, is_enabled);
if (!name)
goto out;
@@ -292,9 +292,10 @@ out:
* systemwide uprobe list.)
*/
char *
-uprobe_create(dev_t dev, ino_t ino, uint64_t addr, const char *spec, int isret)
+uprobe_create(dev_t dev, ino_t ino, uint64_t addr, const char *spec, int isret,
+ int is_enabled)
{
- return uprobe_create_named(dev, ino, addr, spec, isret,
+ return uprobe_create_named(dev, ino, addr, spec, isret, is_enabled,
NULL, NULL, NULL, NULL);
}
@@ -304,7 +305,7 @@ uprobe_create(dev_t dev, ino_t ino, uint64_t addr, const char *spec, int isret)
* are set, they are passed down as the name of the corresponding DTrace probe.
*/
char *
-uprobe_create_from_addr(pid_t pid, uint64_t addr, const char *prv,
+uprobe_create_from_addr(pid_t pid, uint64_t addr, int is_enabled, const char *prv,
const char *mod, const char *fun, const char *prb)
{
char *spec;
@@ -316,7 +317,7 @@ uprobe_create_from_addr(pid_t pid, uint64_t addr, const char *prv,
return NULL;
name = uprobe_create_named(mapp.pr_dev, mapp.pr_inum, addr, spec, 0,
- prv, mod, fun, prb);
+ is_enabled, prv, mod, fun, prb);
free(spec);
return name;
}
@@ -325,13 +326,13 @@ uprobe_create_from_addr(pid_t pid, uint64_t addr, const char *prv,
* Destroy a uprobe for a given device, address, and spec.
*/
int
-uprobe_delete(dev_t dev, ino_t ino, uint64_t addr, int isret)
+uprobe_delete(dev_t dev, ino_t ino, uint64_t addr, int isret, int is_enabled)
{
int fd = -1;
int rc = -1;
char *name;
- name = uprobe_name(dev, ino, addr, isret);
+ name = uprobe_name(dev, ino, addr, isret, is_enabled);
if (!name)
goto out;
diff --git a/libcommon/uprobes.h b/libcommon/uprobes.h
index fde6ba40235a2..bd5f79d1cc9b9 100644
--- a/libcommon/uprobes.h
+++ b/libcommon/uprobes.h
@@ -1,6 +1,6 @@
/*
* Oracle Linux DTrace; simple uprobe helper functions
- * Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2022, 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.
*/
@@ -15,17 +15,19 @@
extern char *uprobe_spec_by_addr(pid_t pid, ps_prochandle *P, uint64_t addr,
prmap_t *mapp);
-extern char *uprobe_name(dev_t dev, ino_t ino, uint64_t addr, int isret);
+extern char *uprobe_name(dev_t dev, ino_t ino, uint64_t addr, int isret,
+ int is_enabled);
extern char *uprobe_create_named(dev_t dev, ino_t ino, uint64_t addr,
- const char *spec, int isret, const char *prv,
- const char *mod, const char *fun,
- const char *prb);
+ const char *spec, int isret, int is_enabled,
+ const char *prv, const char *mod,
+ const char *fun, const char *prb);
extern char *uprobe_create(dev_t dev, ino_t ino, uint64_t addr, const char *spec,
- int isret);
-extern char *uprobe_create_from_addr(pid_t pid, uint64_t addr, const char *prv,
- const char *mod, const char *fun,
- const char *prb);
-extern int uprobe_delete(dev_t dev, ino_t ino, uint64_t addr, int isret);
+ int isret, int is_enabled);
+extern char *uprobe_create_from_addr(pid_t pid, uint64_t addr, int is_enabled,
+ const char *prv, const char *mod,
+ const char *fun, const char *prb);
+extern int uprobe_delete(dev_t dev, ino_t ino, uint64_t addr, int isret,
+ int is_enabled);
extern char *uprobe_encode_name(const char *);
extern char *uprobe_decode_name(const char *);
diff --git a/libdtrace/dt_cg.c b/libdtrace/dt_cg.c
index 14ae21f764f59..27ca56438afac 100644
--- a/libdtrace/dt_cg.c
+++ b/libdtrace/dt_cg.c
@@ -314,11 +314,13 @@ dt_cg_tramp_copy_regs(dt_pcb_t *pcb)
* function: if zero, they are laid out as at the call instruction, before the
* function is called (as is done for e.g. usdt).
*
+ * if one_arg is set, copy only one arg.
+ *
* The caller must ensure that %r7 and %r8 contain the values set by the
* dt_cg_tramp_prologue*() functions.
*/
void
-dt_cg_tramp_copy_args_from_regs(dt_pcb_t *pcb, int called)
+dt_cg_tramp_copy_args_from_regs(dt_pcb_t *pcb, int called, int one_arg)
{
dtrace_hdl_t *dtp = pcb->pcb_hdl;
dt_irlist_t *dlp = &pcb->pcb_ir;
@@ -332,6 +334,10 @@ dt_cg_tramp_copy_args_from_regs(dt_pcb_t *pcb, int called)
*/
emit(dlp, BPF_LOAD(BPF_DW, BPF_REG_0, BPF_REG_8, PT_REGS_ARG0));
emit(dlp, BPF_STORE(BPF_DW, BPF_REG_7, DMST_ARG(0), BPF_REG_0));
+
+ if (one_arg)
+ return;
+
emit(dlp, BPF_LOAD(BPF_DW, BPF_REG_0, BPF_REG_8, PT_REGS_ARG1));
emit(dlp, BPF_STORE(BPF_DW, BPF_REG_7, DMST_ARG(1), BPF_REG_0));
emit(dlp, BPF_LOAD(BPF_DW, BPF_REG_0, BPF_REG_8, PT_REGS_ARG2));
@@ -1014,6 +1020,32 @@ dt_cg_memcpy(dt_irlist_t *dlp, dt_regset_t *drp, int dst, int src, size_t size)
dt_regset_free(drp, BPF_REG_0);
}
+/*
+ * Copy the given immediate value into the address given by the specified probe
+ * argument.
+ */
+void
+dt_cg_tramp_copyout_val(dt_pcb_t *pcb, uint32_t val, int arg)
+{
+ dt_regset_t *drp = pcb->pcb_regs;
+ dt_irlist_t *dlp = &pcb->pcb_ir;
+
+ emit(dlp, BPF_STORE_IMM(BPF_DW, BPF_REG_FP, DT_TRAMP_SP_SLOT(0), val));
+
+ if (dt_regset_xalloc_args(drp) == -1)
+ longjmp(yypcb->pcb_jmpbuf, EDT_NOREG);
+ emit(dlp, BPF_LOAD(BPF_DW, BPF_REG_1, BPF_REG_7, DMST_ARG(arg)));
+ emit(dlp, BPF_MOV_REG(BPF_REG_2, BPF_REG_FP));
+ emit(dlp, BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, DT_TRAMP_SP_SLOT(0)));
+ emit(dlp, BPF_MOV_IMM(BPF_REG_3, sizeof(uint32_t)));
+ dt_regset_xalloc(drp, BPF_REG_0);
+ emit(dlp, BPF_CALL_HELPER(BPF_FUNC_probe_write_user));
+
+ /* XXX any point error-checking here? What can we possibly do? */
+ dt_regset_free(drp, BPF_REG_0);
+ dt_regset_free_args(drp);
+}
+
static void
dt_cg_spill_store(int reg)
{
diff --git a/libdtrace/dt_cg.h b/libdtrace/dt_cg.h
index 95bf507ff7fb1..320862682cb43 100644
--- a/libdtrace/dt_cg.h
+++ b/libdtrace/dt_cg.h
@@ -24,9 +24,10 @@ extern void dt_cg_tramp_prologue_act(dt_pcb_t *pcb, dt_activity_t act);
extern void dt_cg_tramp_prologue(dt_pcb_t *pcb);
extern void dt_cg_tramp_clear_regs(dt_pcb_t *pcb);
extern void dt_cg_tramp_copy_regs(dt_pcb_t *pcb);
-extern void dt_cg_tramp_copy_args_from_regs(dt_pcb_t *pcb, int called);
+extern void dt_cg_tramp_copy_args_from_regs(dt_pcb_t *pcb, int called, int one_arg);
extern void dt_cg_tramp_copy_pc_from_regs(dt_pcb_t *pcb);
extern void dt_cg_tramp_copy_rval_from_regs(dt_pcb_t *pcb);
+extern void dt_cg_tramp_copyout_val(dt_pcb_t *pcb, uint32_t val, int arg);
extern void dt_cg_tramp_save_args(dt_pcb_t *pcb);
extern void dt_cg_tramp_restore_args(dt_pcb_t *pcb);
extern void dt_cg_tramp_call_clauses(dt_pcb_t *pcb, const dt_probe_t *prp,
diff --git a/libdtrace/dt_link.c b/libdtrace/dt_link.c
index 5daaf2b02212a..e6059e9840cde 100644
--- a/libdtrace/dt_link.c
+++ b/libdtrace/dt_link.c
@@ -1,6 +1,6 @@
/*
* Oracle Linux DTrace.
- * Copyright (c) 2008, 2022, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2008, 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.
*/
@@ -775,8 +775,7 @@ dt_elf_symtab_lookup(Elf_Data *data_sym, int nsym, uintptr_t addr, uint_t shn,
/*ARGSUSED*/
static int
-dt_modtext(dtrace_hdl_t *dtp, char *p, int isenabled, GElf_Rela *rela,
- uint32_t *off)
+dt_modtext(dtrace_hdl_t *dtp, char *p, GElf_Rela *rela, uint32_t *off)
{
uint32_t *ip;
@@ -801,25 +800,18 @@ dt_modtext(dtrace_hdl_t *dtp, char *p, int isenabled, GElf_Rela *rela,
* invocation. Check to see if the present instruction sequence matches
* the one we would install below.
*/
- if (isenabled) {
- if (ip[0] == DT_OP_NOP) {
+ if (DT_IS_RESTORE(ip[1])) {
+ if (ip[0] == DT_OP_RET) {
(*off) += sizeof(ip[0]);
return 0;
}
+ } else if (DT_IS_MOV_O7(ip[1])) {
+ if (DT_IS_RETL(ip[0]))
+ return 0;
} else {
- if (DT_IS_RESTORE(ip[1])) {
- if (ip[0] == DT_OP_RET) {
- (*off) += sizeof(ip[0]);
- return 0;
- }
- } else if (DT_IS_MOV_O7(ip[1])) {
- if (DT_IS_RETL(ip[0]))
- return 0;
- } else {
- if (ip[0] == DT_OP_NOP) {
- (*off) += sizeof(ip[0]);
- return 0;
- }
+ if (ip[0] == DT_OP_NOP) {
+ (*off) += sizeof(ip[0]);
+ return 0;
}
}
@@ -832,58 +824,32 @@ dt_modtext(dtrace_hdl_t *dtp, char *p, int isenabled, GElf_Rela *rela,
return -1;
}
- if (isenabled) {
- /*
- * It would necessarily indicate incorrect usage if an is-
- * enabled probe were tail-called so flag that as an error.
- * It's also potentially (very) tricky to handle gracefully,
- * but could be done if this were a desired use scenario.
- */
- if (DT_IS_RESTORE(ip[1]) || DT_IS_MOV_O7(ip[1])) {
- dt_dprintf("tail call to is-enabled probe at %llx\n",
- (unsigned long long)rela->r_offset);
- return -1;
- }
-
-
- /*
- * On SPARC, we take advantage of the fact that the first
- * argument shares the same register as for the return value.
- * The macro handles the work of zeroing that register so we
- * don't need to do anything special here. We instrument the
- * instruction in the delay slot as we'll need to modify the
- * return register after that instruction has been emulated.
- */
- ip[0] = DT_OP_NOP;
+ /*
+ * If the call is followed by a restore, it's a tail call so
+ * change the call to a ret. If the call if followed by a mov
+ * of a register into %o7, it's a tail call in leaf context
+ * so change the call to a retl-like instruction that returns
+ * to that register value + 8 (rather than the typical %o7 +
+ * 8); the delay slot instruction is left, but should have no
+ * effect. Otherwise we change the call to be a nop. We
+ * identify the subsequent instruction as the probe point in
+ * all but the leaf tail-call case to ensure that arguments to
+ * the probe are complete and consistent. An astute, though
+ * largely hypothetical, observer would note that there is the
+ * possibility of a false-positive probe firing if the function
+ * contained a branch to the instruction in the delay slot of
+ * the call. Fixing this would require significant in-kernel
+ * modifications, and isn't worth doing until we see it in the
+ * wild.
+ */
+ if (DT_IS_RESTORE(ip[1])) {
+ ip[0] = DT_OP_RET;
(*off) += sizeof(ip[0]);
+ } else if (DT_IS_MOV_O7(ip[1])) {
+ ip[0] = DT_MAKE_RETL(DT_RS2(ip[1]));
} else {
- /*
- * If the call is followed by a restore, it's a tail call so
- * change the call to a ret. If the call if followed by a mov
- * of a register into %o7, it's a tail call in leaf context
- * so change the call to a retl-like instruction that returns
- * to that register value + 8 (rather than the typical %o7 +
- * 8); the delay slot instruction is left, but should have no
- * effect. Otherwise we change the call to be a nop. We
- * identify the subsequent instruction as the probe point in
- * all but the leaf tail-call case to ensure that arguments to
- * the probe are complete and consistent. An astute, though
- * largely hypothetical, observer would note that there is the
- * possibility of a false-positive probe firing if the function
- * contained a branch to the instruction in the delay slot of
- * the call. Fixing this would require significant in-kernel
- * modifications, and isn't worth doing until we see it in the
- * wild.
- */
- if (DT_IS_RESTORE(ip[1])) {
- ip[0] = DT_OP_RET;
- (*off) += sizeof(ip[0]);
- } else if (DT_IS_MOV_O7(ip[1])) {
- ip[0] = DT_MAKE_RETL(DT_RS2(ip[1]));
- } else {
- ip[0] = DT_OP_NOP;
- (*off) += sizeof(ip[0]);
- }
+ ip[0] = DT_OP_NOP;
+ (*off) += sizeof(ip[0]);
}
return 0;
@@ -895,13 +861,9 @@ dt_modtext(dtrace_hdl_t *dtp, char *p, int isenabled, GElf_Rela *rela,
#define DT_OP_RET 0xc3
#define DT_OP_CALL 0xe8
#define DT_OP_JMP32 0xe9
-#define DT_OP_REX_RAX 0x48
-#define DT_OP_XOR_EAX_0 0x33
-#define DT_OP_XOR_EAX_1 0xc0
static int
-dt_modtext(dtrace_hdl_t *dtp, char *p, int isenabled, GElf_Rela *rela,
- uint32_t *off)
+dt_modtext(dtrace_hdl_t *dtp, char *p, GElf_Rela *rela, uint32_t *off)
{
uint8_t *ip = (uint8_t *)(p + rela->r_offset - 1);
uint8_t ret;
@@ -924,37 +886,20 @@ dt_modtext(dtrace_hdl_t *dtp, char *p, int isenabled, GElf_Rela *rela,
*/
if (GELF_R_TYPE(rela->r_info) != R_386_PC32 &&
GELF_R_TYPE(rela->r_info) != R_386_PLT32 &&
- GELF_R_TYPE(rela->r_info) != R_386_NONE)
+ GELF_R_TYPE(rela->r_info) != R_386_NONE) {
+ dt_dprintf("unexpected reloc type %li\n", GELF_R_TYPE(rela->r_info));
return -1;
+ }
/*
* We may have already processed this object file in an earlier linker
* invocation. Check to see if the present instruction sequence matches
- * the one we would install. For is-enabled probes, we advance the
- * offset to the first nop instruction in the sequence to match the
- * text modification code below.
+ * the one we would install.
*/
- if (!isenabled) {
- if ((ip[0] == DT_OP_NOP || ip[0] == DT_OP_RET) &&
- ip[1] == DT_OP_NOP && ip[2] == DT_OP_NOP &&
- ip[3] == DT_OP_NOP && ip[4] == DT_OP_NOP)
- return 0;
- } else if (dtp->dt_oflags & DTRACE_O_ILP32) {
- if (ip[0] == DT_OP_XOR_EAX_0 && ip[1] == DT_OP_XOR_EAX_1 &&
- (ip[2] == DT_OP_NOP || ip[2] == DT_OP_RET) &&
- ip[3] == DT_OP_NOP && ip[4] == DT_OP_NOP) {
- (*off) += 2;
- return 0;
- }
- } else {
- if (ip[0] == DT_OP_REX_RAX &&
- ip[1] == DT_OP_XOR_EAX_0 && ip[2] == DT_OP_XOR_EAX_1 &&
- (ip[3] == DT_OP_NOP || ip[3] == DT_OP_RET) &&
- ip[4] == DT_OP_NOP) {
- (*off) += 3;
- return 0;
- }
- }
+ if ((ip[0] == DT_OP_NOP || ip[0] == DT_OP_RET) &&
+ ip[1] == DT_OP_NOP && ip[2] == DT_OP_NOP &&
+ ip[3] == DT_OP_NOP && ip[4] == DT_OP_NOP)
+ return 0;
/*
* We expect either a call instrution with a 32-bit displacement or a
@@ -969,33 +914,13 @@ dt_modtext(dtrace_hdl_t *dtp, char *p, int isenabled, GElf_Rela *rela,
ret = (ip[0] == DT_OP_JMP32) ? DT_OP_RET : DT_OP_NOP;
/*
- * Establish the instruction sequence -- all nops for probes, and an
- * instruction to clear the return value register (%eax/%rax) followed
- * by nops for is-enabled probes. For is-enabled probes, we advance
- * the offset to the first nop. This isn't stricly necessary but makes
- * for more readable disassembly when the probe is enabled.
+ * Establish the instruction sequence: all nops.
*/
- if (!isenabled) {
- ip[0] = ret;
- ip[1] = DT_OP_NOP;
- ip[2] = DT_OP_NOP;
- ip[3] = DT_OP_NOP;
- ip[4] = DT_OP_NOP;
- } else if (dtp->dt_oflags & DTRACE_O_ILP32) {
- ip[0] = DT_OP_XOR_EAX_0;
- ip[1] = DT_OP_XOR_EAX_1;
- ip[2] = ret;
- ip[3] = DT_OP_NOP;
- ip[4] = DT_OP_NOP;
- (*off) += 2;
- } else {
- ip[0] = DT_OP_REX_RAX;
- ip[1] = DT_OP_XOR_EAX_0;
- ip[2] = DT_OP_XOR_EAX_1;
- ip[3] = ret;
- ip[4] = DT_OP_NOP;
- (*off) += 3;
- }
+ ip[0] = ret;
+ ip[1] = DT_OP_NOP;
+ ip[2] = DT_OP_NOP;
+ ip[3] = DT_OP_NOP;
+ ip[4] = DT_OP_NOP;
return 0;
}
@@ -1008,8 +933,7 @@ dt_modtext(dtrace_hdl_t *dtp, char *p, int isenabled, GElf_Rela *rela,
#define DT_OP_JUMP26 0x14000000
static int
-dt_modtext(dtrace_hdl_t *dtp, char *p, int isenabled, GElf_Rela *rela,
- uint32_t *off)
+dt_modtext(dtrace_hdl_t *dtp, char *p, GElf_Rela *rela, uint32_t *off)
{
uint32_t *ip;
@@ -1050,11 +974,9 @@ dt_modtext(dtrace_hdl_t *dtp, char *p, int isenabled, GElf_Rela *rela,
}
/*
- * On arm64, we do not have to differentiate between regular probes and
- * is-enabled probes. Both cases are encoded as a regular branch for
- * non-tail call locations, and a jump for tail call locations. Calls
- * are to be converted into a no-op whereas jumps should become a
- * return.
+ * On arm64, we encode all probes as a regular branch for non-tail call
+ * locations, and a jump for tail call locations. Calls are to be
+ * converted into a no-op whereas jumps should become a return.
*/
if (ip[0] == DT_OP_CALL26)
ip[0] = DT_OP_NOP;
@@ -1502,10 +1424,8 @@ process_obj(dtrace_hdl_t *dtp, const char *obj, int *eprobesp)
assert(fsym.st_value <= rela.r_offset);
off = rela.r_offset - fsym.st_value;
- if (dt_modtext(dtp, data_tgt->d_buf, eprobe,
- &rela, &off) != 0) {
+ if (dt_modtext(dtp, data_tgt->d_buf, &rela, &off) != 0)
goto err;
- }
if (dt_probe_define(pvp, prp, s, r, off, eprobe) != 0)
return dt_link_error(dtp, elf, fd, bufs,
diff --git a/libdtrace/dt_pid.c b/libdtrace/dt_pid.c
index fd9e0d1da62dd..06bd7a4dd24aa 100644
--- a/libdtrace/dt_pid.c
+++ b/libdtrace/dt_pid.c
@@ -1,6 +1,6 @@
/*
* Oracle Linux DTrace.
- * Copyright (c) 2010, 2022, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2010, 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.
*/
@@ -626,6 +626,8 @@ dt_pid_create_usdt_probes(dtrace_hdl_t *dtp, dt_proc_t *dpr,
dev_t dev;
ino_t inum;
uint64_t off;
+ int is_enabled;
+ const char *fmt;
unsigned long long dev_ll, inum_ll;
char *inum_str = NULL;
char *spec = NULL;
@@ -634,11 +636,23 @@ dt_pid_create_usdt_probes(dtrace_hdl_t *dtp, dt_proc_t *dpr,
pid_probespec_t psp;
#define UPROBE_PREFIX "p:dt_pid/p_"
- if (strncmp(buf, UPROBE_PREFIX, strlen(UPROBE_PREFIX)) != 0)
+#define UPROBE_IS_ENABLED_PREFIX "p:dt_pid_is_enabled/p_"
+#define UPROBE_PROBE_FMT "%llx_%llx_%lx %ms P%m[^= ]=\\1 M%m[^= ]=\\2 F%m[^= ]=\\3 N%m[^= ]=\\4"
+#define UPROBE_FMT UPROBE_PREFIX UPROBE_PROBE_FMT
+#define UPROBE_IS_ENABLED_FMT UPROBE_IS_ENABLED_PREFIX UPROBE_PROBE_FMT
+
+ if (strncmp(buf, UPROBE_PREFIX, strlen(UPROBE_PREFIX)) == 0) {
+ is_enabled = 0;
+ fmt = UPROBE_FMT;
+ } else if (strncmp(buf, UPROBE_IS_ENABLED_PREFIX,
+ strlen(UPROBE_IS_ENABLED_PREFIX)) == 0) {
+ is_enabled = 1;
+ fmt = UPROBE_IS_ENABLED_FMT;
+ }
+ else /* Not a DTrace uprobe. */
continue;
- switch (sscanf(buf, "p:dt_pid/p_%llx_%llx_%lx %ms "
- "P%m[^= ]=\\1 M%m[^= ]=\\2 F%m[^= ]=\\3 N%m[^= ]=\\4", &dev_ll, &inum_ll,
+ switch (sscanf(buf, fmt, &dev_ll, &inum_ll,
&off, &spec, &eprv, &emod, &efun, &eprb)) {
case 8: /* Includes dtrace probe names: decode them. */
prv = uprobe_decode_name(eprv);
@@ -664,9 +678,7 @@ dt_pid_create_usdt_probes(dtrace_hdl_t *dtp, dt_proc_t *dpr,
* Make the underlying probe, if not already present.
*/
memset(&psp, 0, sizeof(pid_probespec_t));
-
- /* FIXME: DTPPT_IS_ENABLED needs to be supported also. */
- psp.pps_type = DTPPT_OFFSETS;
+ psp.pps_type = is_enabled ? DTPPT_IS_ENABLED : DTPPT_OFFSETS;
/*
* These components are only used for creation of an underlying
@@ -732,8 +744,9 @@ dt_pid_create_usdt_probes(dtrace_hdl_t *dtp, dt_proc_t *dpr,
if (pvp->impl->provide_probe(dtp, &psp) < 0 && pdp) {
dt_pid_error(dtp, pcb, dpr, D_PROC_USDT,
- "failed to instantiate probe %s for pid %d: %s",
- pdp->prb, dpr->dpr_pid,
+ "failed to instantiate %sprobe %s for pid %d: %s",
+ is_enabled ? "is-enabled ": "", pdp->prb,
+ dpr->dpr_pid,
dtrace_errmsg(dtp, dtrace_errno(dtp)));
ret = -1;
}
diff --git a/libdtrace/dt_program.c b/libdtrace/dt_program.c
index a95d0eefdb1a2..a4b052fc47603 100644
--- a/libdtrace/dt_program.c
+++ b/libdtrace/dt_program.c
@@ -1,6 +1,6 @@
/*
* Oracle Linux DTrace.
- * Copyright (c) 2009, 2021, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2009, 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.
*/
@@ -368,12 +368,8 @@ dt_header_decl(dt_idhash_t *dhp, dt_ident_t *idp, void *data)
return dt_set_errno(dtp, errno);
if (fprintf(infop->dthi_out,
- "#if !defined(__aarch64__) && !defined(__sparc)\n"
- "extern int __dtraceenabled_%s___%s(void);\n"
- "#else\n"
- "extern int __dtraceenabled_%s___%s(long);\n"
- "#endif\n",
- infop->dthi_pfname, fname, infop->dthi_pfname, fname) < 0)
+ "extern void __dtraceenabled_%s___%s(uint32_t *flag);\n",
+ infop->dthi_pfname, fname) < 0)
return dt_set_errno(dtp, errno);
return 0;
@@ -436,17 +432,18 @@ dt_header_probe(dt_idhash_t *dhp, dt_ident_t *idp, void *data)
if (!infop->dthi_empty) {
if (fprintf(infop->dthi_out,
- "#if !defined(__aarch64__) && !defined(__sparc)\n"
+ "#ifdef __GNUC__\n"
"#define\t%s_%s_ENABLED() \\\n"
- "\t__dtraceenabled_%s___%s()\n"
+ "\t({ uint32_t enabled = 0; \\\n"
+ "\t__dtraceenabled_%s___%s(&enabled); \\\n"
+ "\t enabled; })\n"
"#else\n"
- "#define\t%s_%s_ENABLED() \\\n"
- "\t__dtraceenabled_%s___%s(0)\n"
+ "#define\t%s_%s_ENABLED() (1)\\n"
+ "#endif\n"
"#endif\n",
infop->dthi_pmname, mname,
infop->dthi_pfname, fname,
- infop->dthi_pmname, mname,
- infop->dthi_pfname, fname) < 0)
+ infop->dthi_pmname, mname) < 0)
return dt_set_errno(dtp, errno);
} else {
@@ -536,6 +533,11 @@ dtrace_program_header(dtrace_hdl_t *dtp, FILE *out, const char *fname)
if (fprintf(out, "#ifdef\t__cplusplus\nextern \"C\" {\n#endif\n\n") < 0)
return -1;
+ if (fprintf(out, "#ifdef\t__GNUC__\n"
+ "#pragma GCC system_header\n"
+ "#endif\n\n") < 0)
+ return -1;
+
while ((pvp = dt_htab_next(dtp->dt_provs, &it)) != NULL) {
if (dt_header_provider(dtp, pvp, out) != 0) {
dt_htab_next_destroy(it);
diff --git a/libdtrace/dt_prov_fbt.c b/libdtrace/dt_prov_fbt.c
index add76c55f3ae8..be0e6248e6ac0 100644
--- a/libdtrace/dt_prov_fbt.c
+++ b/libdtrace/dt_prov_fbt.c
@@ -1,6 +1,6 @@
/*
* Oracle Linux DTrace.
- * Copyright (c) 2019, 2022, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2019, 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.
*
@@ -175,7 +175,7 @@ static void trampoline(dt_pcb_t *pcb, uint_t exitlbl)
dt_cg_xsetx(dlp, NULL, DT_LBL_NONE, BPF_REG_0, -1);
emit(dlp, BPF_STORE(BPF_DW, BPF_REG_7, DMST_ARG(0), BPF_REG_0));
} else
- dt_cg_tramp_copy_args_from_regs(pcb, 1);
+ dt_cg_tramp_copy_args_from_regs(pcb, 1, 0);
dt_cg_tramp_epilogue(pcb);
}
diff --git a/libdtrace/dt_prov_uprobe.c b/libdtrace/dt_prov_uprobe.c
index f85d15297e910..d3bd2097ac0ae 100644
--- a/libdtrace/dt_prov_uprobe.c
+++ b/libdtrace/dt_prov_uprobe.c
@@ -1,6 +1,6 @@
/*
* Oracle Linux DTrace.
- * Copyright (c) 2021, 2022, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2021, 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.
*
@@ -23,13 +23,15 @@
#include "uprobes.h"
/* Provider name for the underlying probes. */
-static const char prvname[] = "uprobe";
+static const char prvname[] = "uprobe";
+static const char prvname_is_enabled[] = "uprobe__is_enabled";
-#define UPROBE_EVENTS TRACEFS "uprobe_events"
+#define UPROBE_EVENTS TRACEFS "uprobe_events"
#define PP_IS_MINE 1
#define PP_IS_RETURN 2
#define PP_IS_FUNCALL 4
+#define PP_IS_ENABLED 8
typedef struct dt_uprobe {
dev_t dev;
@@ -54,12 +56,15 @@ static const dtrace_pattr_t pattr = {
{ DTRACE_STABILITY_PRIVATE, DTRACE_STABILITY_PRIVATE, DTRACE_CLASS_UNKNOWN },
};
+dt_provimpl_t dt_uprobe_is_enabled;
dt_provimpl_t dt_pid;
dt_provimpl_t dt_usdt;
static int populate(dtrace_hdl_t *dtp)
{
dt_provider_create(dtp, dt_uprobe.name, &dt_uprobe, &pattr);
+ dt_provider_create(dtp, dt_uprobe_is_enabled.name,
+ &dt_uprobe_is_enabled, &pattr);
dt_provider_create(dtp, dt_pid.name, &dt_pid, &pattr);
dt_provider_create(dtp, dt_usdt.name, &dt_usdt, &pattr);
@@ -115,6 +120,7 @@ static dt_probe_t *create_underlying(dtrace_hdl_t *dtp,
dtrace_probedesc_t pd;
dt_probe_t *prp;
dt_uprobe_t *upp;
+ int is_enabled = 0;
/*
* The underlying probes (uprobes) represent the tracepoints that pid
@@ -136,6 +142,9 @@ static dt_probe_t *create_underlying(dtrace_hdl_t *dtp,
case DTPPT_RETURN:
strcpy(prb, "return");
break;
+ case DTPPT_IS_ENABLED:
+ is_enabled = 1;
+ /* Fallthrough. */
case DTPPT_ENTRY:
case DTPPT_OFFSETS:
snprintf(prb, sizeof(prb), "%lx", psp->pps_off);
@@ -146,7 +155,7 @@ static dt_probe_t *create_underlying(dtrace_hdl_t *dtp,
}
pd.id = DTRACE_IDNONE;
- pd.prv = prvname;
+ pd.prv = is_enabled ? prvname_is_enabled : prvname;
pd.mod = mod;
pd.fun = psp->pps_fun;
pd.prb = prb;
@@ -156,7 +165,7 @@ static dt_probe_t *create_underlying(dtrace_hdl_t *dtp,
dt_provider_t *pvp;
/* Get the provider for underlying probes. */
- pvp = dt_provider_lookup(dtp, prvname);
+ pvp = dt_provider_lookup(dtp, pd.prv);
if (pvp == NULL)
return NULL;
@@ -181,8 +190,18 @@ static dt_probe_t *create_underlying(dtrace_hdl_t *dtp,
} else
upp = prp->prv_data;
- if (psp->pps_type == DTPPT_RETURN)
- upp->flags |= PP_IS_RETURN;
+ switch (psp->pps_type) {
+ case DTPPT_RETURN:
+ upp->flags |= PP_IS_RETURN;
+ break;
+ case DTPPT_IS_ENABLED:
+ upp->flags |= PP_IS_ENABLED;
+ break;
+ default: ;
+ /*
+ * No flags needed for other types.
+ */
+ }
return prp;
@@ -302,7 +321,8 @@ static int provide_pid_probe(dtrace_hdl_t *dtp, const pid_probespec_t *psp)
static int provide_usdt_probe(dtrace_hdl_t *dtp, const pid_probespec_t *psp)
{
- if (psp->pps_type != DTPPT_OFFSETS) {
+ if (psp->pps_type != DTPPT_OFFSETS &&
+ psp->pps_type != DTPPT_IS_ENABLED) {
dt_dprintf("pid: unknown USDT probe type %i\n", psp->pps_type);
return -1;
}
@@ -310,7 +330,7 @@ static int provide_usdt_probe(dtrace_hdl_t *dtp, const pid_probespec_t *psp)
return provide_probe(dtp, psp, psp->pps_prb, &dt_usdt, PP_IS_FUNCALL);
}
-static void enable(dtrace_hdl_t *dtp, dt_probe_t *prp)
+static void enable(dtrace_hdl_t *dtp, dt_probe_t *prp, int is_enabled)
{
const list_probe_t *pup;
@@ -318,12 +338,26 @@ static void enable(dtrace_hdl_t *dtp, dt_probe_t *prp)
/*
* We need to enable the underlying probes (if not enabled yet).
+ *
+ * If necessary, we need to enable is-enabled probes too (if they
+ * exist).
*/
for (pup = prp->prv_data; pup != NULL; pup = dt_list_next(pup)) {
dt_probe_t *uprp = pup->probe;
dt_probe_enable(dtp, uprp);
}
+ if (is_enabled) {
+ dtrace_probedesc_t pd;
+ dt_probe_t *iep;
+
+ memcpy(&pd, &prp->desc, sizeof(pd));
+ pd.prv = prvname_is_enabled;
+ iep = dt_probe_lookup(dtp, &pd);
+ if (iep != NULL)
+ dt_probe_enable(dtp, iep);
+ }
+
/*
* Finally, ensure we're in the list of enablings as well.
* (This ensures that, among other things, the probes map
@@ -333,6 +367,19 @@ static void enable(dtrace_hdl_t *dtp, dt_probe_t *prp)
dt_list_append(&dtp->dt_enablings, prp);
}
+static void enable_plain(dtrace_hdl_t *dtp, dt_probe_t *prp)
+{
+ enable(dtp, prp, 0);
+}
+
+/*
+ * USDT enabling has to enable any is-enabled probes as well.
+ */
+static void enable_usdt(dtrace_hdl_t *dtp, dt_probe_t *prp)
+{
+ enable(dtp, prp, 1);
+}
+
/*
* Generate a BPF trampoline for a pid probe.
*
@@ -365,7 +412,8 @@ static void trampoline(dt_pcb_t *pcb, uint_t exitlbl)
dt_cg_tramp_copy_rval_from_regs(pcb);
else
dt_cg_tramp_copy_args_from_regs(pcb,
- !(upp->flags & PP_IS_FUNCALL));
+ !(upp->flags & PP_IS_FUNCALL),
+ 0);
/*
* Retrieve the PID of the process that caused the probe to fire.
@@ -420,6 +468,88 @@ static void trampoline(dt_pcb_t *pcb, uint_t exitlbl)
dt_cg_tramp_return(pcb);
}
+/*
+ * Generate a BPF trampoline for an is-enabled probe. The is-enabled probe
+ * prototype looks like:
+ *
+ * int is_enabled(int *arg)
+ *
+ * The trampoline dereferences the passed-in arg and writes 1 into it if this is
+ * one of the processes for which the probe is enabled.
+ */
+static void trampoline_is_enabled(dt_pcb_t *pcb, uint_t exitlbl)
+{
+ dt_irlist_t *dlp = &pcb->pcb_ir;
+ const dt_probe_t *prp = pcb->pcb_probe;
+ const dt_uprobe_t *upp = prp->prv_data;
+ const list_probe_t *pop;
+ uint_t lbl_exit = pcb->pcb_exitlbl;
+
+ dt_cg_tramp_prologue(pcb);
+
+ /*
+ * After the dt_cg_tramp_prologue() call, we have:
+ * // (%r7 = dctx->mst)
+ * // (%r8 = dctx->ctx)
+ */
+
+ dt_cg_tramp_copy_regs(pcb);
+ dt_cg_tramp_copy_args_from_regs(pcb,
+ !(upp->flags & PP_IS_FUNCALL), 1);
+
+ /*
+ * Retrieve the PID of the process that caused the probe to fire.
+ */
+ emit(dlp, BPF_CALL_HELPER(BPF_FUNC_get_current_pid_tgid));
+ emit(dlp, BPF_ALU64_IMM(BPF_RSH, BPF_REG_0, 32));
+
+ /*
+ * Generate a composite conditional clause, as above, except that rather
+ * than emitting call_clauses, we emit copyouts instead, using
+ * dt_cg_copyout_reg().
+ *
+ * if (pid == PID1) {
+ * *arg0 = 1;
+ * goto exit;
+ * } else if (pid == PID2) {
+ * *arg0 = 1;
+ * goto exit;
+ * } else if (pid == ...) {
+ * < ... >
+ * }
+ *
+ * It is valid and safe to use %r0 to hold the pid value because there
+ * are no assignments to %r0 possible in between the conditional
+ * statements.
+ */
+ for (pop = dt_list_next(&upp->probes); pop != NULL;
+ pop = dt_list_next(pop)) {
+ const dt_probe_t *pprp = pop->probe;
+ uint_t lbl_next = dt_irlist_label(dlp);
+ pid_t pid;
+ dt_ident_t *idp;
+
+ pid = dt_pid_get_pid(pprp->desc, pcb->pcb_hdl, pcb, NULL);
+ assert(pid != -1);
+
+ idp = dt_dlib_add_probe_var(pcb->pcb_hdl, pprp);
+ assert(idp != NULL);
+
+ /*
+ * Check whether this pid-provider probe serves the current
+ * process, and copy out a 1 into arg 0 if so.
+ */
+ emit(dlp, BPF_BRANCH_IMM(BPF_JNE, BPF_REG_0, pid, lbl_next));
+ dt_cg_tramp_copyout_val(pcb, 1, 0);
+ emit(dlp, BPF_JUMP(lbl_exit));
+ emitl(dlp, lbl_next,
+ BPF_NOP());
+ }
+
+ dt_cg_tramp_return(pcb);
+}
+
+
static int attach(dtrace_hdl_t *dtp, const dt_probe_t *prp, int bpf_fd)
{
dt_uprobe_t *upp = prp->prv_data;
@@ -441,7 +571,7 @@ static int attach(dtrace_hdl_t *dtp, const dt_probe_t *prp, int bpf_fd)
return -ENOENT;
prb = uprobe_create(upp->dev, upp->inum, upp->off, spec,
- upp->flags & PP_IS_RETURN);
+ upp->flags & PP_IS_RETURN, 0);
free(spec);
/*
@@ -453,7 +583,8 @@ static int attach(dtrace_hdl_t *dtp, const dt_probe_t *prp, int bpf_fd)
if (prb == NULL)
prb = uprobe_name(upp->dev, upp->inum, upp->off,
- upp->flags & PP_IS_RETURN);
+ upp->flags & PP_IS_RETURN,
+ upp->flags & PP_IS_ENABLED);
/* open format file */
rc = asprintf(&fn, "%s%s/format", EVENTSFS, prb);
@@ -509,8 +640,9 @@ static void detach(dtrace_hdl_t *dtp, const dt_probe_t *prp)
if (!(upp->flags & PP_IS_MINE))
return;
- uprobe_delete(upp->dev, upp->inum, upp->off, upp->flags & PP_IS_RETURN);
-}
+ uprobe_delete(upp->dev, upp->inum, upp->off, upp->flags & PP_IS_RETURN,
+ upp->flags & PP_IS_ENABLED);
+ }
/*
* Used for underlying probes (uprobes).
@@ -526,6 +658,20 @@ dt_provimpl_t dt_uprobe = {
.probe_destroy = &probe_destroy_underlying,
};
+/*
+ * Used for underlying is-enabled uprobes.
+ */
+dt_provimpl_t dt_uprobe_is_enabled = {
+ .name = prvname_is_enabled,
+ .prog_type = BPF_PROG_TYPE_KPROBE,
+ .populate = &populate,
+ .trampoline = &trampoline_is_enabled,
+ .attach = &attach,
+ .probe_info = &probe_info,
+ .detach = &detach,
+ .probe_destroy = &probe_destroy_underlying,
+};
+
/*
* Used for pid probes.
*/
@@ -533,7 +679,7 @@ dt_provimpl_t dt_pid = {
.name = "pid",
.prog_type = BPF_PROG_TYPE_UNSPEC,
.provide_probe = &provide_pid_probe,
- .enable = &enable,
+ .enable = &enable_plain,
.probe_destroy = &probe_destroy,
};
@@ -544,6 +690,6 @@ dt_provimpl_t dt_usdt = {
.name = "usdt",
.prog_type = BPF_PROG_TYPE_UNSPEC,
.provide_probe = &provide_usdt_probe,
- .enable = &enable,
+ .enable = &enable_usdt,
.probe_destroy = &probe_destroy,
};
diff --git a/test/unittest/usdt/tst.enable.d b/test/unittest/usdt/tst.enable.d
index 1211af97290ad..a95eee2009174 100644
--- a/test/unittest/usdt/tst.enable.d
+++ b/test/unittest/usdt/tst.enable.d
@@ -1,11 +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, no is-enabled probes yet */
/* @@trigger: usdt-tst-special 2 */
#pragma D option quiet
diff --git a/test/unittest/usdt/tst.enable_and.d b/test/unittest/usdt/tst.enable_and.d
index 94a053ef43bbb..9715c9c11eaa4 100644
--- a/test/unittest/usdt/tst.enable_and.d
+++ b/test/unittest/usdt/tst.enable_and.d
@@ -1,11 +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, no is-enabled probes yet */
/* @@trigger: usdt-tst-special 5 */
#pragma D option quiet
diff --git a/test/unittest/usdt/tst.enable_and_2.d b/test/unittest/usdt/tst.enable_and_2.d
index 3b2963f4330bc..47e8feb59825f 100644
--- a/test/unittest/usdt/tst.enable_and_2.d
+++ b/test/unittest/usdt/tst.enable_and_2.d
@@ -1,11 +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, no is-enabled probes yet */
/* @@trigger: usdt-tst-special 6 */
#pragma D option quiet
diff --git a/test/unittest/usdt/tst.enable_or_2.d b/test/unittest/usdt/tst.enable_or_2.d
index 6b599544fe9f4..c384cddfb8db4 100644
--- a/test/unittest/usdt/tst.enable_or_2.d
+++ b/test/unittest/usdt/tst.enable_or_2.d
@@ -1,11 +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, no is-enabled probes yet */
/* @@trigger: usdt-tst-special 4 */
#pragma D option quiet
diff --git a/test/unittest/usdt/tst.enable_return.d b/test/unittest/usdt/tst.enable_return.d
index 0d727b8a6d0c9..2e7b41f91c7b9 100644
--- a/test/unittest/usdt/tst.enable_return.d
+++ b/test/unittest/usdt/tst.enable_return.d
@@ -1,11 +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, no is-enabled probes yet */
/* @@trigger: usdt-tst-special 8 */
#pragma D option quiet
diff --git a/test/unittest/usdt/tst.enable_stmt.d b/test/unittest/usdt/tst.enable_stmt.d
index 5c26919f764d6..37e106bf6d1d1 100644
--- a/test/unittest/usdt/tst.enable_stmt.d
+++ b/test/unittest/usdt/tst.enable_stmt.d
@@ -1,11 +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, no is-enabled probes yet */
/* @@trigger: usdt-tst-special 7 */
#pragma D option quiet
diff --git a/test/unittest/usdt/tst.enabled.sh b/test/unittest/usdt/tst.enabled.sh
index 5363172fd8b4b..2c0a5b405e7a5 100755
--- a/test/unittest/usdt/tst.enabled.sh
+++ b/test/unittest/usdt/tst.enabled.sh
@@ -1,7 +1,7 @@
#!/bin/bash
#
# 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.
#
@@ -9,7 +9,6 @@ if [ $# != 1 ]; then
echo expected one argument: '<'dtrace-path'>'
exit 2
fi
-# @@xfail: dtv2, no is-enabled probes yet
dtrace=$1
CC=/usr/bin/gcc
base-commit: f543fa6706c0b31364356c01bf3de63e3cce8ad1
prerequisite-patch-id: fa667248b7b02e92ee6b3807123ebcf2ac0acc38
prerequisite-patch-id: 0cec5f1a31d528a493d6143644c1e6b78c7f403b
prerequisite-patch-id: 756ad5b8f08d5595c32dd113d742218991107746
prerequisite-patch-id: eb290f098e38981181d85240150e1713979dc505
prerequisite-patch-id: c25b38ab68e815a63f064aff7496408684f94a36
prerequisite-patch-id: b86eb7e00b5883a586bd4dc7143ab25094912288
--
2.39.1.268.g9de2f9a303
More information about the DTrace-devel
mailing list