All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 5/8] parser: resolve explicitly scoped user objects
@ 2026-09-28 18:02 Kris Van Hees
  2026-10-03  8:40 ` [DTrace-devel] " Elena Zannoni
  0 siblings, 1 reply; 2+ messages in thread
From: Kris Van Hees @ 2026-09-28 18:02 UTC (permalink / raw)
  To: dtrace, dtrace-devel

Signed-off-by: Kris Van Hees <kris.van.hees@oracle.com>
---
 libdtrace/dt_module.c                         | 50 ++++++++++++++-----
 libdtrace/dt_parser.c                         | 34 ++++++++-----
 test/triggers/Build                           |  3 ++
 test/triggers/testprobe.c                     | 12 ++++-
 .../err.D_IDENT_UNDEF.scope-dot-kernel.r      |  2 +-
 .../lexer/err.D_IDENT_UNDEF.scope-dot.r       |  2 +-
 ... err.D_IDENT_UNDEF.scope-kernel-as-user.d} |  0
 .../err.D_IDENT_UNDEF.scope-kernel-as-user.r  |  2 +
 ... err.D_IDENT_UNDEF.scope-user-as-kernel.d} |  0
 .../err.D_IDENT_UNDEF.scope-user-as-kernel.r  |  2 +
 .../err.D_IDENT_UNDEF.scope-user-missing.d    | 19 +++++++
 .../err.D_IDENT_UNDEF.scope-user-missing.r    |  2 +
 .../err.D_SYM_BADREF.scope-kernel-as-user.r   |  2 -
 .../err.D_SYM_BADREF.scope-user-as-kernel.r   |  2 -
 test/unittest/lexer/tst.scope-user-explicit.d |  2 +-
 test/unittest/lexer/tst.scope-user-explicit.r |  0
 .../lexer/tst.scope-user-path-empty.sh        | 27 ++++++++++
 .../err.D_DECL_SCOPE.scopeop-enumerator.r     |  2 +-
 test/unittest/types/tst.scope-user-dotted.r   |  0
 test/unittest/types/tst.scope-user-dotted.sh  | 28 +++++++++++
 test/unittest/types/tst.scope-user-types.d    | 24 +++++++++
 test/unittest/types/tst.scope-user-types.r    |  0
 22 files changed, 181 insertions(+), 34 deletions(-)
 rename test/unittest/lexer/{err.D_SYM_BADREF.scope-kernel-as-user.d => err.D_IDENT_UNDEF.scope-kernel-as-user.d} (100%)
 create mode 100644 test/unittest/lexer/err.D_IDENT_UNDEF.scope-kernel-as-user.r
 rename test/unittest/lexer/{err.D_SYM_BADREF.scope-user-as-kernel.d => err.D_IDENT_UNDEF.scope-user-as-kernel.d} (100%)
 create mode 100644 test/unittest/lexer/err.D_IDENT_UNDEF.scope-user-as-kernel.r
 create mode 100644 test/unittest/lexer/err.D_IDENT_UNDEF.scope-user-missing.d
 create mode 100644 test/unittest/lexer/err.D_IDENT_UNDEF.scope-user-missing.r
 delete mode 100644 test/unittest/lexer/err.D_SYM_BADREF.scope-kernel-as-user.r
 delete mode 100644 test/unittest/lexer/err.D_SYM_BADREF.scope-user-as-kernel.r
 create mode 100644 test/unittest/lexer/tst.scope-user-explicit.r
 create mode 100755 test/unittest/lexer/tst.scope-user-path-empty.sh
 create mode 100644 test/unittest/types/tst.scope-user-dotted.r
 create mode 100755 test/unittest/types/tst.scope-user-dotted.sh
 create mode 100644 test/unittest/types/tst.scope-user-types.d
 create mode 100644 test/unittest/types/tst.scope-user-types.r

diff --git a/libdtrace/dt_module.c b/libdtrace/dt_module.c
index acf4baa7..08dc0937 100644
--- a/libdtrace/dt_module.c
+++ b/libdtrace/dt_module.c
@@ -71,6 +71,9 @@ dt_user_path_add(dtrace_hdl_t *dtp, dt_htab_t *h, char *s)
 {
 	dt_path_t	tmpl, *path;
 
+	if (s == NULL)
+		return -1;
+
 	tmpl.str = s;
 	if (dt_htab_lookup(h, &tmpl) != NULL) {
 		free(s);
@@ -88,6 +91,7 @@ dt_user_path_add(dtrace_hdl_t *dtp, dt_htab_t *h, char *s)
 		goto fail;
 	}
 
+	dt_dprintf("Adding user module path %s\n", path->str);
 	dt_list_append(&dtp->dt_user_path, path);
 
 	return 0;
@@ -109,14 +113,14 @@ dt_user_path_add_env(dtrace_hdl_t *dtp, dt_htab_t *h, const char *env)
 	for (;;) {
 		end = strchr(str, ':');
 		if (end == NULL) {
+			/*
+			 * A trailing empty path component denotes the current
+			 * directory.
+			 */
 			if (*str == '\0')
-				if (dt_user_path_add(dtp, h, strdup(".")) == -1)
-					return -1;
-
-			if (dt_user_path_add(dtp, h, strdup(str)) == -1)
-				return -1;
+				return dt_user_path_add(dtp, h, strdup("."));
 
-			break;
+			return dt_user_path_add(dtp, h, strdup(str));
 		}
 
 		if (end == str) {
@@ -142,14 +146,19 @@ dt_user_path_init(dtrace_hdl_t *dtp)
 	char		*str, *end;
 	int		rc = 0;
 
+	if (h == NULL)
+		goto fail;
+
 	/* Add paths from $LD_LIBRARY_PATH. */
 	if (dt_user_path_add_env(dtp, h, "LD_LIBRARY_PATH") != 0)
 		goto fail;
 
 	/* Add paths from ld.so.cache (using ldconfig -p output). */
 	fp = popen("/sbin/ldconfig -p", "r");
-	if (fp == NULL)
-		goto fail;
+	if (fp == NULL) {
+		dt_dprintf("Failed to get paths from ldconfig\n");
+		goto path;
+	}
 
 	while (getline(&buf, &len, fp) != -1) {
 		/* We are interested in lines like: <something> => /path */
@@ -182,6 +191,7 @@ dt_user_path_init(dtrace_hdl_t *dtp)
 	if (rc == -1)
 		goto fail;
 
+path:
 	/* Add paths from $PATH. */
 	if (dt_user_path_add_env(dtp, h, "PATH") != 0)
 		goto fail;
@@ -195,6 +205,8 @@ dt_user_path_init(dtrace_hdl_t *dtp)
 
 fail:
 	dt_htab_destroy(h);
+	dt_user_path_destroy(dtp);
+	dt_set_errno(dtp, ENOMEM);
 	return -1;
 }
 
@@ -328,6 +340,8 @@ dt_module_create(dtrace_hdl_t *dtp, const char *name)
 		dmp->dm_ops = &dt_modops_32;
 	dmp->dm_dtp = dtp;
 
+	dt_dprintf("created module %s\n", dmp->dm_name);
+
 	return dmp;
 }
 
@@ -341,14 +355,16 @@ dt_module_create_user(dtrace_hdl_t *dtp, const char *name)
 {
 	dt_module_t	*dmp;
 	char		*file = NULL;
+	char		*p;
 
 	if (name == NULL || name[0] == '\0') {
 		dt_set_errno(dtp, EINVAL);
 		return NULL;
 	}
 
-	if (dt_list_empty(&dtp->dt_user_path))
-		dt_user_path_init(dtp);
+	if (dt_list_empty(&dtp->dt_user_path) && dt_user_path_init(dtp) == -1)
+		return NULL;
+
 	if (!dt_list_empty(&dtp->dt_user_path)) {
 		dt_path_t	*path;
 
@@ -366,11 +382,19 @@ dt_module_create_user(dtrace_hdl_t *dtp, const char *name)
 		}
 
 		if (file == NULL) {
-			dt_set_errno(dtp, ENOENT);
+			dt_set_errno(dtp, EDT_NOMOD);
 			return NULL;
 		}
 	}
 
+	/*
+	 * Use the resolved pathname as the object location, but name it based
+	 * on just the filename.
+	 */
+	p = strrchr(name, '/');
+	if (p != NULL)
+		name = p + 1;
+
 	if (strlen(name) >= DTRACE_MODNAMELEN ||
 	    strlen(file) >= sizeof(dmp->dm_file)) {
 		dt_set_errno(dtp, ENAMETOOLONG);
@@ -437,7 +461,7 @@ dt_module_init_elf(dtrace_hdl_t *dtp, dt_module_t *dmp)
 	if (dmp->dm_file[0] == '\0') {
 		dt_dprintf("failed to open ELF file for module %s: "
 		    "no file name known\n", dmp->dm_name);
-		return dt_set_errno(dtp, EDT_NOTLOADED);
+		return dt_set_errno(dtp, EDT_NOMOD);
 	}
 
 	if ((fd = open(dmp->dm_file, O_RDONLY)) == -1) {
@@ -496,7 +520,7 @@ dt_module_load_sect(dtrace_hdl_t *dtp, dt_module_t *dmp, ctf_sect_t *ctsp)
 	Elf_Scn *sp;
 
 	if (elf_getshdrstrndx(dmp->dm_elf, &shstrs) == -1)
-		return dt_set_errno(dtp, EDT_NOTLOADED);
+		return dt_set_errno(dtp, EDT_NOMOD);
 
 	for (sp = NULL; (sp = elf_nextscn(dmp->dm_elf, sp)) != NULL; ) {
 		if (gelf_getshdr(sp, &sh) == NULL || sh.sh_type == SHT_NULL ||
diff --git a/libdtrace/dt_parser.c b/libdtrace/dt_parser.c
index 1fd0f5b4..1eccc0fd 100644
--- a/libdtrace/dt_parser.c
+++ b/libdtrace/dt_parser.c
@@ -257,6 +257,14 @@ dt_type_lookup(const char *s, dtrace_typeinfo_t *tip)
 		memcpy(type, s, (size_t)(start - s));
 		memcpy(type + (size_t)(start - s), ident, strlen(ident) + 1);
 
+		if (scopekind == 2 && obj != DTRACE_OBJ_UMODS) {
+			dt_module_t *dmp = dt_module_create_user(dtp, obj);
+
+			if (dmp == NULL)
+				return -1;
+			obj = dmp->dm_name;
+		}
+
 		return dtrace_lookup_by_type(dtp, obj, type, tip);
 	}
 
@@ -2832,17 +2840,14 @@ dt_xcook_ident(dt_node_t *dnp, dt_idhash_t *dhp, uint_t idkind, int create)
 	 * scope is desired and we should search the specified idhash.
 	 */
 	scopekind = dt_scope_parse(dnp->dn_string, &scope, &ident);
-	if (scopekind < 0) {
-		xyerror(D_SYNTAX, "syntax error near \"%s\"\n",
-		    dnp->dn_string);
-	}
+	if (scopekind < 0)
+		xyerror(D_SYNTAX, "syntax error near \"%s\"\n", dnp->dn_string);
 
 	if (scopekind > 0) {
 		uref = scopekind == 2;
 		name = (char *)ident;
 		*(char *)(ident - scopekind) = '\0';
 		dnkind = DT_NODE_VAR;
-
 	} else if (idkind == DT_IDENT_AGG) {
 		scope = DTRACE_OBJ_EXEC;
 		name = dnp->dn_string + 1;
@@ -2862,6 +2867,17 @@ dt_xcook_ident(dt_node_t *dnp, dt_idhash_t *dhp, uint_t idkind, int create)
 	dt_set_errno(dtp, EDT_NOVAR);
 	markstr = uref ? "``" : "`";
 
+	if (uref && scope != DTRACE_OBJ_UMODS) {
+		dt_module_t *dmp = dt_module_create_user(dtp, scope);
+
+		if (dmp == NULL) {
+			xyerror(D_IDENT_UNDEF, "failed to resolve %s%s%s: %s\n",
+			    dnp->dn_string, markstr, name,
+			    dtrace_errmsg(dtp, dtrace_errno(dtp)));
+		}
+		scope = dmp->dm_name;
+	}
+
 	if (scope == DTRACE_OBJ_EXEC && (
 	    (dhp != dtp->dt_globals &&
 	    (idp = dt_idhash_lookup(dhp, name)) != NULL) ||
@@ -2925,14 +2941,11 @@ dt_xcook_ident(dt_node_t *dnp, dt_idhash_t *dhp, uint_t idkind, int create)
 			dt_cook_taint_alloca(dnp, idp, NULL);
 
 		dt_node_attr_assign(dnp, attr);
-
 	} else if (dhp == dtp->dt_globals && scope != DTRACE_OBJ_EXEC &&
 	    dtrace_lookup_by_name(dtp, scope, name, &sym, &dts) == 0) {
-
 		dt_module_t *mp = dt_module_lookup_by_name(dtp, dts.object);
 		int umod = (mp->dm_flags & DT_DM_KERNEL) == 0;
 		static const char *const kunames[] = { "kernel", "user" };
-
 		dtrace_typeinfo_t dtt;
 		dtrace_syminfo_t *sip;
 
@@ -2992,7 +3005,6 @@ dt_xcook_ident(dt_node_t *dnp, dt_idhash_t *dhp, uint_t idkind, int create)
 			idp->di_flags |= DT_IDFLG_USER;
 			dnp->dn_flags |= DT_NF_USERLAND;
 		}
-
 	} else if (scope == DTRACE_OBJ_EXEC && create == B_TRUE) {
 		uint_t flags = DT_IDFLG_WRITE;
 		uint_t id;
@@ -3061,15 +3073,13 @@ dt_xcook_ident(dt_node_t *dnp, dt_idhash_t *dhp, uint_t idkind, int create)
 			dt_cook_taint_alloca(dnp, idp, NULL);
 
 		dt_node_attr_assign(dnp, attr);
-
 	} else if (scope != DTRACE_OBJ_EXEC) {
 		xyerror(D_IDENT_UNDEF, "failed to resolve %s%s%s: %s\n",
 		    dnp->dn_string, markstr, name,
 		    dtrace_errmsg(dtp, dtrace_errno(dtp)));
-	} else {
+	} else
 		xyerror(D_IDENT_UNDEF, "failed to resolve %s: %s\n",
 		    dnp->dn_string, dtrace_errmsg(dtp, dtrace_errno(dtp)));
-	}
 }
 
 static dt_node_t *
diff --git a/test/triggers/Build b/test/triggers/Build
index 4ff5002a..98556586 100644
--- a/test/triggers/Build
+++ b/test/triggers/Build
@@ -106,6 +106,9 @@ proc-tst-omp_LDFLAGS := -fopenmp
 proc-tst-pthread-exec_CFLAGS := -pthread
 proc-tst-pthread-exec_LIBS := -pthread
 
+# Userspace scoped-type tests need type information in this executable.
+testprobe_CFLAGS := -gctf
+
 # readwholedir is used for ustack() tests, so needs a symbol table and needs
 # all its functions in it, even if they would be sibcalled out of existence.
 readwholedir_CFLAGS := -fno-inline -fno-optimize-sibling-calls
diff --git a/test/triggers/testprobe.c b/test/triggers/testprobe.c
index 4bef92fe..22546ddf 100644
--- a/test/triggers/testprobe.c
+++ b/test/triggers/testprobe.c
@@ -1,6 +1,6 @@
 /*
  * Oracle Linux DTrace.
- * Copyright (c) 2005, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2005, 2012, 2026, 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.
  */
@@ -17,10 +17,20 @@
 #include <stdio.h>
 #include <unistd.h>
 
+/* Keep a named type in the executable's CTF for userspace type-lookup tests. */
+struct dtrace_scope_test_type {
+    int value;
+};
+
+static struct dtrace_scope_test_type dtrace_scope_test_instance;
+
 int main(int argc, char *argv[])
 {
     int fd, i;
 
+    /* Prevent optimization from discarding the test type. */
+    dtrace_scope_test_instance.value = argc;
+
     if ((fd = open("/dev/dtrace/provider/dt_test", O_RDONLY)) == -1) {
         perror("open");
         exit(1);
diff --git a/test/unittest/lexer/err.D_IDENT_UNDEF.scope-dot-kernel.r b/test/unittest/lexer/err.D_IDENT_UNDEF.scope-dot-kernel.r
index 89a9f9c5..926e5a91 100644
--- a/test/unittest/lexer/err.D_IDENT_UNDEF.scope-dot-kernel.r
+++ b/test/unittest/lexer/err.D_IDENT_UNDEF.scope-dot-kernel.r
@@ -1,2 +1,2 @@
 -- @@stderr --
-dtrace: failed to compile script test/unittest/lexer/err.D_IDENT_UNDEF.scope-dot-kernel.d: [D_IDENT_UNDEF] line 17: failed to resolve foo.bar`baz: Module is no longer loaded
+dtrace: failed to compile script test/unittest/lexer/err.D_IDENT_UNDEF.scope-dot-kernel.d: [D_IDENT_UNDEF] line 17: failed to resolve foo.bar`baz: Unknown module name
diff --git a/test/unittest/lexer/err.D_IDENT_UNDEF.scope-dot.r b/test/unittest/lexer/err.D_IDENT_UNDEF.scope-dot.r
index 7734e29f..42a6ea95 100644
--- a/test/unittest/lexer/err.D_IDENT_UNDEF.scope-dot.r
+++ b/test/unittest/lexer/err.D_IDENT_UNDEF.scope-dot.r
@@ -1,2 +1,2 @@
 -- @@stderr --
-dtrace: failed to compile script test/unittest/lexer/err.D_IDENT_UNDEF.scope-dot.d: [D_IDENT_UNDEF] line 17: failed to resolve foo.bar``baz: Module is no longer loaded
+dtrace: failed to compile script test/unittest/lexer/err.D_IDENT_UNDEF.scope-dot.d: [D_IDENT_UNDEF] line 17: failed to resolve foo.bar``baz: Unknown module name
diff --git a/test/unittest/lexer/err.D_SYM_BADREF.scope-kernel-as-user.d b/test/unittest/lexer/err.D_IDENT_UNDEF.scope-kernel-as-user.d
similarity index 100%
rename from test/unittest/lexer/err.D_SYM_BADREF.scope-kernel-as-user.d
rename to test/unittest/lexer/err.D_IDENT_UNDEF.scope-kernel-as-user.d
diff --git a/test/unittest/lexer/err.D_IDENT_UNDEF.scope-kernel-as-user.r b/test/unittest/lexer/err.D_IDENT_UNDEF.scope-kernel-as-user.r
new file mode 100644
index 00000000..3299b3c3
--- /dev/null
+++ b/test/unittest/lexer/err.D_IDENT_UNDEF.scope-kernel-as-user.r
@@ -0,0 +1,2 @@
+-- @@stderr --
+dtrace: failed to compile script test/unittest/lexer/err.D_IDENT_UNDEF.scope-kernel-as-user.d: [D_IDENT_UNDEF] line 16: failed to resolve vmlinux``major_names: Unknown module name
diff --git a/test/unittest/lexer/err.D_SYM_BADREF.scope-user-as-kernel.d b/test/unittest/lexer/err.D_IDENT_UNDEF.scope-user-as-kernel.d
similarity index 100%
rename from test/unittest/lexer/err.D_SYM_BADREF.scope-user-as-kernel.d
rename to test/unittest/lexer/err.D_IDENT_UNDEF.scope-user-as-kernel.d
diff --git a/test/unittest/lexer/err.D_IDENT_UNDEF.scope-user-as-kernel.r b/test/unittest/lexer/err.D_IDENT_UNDEF.scope-user-as-kernel.r
new file mode 100644
index 00000000..b952b509
--- /dev/null
+++ b/test/unittest/lexer/err.D_IDENT_UNDEF.scope-user-as-kernel.r
@@ -0,0 +1,2 @@
+-- @@stderr --
+dtrace: failed to compile script test/unittest/lexer/err.D_IDENT_UNDEF.scope-user-as-kernel.d: [D_IDENT_UNDEF] line 18: failed to resolve testprobe`main: Unknown module name
diff --git a/test/unittest/lexer/err.D_IDENT_UNDEF.scope-user-missing.d b/test/unittest/lexer/err.D_IDENT_UNDEF.scope-user-missing.d
new file mode 100644
index 00000000..7304da72
--- /dev/null
+++ b/test/unittest/lexer/err.D_IDENT_UNDEF.scope-user-missing.d
@@ -0,0 +1,19 @@
+/*
+ * Oracle Linux DTrace.
+ * Copyright (c) 2026, 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: An explicitly-scoped userspace symbol reports a lookup error
+ * when its module cannot be found.
+ */
+
+#pragma D option quiet
+
+BEGIN
+{
+	trace(no_such_module``main);
+	exit(0);
+}
diff --git a/test/unittest/lexer/err.D_IDENT_UNDEF.scope-user-missing.r b/test/unittest/lexer/err.D_IDENT_UNDEF.scope-user-missing.r
new file mode 100644
index 00000000..3e752fc9
--- /dev/null
+++ b/test/unittest/lexer/err.D_IDENT_UNDEF.scope-user-missing.r
@@ -0,0 +1,2 @@
+-- @@stderr --
+dtrace: failed to compile script test/unittest/lexer/err.D_IDENT_UNDEF.scope-user-missing.d: [D_IDENT_UNDEF] line 17: failed to resolve no_such_module``main: Unknown module name
diff --git a/test/unittest/lexer/err.D_SYM_BADREF.scope-kernel-as-user.r b/test/unittest/lexer/err.D_SYM_BADREF.scope-kernel-as-user.r
deleted file mode 100644
index 718b2b31..00000000
--- a/test/unittest/lexer/err.D_SYM_BADREF.scope-kernel-as-user.r
+++ /dev/null
@@ -1,2 +0,0 @@
--- @@stderr --
-dtrace: failed to compile script test/unittest/lexer/err.D_SYM_BADREF.scope-kernel-as-user.d: [D_SYM_BADREF] line 16: kernel module 'vmlinux' symbol 'major_names' may not be referenced as a user symbol
diff --git a/test/unittest/lexer/err.D_SYM_BADREF.scope-user-as-kernel.r b/test/unittest/lexer/err.D_SYM_BADREF.scope-user-as-kernel.r
deleted file mode 100644
index 87169597..00000000
--- a/test/unittest/lexer/err.D_SYM_BADREF.scope-user-as-kernel.r
+++ /dev/null
@@ -1,2 +0,0 @@
--- @@stderr --
-dtrace: failed to compile script test/unittest/lexer/err.D_SYM_BADREF.scope-user-as-kernel.d: [D_SYM_BADREF] line 18: user module 'testprobe' symbol 'main' may not be referenced as a kernel symbol
diff --git a/test/unittest/lexer/tst.scope-user-explicit.d b/test/unittest/lexer/tst.scope-user-explicit.d
index 2d649f6f..daead7b3 100644
--- a/test/unittest/lexer/tst.scope-user-explicit.d
+++ b/test/unittest/lexer/tst.scope-user-explicit.d
@@ -6,7 +6,7 @@
  */
 
 /* @@trigger: testprobe */
-/* @@runtest-opts: -e */
+/* @@runtest-opts: -e -xlinkmode=static */
 
 /*
  * ASSERTION: Explicit userspace module scoping resolves as a userspace
diff --git a/test/unittest/lexer/tst.scope-user-explicit.r b/test/unittest/lexer/tst.scope-user-explicit.r
new file mode 100644
index 00000000..e69de29b
diff --git a/test/unittest/lexer/tst.scope-user-path-empty.sh b/test/unittest/lexer/tst.scope-user-path-empty.sh
new file mode 100755
index 00000000..00502578
--- /dev/null
+++ b/test/unittest/lexer/tst.scope-user-path-empty.sh
@@ -0,0 +1,27 @@
+#!/bin/bash
+#
+# Oracle Linux DTrace.
+# Copyright (c) 2026, 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: An empty trailing entry in PATH or LD_LIBRARY_PATH denotes the
+# current directory when resolving a userspace module.
+#
+
+dtrace=$1
+dir=$tmpdir/scope-user-path-empty.$$
+
+mkdir -p "$dir" || exit 1
+trap 'rm -rf "$dir"' EXIT
+cp test/triggers/testprobe "$dir/testprobe" || exit 1
+cd "$dir" || exit 1
+
+PATH=.: LD_LIBRARY_PATH=.: "$dtrace" $dt_flags -e -c testprobe -n '
+BEGIN
+{
+	trace(&testprobe``main);
+	exit(0);
+}'
diff --git a/test/unittest/types/err.D_DECL_SCOPE.scopeop-enumerator.r b/test/unittest/types/err.D_DECL_SCOPE.scopeop-enumerator.r
index 06ef912b..48ee9b20 100644
--- a/test/unittest/types/err.D_DECL_SCOPE.scopeop-enumerator.r
+++ b/test/unittest/types/err.D_DECL_SCOPE.scopeop-enumerator.r
@@ -1,2 +1,2 @@
 -- @@stderr --
-dtrace: failed to compile script test/unittest/types/err.D_DECL_SCOPE.scopeop-enumerator.d: [D_DECL_SCOPE] line 15: D scoping operator may not be used in an enumerator name (foo`bar)
+dtrace: failed to compile script test/unittest/types/err.D_DECL_SCOPE.scopeop-enumerator.d: [D_DECL_SCOPE] line 16: D scoping operator may not be used in an enumerator name (foo`bar)
diff --git a/test/unittest/types/tst.scope-user-dotted.r b/test/unittest/types/tst.scope-user-dotted.r
new file mode 100644
index 00000000..e69de29b
diff --git a/test/unittest/types/tst.scope-user-dotted.sh b/test/unittest/types/tst.scope-user-dotted.sh
new file mode 100755
index 00000000..3d0348b7
--- /dev/null
+++ b/test/unittest/types/tst.scope-user-dotted.sh
@@ -0,0 +1,28 @@
+#!/bin/bash
+#
+# Oracle Linux DTrace.
+# Copyright (c) 2026, 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: A dotted userspace module name resolves both external symbols
+# and types.
+#
+
+dtrace=$1
+dir=$tmpdir/scope-user-dotted.$$
+
+mkdir -p "$dir" || exit 1
+trap 'rm -rf "$dir"' EXIT
+cp test/triggers/testprobe "$dir/scope.user" || exit 1
+cd "$dir" || exit 1
+
+PATH=.: "$dtrace" $dt_flags -e -xlinkmode=static -c scope.user -n '
+BEGIN
+{
+	symbol = &scope.user``main;
+	type = (struct scope.user``dtrace_scope_test_type *)NULL;
+	exit(0);
+}'
diff --git a/test/unittest/types/tst.scope-user-types.d b/test/unittest/types/tst.scope-user-types.d
new file mode 100644
index 00000000..380af340
--- /dev/null
+++ b/test/unittest/types/tst.scope-user-types.d
@@ -0,0 +1,24 @@
+/*
+ * Oracle Linux DTrace.
+ * Copyright (c) 2026, 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.
+ */
+
+/* @@trigger: testprobe */
+/* @@runtest-opts: -e -xlinkmode=static */
+
+/*
+ * ASSERTION: Explicit and implicit userspace type scopes, and the implicit
+ * kernel type scope, resolve external types.
+ */
+
+#pragma D option quiet
+
+BEGIN
+{
+	scope_explicit = (struct testprobe``dtrace_scope_test_type *)NULL;
+	scope_implicit = (struct ``dtrace_scope_test_type *)NULL;
+	scope_kernel = (struct `task_struct *)NULL;
+	exit(0);
+}
diff --git a/test/unittest/types/tst.scope-user-types.r b/test/unittest/types/tst.scope-user-types.r
new file mode 100644
index 00000000..e69de29b
-- 
2.52.0


^ permalink raw reply related	[flat|nested] 2+ messages in thread

* Re: [DTrace-devel] [PATCH 5/8] parser: resolve explicitly scoped user objects
  2026-09-28 18:02 [PATCH 5/8] parser: resolve explicitly scoped user objects Kris Van Hees
@ 2026-10-03  8:40 ` Elena Zannoni
  0 siblings, 0 replies; 2+ messages in thread
From: Elena Zannoni @ 2026-10-03  8:40 UTC (permalink / raw)
  To: Kris Van Hees, dtrace, dtrace-devel

Reviewed-by: Elena Zannoni <elena.zannoni@oracle.com>

On 9/28/26 12:02 PM, Kris Van Hees via DTrace-devel wrote:

> Signed-off-by: Kris Van Hees <kris.van.hees@oracle.com>
> ---
>  libdtrace/dt_module.c                         | 50 ++++++++++++++-----
>  libdtrace/dt_parser.c                         | 34 ++++++++-----
>  test/triggers/Build                           |  3 ++
>  test/triggers/testprobe.c                     | 12 ++++-
>  .../err.D_IDENT_UNDEF.scope-dot-kernel.r      |  2 +-
>  .../lexer/err.D_IDENT_UNDEF.scope-dot.r       |  2 +-
>  ... err.D_IDENT_UNDEF.scope-kernel-as-user.d} |  0
>  .../err.D_IDENT_UNDEF.scope-kernel-as-user.r  |  2 +
>  ... err.D_IDENT_UNDEF.scope-user-as-kernel.d} |  0
>  .../err.D_IDENT_UNDEF.scope-user-as-kernel.r  |  2 +
>  .../err.D_IDENT_UNDEF.scope-user-missing.d    | 19 +++++++
>  .../err.D_IDENT_UNDEF.scope-user-missing.r    |  2 +
>  .../err.D_SYM_BADREF.scope-kernel-as-user.r   |  2 -
>  .../err.D_SYM_BADREF.scope-user-as-kernel.r   |  2 -
>  test/unittest/lexer/tst.scope-user-explicit.d |  2 +-
>  test/unittest/lexer/tst.scope-user-explicit.r |  0
>  .../lexer/tst.scope-user-path-empty.sh        | 27 ++++++++++
>  .../err.D_DECL_SCOPE.scopeop-enumerator.r     |  2 +-
>  test/unittest/types/tst.scope-user-dotted.r   |  0
>  test/unittest/types/tst.scope-user-dotted.sh  | 28 +++++++++++
>  test/unittest/types/tst.scope-user-types.d    | 24 +++++++++
>  test/unittest/types/tst.scope-user-types.r    |  0
>  22 files changed, 181 insertions(+), 34 deletions(-)
>  rename test/unittest/lexer/{err.D_SYM_BADREF.scope-kernel-as-user.d => err.D_IDENT_UNDEF.scope-kernel-as-user.d} (100%)
>  create mode 100644 test/unittest/lexer/err.D_IDENT_UNDEF.scope-kernel-as-user.r
>  rename test/unittest/lexer/{err.D_SYM_BADREF.scope-user-as-kernel.d => err.D_IDENT_UNDEF.scope-user-as-kernel.d} (100%)
>  create mode 100644 test/unittest/lexer/err.D_IDENT_UNDEF.scope-user-as-kernel.r
>  create mode 100644 test/unittest/lexer/err.D_IDENT_UNDEF.scope-user-missing.d
>  create mode 100644 test/unittest/lexer/err.D_IDENT_UNDEF.scope-user-missing.r
>  delete mode 100644 test/unittest/lexer/err.D_SYM_BADREF.scope-kernel-as-user.r
>  delete mode 100644 test/unittest/lexer/err.D_SYM_BADREF.scope-user-as-kernel.r
>  create mode 100644 test/unittest/lexer/tst.scope-user-explicit.r
>  create mode 100755 test/unittest/lexer/tst.scope-user-path-empty.sh
>  create mode 100644 test/unittest/types/tst.scope-user-dotted.r
>  create mode 100755 test/unittest/types/tst.scope-user-dotted.sh
>  create mode 100644 test/unittest/types/tst.scope-user-types.d
>  create mode 100644 test/unittest/types/tst.scope-user-types.r
> 
> diff --git a/libdtrace/dt_module.c b/libdtrace/dt_module.c
> index acf4baa7..08dc0937 100644
> --- a/libdtrace/dt_module.c
> +++ b/libdtrace/dt_module.c
> @@ -71,6 +71,9 @@ dt_user_path_add(dtrace_hdl_t *dtp, dt_htab_t *h, char *s)
>  {
>  	dt_path_t	tmpl, *path;
>  
> +	if (s == NULL)
> +		return -1;
> +
>  	tmpl.str = s;
>  	if (dt_htab_lookup(h, &tmpl) != NULL) {
>  		free(s);
> @@ -88,6 +91,7 @@ dt_user_path_add(dtrace_hdl_t *dtp, dt_htab_t *h, char *s)
>  		goto fail;
>  	}
>  
> +	dt_dprintf("Adding user module path %s\n", path->str);
>  	dt_list_append(&dtp->dt_user_path, path);
>  
>  	return 0;
> @@ -109,14 +113,14 @@ dt_user_path_add_env(dtrace_hdl_t *dtp, dt_htab_t *h, const char *env)
>  	for (;;) {
>  		end = strchr(str, ':');
>  		if (end == NULL) {
> +			/*
> +			 * A trailing empty path component denotes the current
> +			 * directory.
> +			 */
>  			if (*str == '\0')
> -				if (dt_user_path_add(dtp, h, strdup(".")) == -1)
> -					return -1;
> -
> -			if (dt_user_path_add(dtp, h, strdup(str)) == -1)
> -				return -1;
> +				return dt_user_path_add(dtp, h, strdup("."));
>  
> -			break;
> +			return dt_user_path_add(dtp, h, strdup(str));
>  		}
>  
>  		if (end == str) {
> @@ -142,14 +146,19 @@ dt_user_path_init(dtrace_hdl_t *dtp)
>  	char		*str, *end;
>  	int		rc = 0;
>  
> +	if (h == NULL)
> +		goto fail;
> +
>  	/* Add paths from $LD_LIBRARY_PATH. */
>  	if (dt_user_path_add_env(dtp, h, "LD_LIBRARY_PATH") != 0)
>  		goto fail;
>  
>  	/* Add paths from ld.so.cache (using ldconfig -p output). */
>  	fp = popen("/sbin/ldconfig -p", "r");
> -	if (fp == NULL)
> -		goto fail;
> +	if (fp == NULL) {
> +		dt_dprintf("Failed to get paths from ldconfig\n");
> +		goto path;
> +	}
>  
>  	while (getline(&buf, &len, fp) != -1) {
>  		/* We are interested in lines like: <something> => /path */
> @@ -182,6 +191,7 @@ dt_user_path_init(dtrace_hdl_t *dtp)
>  	if (rc == -1)
>  		goto fail;
>  
> +path:
>  	/* Add paths from $PATH. */
>  	if (dt_user_path_add_env(dtp, h, "PATH") != 0)
>  		goto fail;
> @@ -195,6 +205,8 @@ dt_user_path_init(dtrace_hdl_t *dtp)
>  
>  fail:
>  	dt_htab_destroy(h);
> +	dt_user_path_destroy(dtp);
> +	dt_set_errno(dtp, ENOMEM);
>  	return -1;
>  }
>  
> @@ -328,6 +340,8 @@ dt_module_create(dtrace_hdl_t *dtp, const char *name)
>  		dmp->dm_ops = &dt_modops_32;
>  	dmp->dm_dtp = dtp;
>  
> +	dt_dprintf("created module %s\n", dmp->dm_name);
> +
>  	return dmp;
>  }
>  
> @@ -341,14 +355,16 @@ dt_module_create_user(dtrace_hdl_t *dtp, const char *name)
>  {
>  	dt_module_t	*dmp;
>  	char		*file = NULL;
> +	char		*p;
>  
>  	if (name == NULL || name[0] == '\0') {
>  		dt_set_errno(dtp, EINVAL);
>  		return NULL;
>  	}
>  
> -	if (dt_list_empty(&dtp->dt_user_path))
> -		dt_user_path_init(dtp);
> +	if (dt_list_empty(&dtp->dt_user_path) && dt_user_path_init(dtp) == -1)
> +		return NULL;
> +
>  	if (!dt_list_empty(&dtp->dt_user_path)) {
>  		dt_path_t	*path;
>  
> @@ -366,11 +382,19 @@ dt_module_create_user(dtrace_hdl_t *dtp, const char *name)
>  		}
>  
>  		if (file == NULL) {
> -			dt_set_errno(dtp, ENOENT);
> +			dt_set_errno(dtp, EDT_NOMOD);
>  			return NULL;
>  		}
>  	}
>  
> +	/*
> +	 * Use the resolved pathname as the object location, but name it based
> +	 * on just the filename.
> +	 */
> +	p = strrchr(name, '/');
> +	if (p != NULL)
> +		name = p + 1;
> +
>  	if (strlen(name) >= DTRACE_MODNAMELEN ||
>  	    strlen(file) >= sizeof(dmp->dm_file)) {
>  		dt_set_errno(dtp, ENAMETOOLONG);
> @@ -437,7 +461,7 @@ dt_module_init_elf(dtrace_hdl_t *dtp, dt_module_t *dmp)
>  	if (dmp->dm_file[0] == '\0') {
>  		dt_dprintf("failed to open ELF file for module %s: "
>  		    "no file name known\n", dmp->dm_name);
> -		return dt_set_errno(dtp, EDT_NOTLOADED);
> +		return dt_set_errno(dtp, EDT_NOMOD);
>  	}
>  
>  	if ((fd = open(dmp->dm_file, O_RDONLY)) == -1) {
> @@ -496,7 +520,7 @@ dt_module_load_sect(dtrace_hdl_t *dtp, dt_module_t *dmp, ctf_sect_t *ctsp)
>  	Elf_Scn *sp;
>  
>  	if (elf_getshdrstrndx(dmp->dm_elf, &shstrs) == -1)
> -		return dt_set_errno(dtp, EDT_NOTLOADED);
> +		return dt_set_errno(dtp, EDT_NOMOD);
>  
>  	for (sp = NULL; (sp = elf_nextscn(dmp->dm_elf, sp)) != NULL; ) {
>  		if (gelf_getshdr(sp, &sh) == NULL || sh.sh_type == SHT_NULL ||
> diff --git a/libdtrace/dt_parser.c b/libdtrace/dt_parser.c
> index 1fd0f5b4..1eccc0fd 100644
> --- a/libdtrace/dt_parser.c
> +++ b/libdtrace/dt_parser.c
> @@ -257,6 +257,14 @@ dt_type_lookup(const char *s, dtrace_typeinfo_t *tip)
>  		memcpy(type, s, (size_t)(start - s));
>  		memcpy(type + (size_t)(start - s), ident, strlen(ident) + 1);
>  
> +		if (scopekind == 2 && obj != DTRACE_OBJ_UMODS) {
> +			dt_module_t *dmp = dt_module_create_user(dtp, obj);
> +
> +			if (dmp == NULL)
> +				return -1;
> +			obj = dmp->dm_name;
> +		}
> +
>  		return dtrace_lookup_by_type(dtp, obj, type, tip);
>  	}
>  
> @@ -2832,17 +2840,14 @@ dt_xcook_ident(dt_node_t *dnp, dt_idhash_t *dhp, uint_t idkind, int create)
>  	 * scope is desired and we should search the specified idhash.
>  	 */
>  	scopekind = dt_scope_parse(dnp->dn_string, &scope, &ident);
> -	if (scopekind < 0) {
> -		xyerror(D_SYNTAX, "syntax error near \"%s\"\n",
> -		    dnp->dn_string);
> -	}
> +	if (scopekind < 0)
> +		xyerror(D_SYNTAX, "syntax error near \"%s\"\n", dnp->dn_string);
>  
>  	if (scopekind > 0) {
>  		uref = scopekind == 2;
>  		name = (char *)ident;
>  		*(char *)(ident - scopekind) = '\0';
>  		dnkind = DT_NODE_VAR;
> -
>  	} else if (idkind == DT_IDENT_AGG) {
>  		scope = DTRACE_OBJ_EXEC;
>  		name = dnp->dn_string + 1;
> @@ -2862,6 +2867,17 @@ dt_xcook_ident(dt_node_t *dnp, dt_idhash_t *dhp, uint_t idkind, int create)
>  	dt_set_errno(dtp, EDT_NOVAR);
>  	markstr = uref ? "``" : "`";
>  
> +	if (uref && scope != DTRACE_OBJ_UMODS) {
> +		dt_module_t *dmp = dt_module_create_user(dtp, scope);
> +
> +		if (dmp == NULL) {
> +			xyerror(D_IDENT_UNDEF, "failed to resolve %s%s%s: %s\n",
> +			    dnp->dn_string, markstr, name,
> +			    dtrace_errmsg(dtp, dtrace_errno(dtp)));
> +		}
> +		scope = dmp->dm_name;
> +	}
> +
>  	if (scope == DTRACE_OBJ_EXEC && (
>  	    (dhp != dtp->dt_globals &&
>  	    (idp = dt_idhash_lookup(dhp, name)) != NULL) ||
> @@ -2925,14 +2941,11 @@ dt_xcook_ident(dt_node_t *dnp, dt_idhash_t *dhp, uint_t idkind, int create)
>  			dt_cook_taint_alloca(dnp, idp, NULL);
>  
>  		dt_node_attr_assign(dnp, attr);
> -
>  	} else if (dhp == dtp->dt_globals && scope != DTRACE_OBJ_EXEC &&
>  	    dtrace_lookup_by_name(dtp, scope, name, &sym, &dts) == 0) {
> -
>  		dt_module_t *mp = dt_module_lookup_by_name(dtp, dts.object);
>  		int umod = (mp->dm_flags & DT_DM_KERNEL) == 0;
>  		static const char *const kunames[] = { "kernel", "user" };
> -
>  		dtrace_typeinfo_t dtt;
>  		dtrace_syminfo_t *sip;
>  
> @@ -2992,7 +3005,6 @@ dt_xcook_ident(dt_node_t *dnp, dt_idhash_t *dhp, uint_t idkind, int create)
>  			idp->di_flags |= DT_IDFLG_USER;
>  			dnp->dn_flags |= DT_NF_USERLAND;
>  		}
> -
>  	} else if (scope == DTRACE_OBJ_EXEC && create == B_TRUE) {
>  		uint_t flags = DT_IDFLG_WRITE;
>  		uint_t id;
> @@ -3061,15 +3073,13 @@ dt_xcook_ident(dt_node_t *dnp, dt_idhash_t *dhp, uint_t idkind, int create)
>  			dt_cook_taint_alloca(dnp, idp, NULL);
>  
>  		dt_node_attr_assign(dnp, attr);
> -
>  	} else if (scope != DTRACE_OBJ_EXEC) {
>  		xyerror(D_IDENT_UNDEF, "failed to resolve %s%s%s: %s\n",
>  		    dnp->dn_string, markstr, name,
>  		    dtrace_errmsg(dtp, dtrace_errno(dtp)));
> -	} else {
> +	} else
>  		xyerror(D_IDENT_UNDEF, "failed to resolve %s: %s\n",
>  		    dnp->dn_string, dtrace_errmsg(dtp, dtrace_errno(dtp)));
> -	}
>  }
>  
>  static dt_node_t *
> diff --git a/test/triggers/Build b/test/triggers/Build
> index 4ff5002a..98556586 100644
> --- a/test/triggers/Build
> +++ b/test/triggers/Build
> @@ -106,6 +106,9 @@ proc-tst-omp_LDFLAGS := -fopenmp
>  proc-tst-pthread-exec_CFLAGS := -pthread
>  proc-tst-pthread-exec_LIBS := -pthread
>  
> +# Userspace scoped-type tests need type information in this executable.
> +testprobe_CFLAGS := -gctf
> +
>  # readwholedir is used for ustack() tests, so needs a symbol table and needs
>  # all its functions in it, even if they would be sibcalled out of existence.
>  readwholedir_CFLAGS := -fno-inline -fno-optimize-sibling-calls
> diff --git a/test/triggers/testprobe.c b/test/triggers/testprobe.c
> index 4bef92fe..22546ddf 100644
> --- a/test/triggers/testprobe.c
> +++ b/test/triggers/testprobe.c
> @@ -1,6 +1,6 @@
>  /*
>   * Oracle Linux DTrace.
> - * Copyright (c) 2005, 2012, Oracle and/or its affiliates. All rights reserved.
> + * Copyright (c) 2005, 2012, 2026, 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.
>   */
> @@ -17,10 +17,20 @@
>  #include <stdio.h>
>  #include <unistd.h>
>  
> +/* Keep a named type in the executable's CTF for userspace type-lookup tests. */
> +struct dtrace_scope_test_type {
> +    int value;
> +};
> +
> +static struct dtrace_scope_test_type dtrace_scope_test_instance;
> +
>  int main(int argc, char *argv[])
>  {
>      int fd, i;
>  
> +    /* Prevent optimization from discarding the test type. */
> +    dtrace_scope_test_instance.value = argc;
> +
>      if ((fd = open("/dev/dtrace/provider/dt_test", O_RDONLY)) == -1) {
>          perror("open");
>          exit(1);
> diff --git a/test/unittest/lexer/err.D_IDENT_UNDEF.scope-dot-kernel.r b/test/unittest/lexer/err.D_IDENT_UNDEF.scope-dot-kernel.r
> index 89a9f9c5..926e5a91 100644
> --- a/test/unittest/lexer/err.D_IDENT_UNDEF.scope-dot-kernel.r
> +++ b/test/unittest/lexer/err.D_IDENT_UNDEF.scope-dot-kernel.r
> @@ -1,2 +1,2 @@
>  -- @@stderr --
> -dtrace: failed to compile script test/unittest/lexer/err.D_IDENT_UNDEF.scope-dot-kernel.d: [D_IDENT_UNDEF] line 17: failed to resolve foo.bar`baz: Module is no longer loaded
> +dtrace: failed to compile script test/unittest/lexer/err.D_IDENT_UNDEF.scope-dot-kernel.d: [D_IDENT_UNDEF] line 17: failed to resolve foo.bar`baz: Unknown module name
> diff --git a/test/unittest/lexer/err.D_IDENT_UNDEF.scope-dot.r b/test/unittest/lexer/err.D_IDENT_UNDEF.scope-dot.r
> index 7734e29f..42a6ea95 100644
> --- a/test/unittest/lexer/err.D_IDENT_UNDEF.scope-dot.r
> +++ b/test/unittest/lexer/err.D_IDENT_UNDEF.scope-dot.r
> @@ -1,2 +1,2 @@
>  -- @@stderr --
> -dtrace: failed to compile script test/unittest/lexer/err.D_IDENT_UNDEF.scope-dot.d: [D_IDENT_UNDEF] line 17: failed to resolve foo.bar``baz: Module is no longer loaded
> +dtrace: failed to compile script test/unittest/lexer/err.D_IDENT_UNDEF.scope-dot.d: [D_IDENT_UNDEF] line 17: failed to resolve foo.bar``baz: Unknown module name
> diff --git a/test/unittest/lexer/err.D_SYM_BADREF.scope-kernel-as-user.d b/test/unittest/lexer/err.D_IDENT_UNDEF.scope-kernel-as-user.d
> similarity index 100%
> rename from test/unittest/lexer/err.D_SYM_BADREF.scope-kernel-as-user.d
> rename to test/unittest/lexer/err.D_IDENT_UNDEF.scope-kernel-as-user.d
> diff --git a/test/unittest/lexer/err.D_IDENT_UNDEF.scope-kernel-as-user.r b/test/unittest/lexer/err.D_IDENT_UNDEF.scope-kernel-as-user.r
> new file mode 100644
> index 00000000..3299b3c3
> --- /dev/null
> +++ b/test/unittest/lexer/err.D_IDENT_UNDEF.scope-kernel-as-user.r
> @@ -0,0 +1,2 @@
> +-- @@stderr --
> +dtrace: failed to compile script test/unittest/lexer/err.D_IDENT_UNDEF.scope-kernel-as-user.d: [D_IDENT_UNDEF] line 16: failed to resolve vmlinux``major_names: Unknown module name
> diff --git a/test/unittest/lexer/err.D_SYM_BADREF.scope-user-as-kernel.d b/test/unittest/lexer/err.D_IDENT_UNDEF.scope-user-as-kernel.d
> similarity index 100%
> rename from test/unittest/lexer/err.D_SYM_BADREF.scope-user-as-kernel.d
> rename to test/unittest/lexer/err.D_IDENT_UNDEF.scope-user-as-kernel.d
> diff --git a/test/unittest/lexer/err.D_IDENT_UNDEF.scope-user-as-kernel.r b/test/unittest/lexer/err.D_IDENT_UNDEF.scope-user-as-kernel.r
> new file mode 100644
> index 00000000..b952b509
> --- /dev/null
> +++ b/test/unittest/lexer/err.D_IDENT_UNDEF.scope-user-as-kernel.r
> @@ -0,0 +1,2 @@
> +-- @@stderr --
> +dtrace: failed to compile script test/unittest/lexer/err.D_IDENT_UNDEF.scope-user-as-kernel.d: [D_IDENT_UNDEF] line 18: failed to resolve testprobe`main: Unknown module name
> diff --git a/test/unittest/lexer/err.D_IDENT_UNDEF.scope-user-missing.d b/test/unittest/lexer/err.D_IDENT_UNDEF.scope-user-missing.d
> new file mode 100644
> index 00000000..7304da72
> --- /dev/null
> +++ b/test/unittest/lexer/err.D_IDENT_UNDEF.scope-user-missing.d
> @@ -0,0 +1,19 @@
> +/*
> + * Oracle Linux DTrace.
> + * Copyright (c) 2026, 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: An explicitly-scoped userspace symbol reports a lookup error
> + * when its module cannot be found.
> + */
> +
> +#pragma D option quiet
> +
> +BEGIN
> +{
> +	trace(no_such_module``main);
> +	exit(0);
> +}
> diff --git a/test/unittest/lexer/err.D_IDENT_UNDEF.scope-user-missing.r b/test/unittest/lexer/err.D_IDENT_UNDEF.scope-user-missing.r
> new file mode 100644
> index 00000000..3e752fc9
> --- /dev/null
> +++ b/test/unittest/lexer/err.D_IDENT_UNDEF.scope-user-missing.r
> @@ -0,0 +1,2 @@
> +-- @@stderr --
> +dtrace: failed to compile script test/unittest/lexer/err.D_IDENT_UNDEF.scope-user-missing.d: [D_IDENT_UNDEF] line 17: failed to resolve no_such_module``main: Unknown module name
> diff --git a/test/unittest/lexer/err.D_SYM_BADREF.scope-kernel-as-user.r b/test/unittest/lexer/err.D_SYM_BADREF.scope-kernel-as-user.r
> deleted file mode 100644
> index 718b2b31..00000000
> --- a/test/unittest/lexer/err.D_SYM_BADREF.scope-kernel-as-user.r
> +++ /dev/null
> @@ -1,2 +0,0 @@
> --- @@stderr --
> -dtrace: failed to compile script test/unittest/lexer/err.D_SYM_BADREF.scope-kernel-as-user.d: [D_SYM_BADREF] line 16: kernel module 'vmlinux' symbol 'major_names' may not be referenced as a user symbol
> diff --git a/test/unittest/lexer/err.D_SYM_BADREF.scope-user-as-kernel.r b/test/unittest/lexer/err.D_SYM_BADREF.scope-user-as-kernel.r
> deleted file mode 100644
> index 87169597..00000000
> --- a/test/unittest/lexer/err.D_SYM_BADREF.scope-user-as-kernel.r
> +++ /dev/null
> @@ -1,2 +0,0 @@
> --- @@stderr --
> -dtrace: failed to compile script test/unittest/lexer/err.D_SYM_BADREF.scope-user-as-kernel.d: [D_SYM_BADREF] line 18: user module 'testprobe' symbol 'main' may not be referenced as a kernel symbol
> diff --git a/test/unittest/lexer/tst.scope-user-explicit.d b/test/unittest/lexer/tst.scope-user-explicit.d
> index 2d649f6f..daead7b3 100644
> --- a/test/unittest/lexer/tst.scope-user-explicit.d
> +++ b/test/unittest/lexer/tst.scope-user-explicit.d
> @@ -6,7 +6,7 @@
>   */
>  
>  /* @@trigger: testprobe */
> -/* @@runtest-opts: -e */
> +/* @@runtest-opts: -e -xlinkmode=static */
>  
>  /*
>   * ASSERTION: Explicit userspace module scoping resolves as a userspace
> diff --git a/test/unittest/lexer/tst.scope-user-explicit.r b/test/unittest/lexer/tst.scope-user-explicit.r
> new file mode 100644
> index 00000000..e69de29b
> diff --git a/test/unittest/lexer/tst.scope-user-path-empty.sh b/test/unittest/lexer/tst.scope-user-path-empty.sh
> new file mode 100755
> index 00000000..00502578
> --- /dev/null
> +++ b/test/unittest/lexer/tst.scope-user-path-empty.sh
> @@ -0,0 +1,27 @@
> +#!/bin/bash
> +#
> +# Oracle Linux DTrace.
> +# Copyright (c) 2026, 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: An empty trailing entry in PATH or LD_LIBRARY_PATH denotes the
> +# current directory when resolving a userspace module.
> +#
> +
> +dtrace=$1
> +dir=$tmpdir/scope-user-path-empty.$$
> +
> +mkdir -p "$dir" || exit 1
> +trap 'rm -rf "$dir"' EXIT
> +cp test/triggers/testprobe "$dir/testprobe" || exit 1
> +cd "$dir" || exit 1
> +
> +PATH=.: LD_LIBRARY_PATH=.: "$dtrace" $dt_flags -e -c testprobe -n '
> +BEGIN
> +{
> +	trace(&testprobe``main);
> +	exit(0);
> +}'
> diff --git a/test/unittest/types/err.D_DECL_SCOPE.scopeop-enumerator.r b/test/unittest/types/err.D_DECL_SCOPE.scopeop-enumerator.r
> index 06ef912b..48ee9b20 100644
> --- a/test/unittest/types/err.D_DECL_SCOPE.scopeop-enumerator.r
> +++ b/test/unittest/types/err.D_DECL_SCOPE.scopeop-enumerator.r
> @@ -1,2 +1,2 @@
>  -- @@stderr --
> -dtrace: failed to compile script test/unittest/types/err.D_DECL_SCOPE.scopeop-enumerator.d: [D_DECL_SCOPE] line 15: D scoping operator may not be used in an enumerator name (foo`bar)
> +dtrace: failed to compile script test/unittest/types/err.D_DECL_SCOPE.scopeop-enumerator.d: [D_DECL_SCOPE] line 16: D scoping operator may not be used in an enumerator name (foo`bar)
> diff --git a/test/unittest/types/tst.scope-user-dotted.r b/test/unittest/types/tst.scope-user-dotted.r
> new file mode 100644
> index 00000000..e69de29b
> diff --git a/test/unittest/types/tst.scope-user-dotted.sh b/test/unittest/types/tst.scope-user-dotted.sh
> new file mode 100755
> index 00000000..3d0348b7
> --- /dev/null
> +++ b/test/unittest/types/tst.scope-user-dotted.sh
> @@ -0,0 +1,28 @@
> +#!/bin/bash
> +#
> +# Oracle Linux DTrace.
> +# Copyright (c) 2026, 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: A dotted userspace module name resolves both external symbols
> +# and types.
> +#
> +
> +dtrace=$1
> +dir=$tmpdir/scope-user-dotted.$$
> +
> +mkdir -p "$dir" || exit 1
> +trap 'rm -rf "$dir"' EXIT
> +cp test/triggers/testprobe "$dir/scope.user" || exit 1
> +cd "$dir" || exit 1
> +
> +PATH=.: "$dtrace" $dt_flags -e -xlinkmode=static -c scope.user -n '
> +BEGIN
> +{
> +	symbol = &scope.user``main;
> +	type = (struct scope.user``dtrace_scope_test_type *)NULL;
> +	exit(0);
> +}'
> diff --git a/test/unittest/types/tst.scope-user-types.d b/test/unittest/types/tst.scope-user-types.d
> new file mode 100644
> index 00000000..380af340
> --- /dev/null
> +++ b/test/unittest/types/tst.scope-user-types.d
> @@ -0,0 +1,24 @@
> +/*
> + * Oracle Linux DTrace.
> + * Copyright (c) 2026, 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.
> + */
> +
> +/* @@trigger: testprobe */
> +/* @@runtest-opts: -e -xlinkmode=static */
> +
> +/*
> + * ASSERTION: Explicit and implicit userspace type scopes, and the implicit
> + * kernel type scope, resolve external types.
> + */
> +
> +#pragma D option quiet
> +
> +BEGIN
> +{
> +	scope_explicit = (struct testprobe``dtrace_scope_test_type *)NULL;
> +	scope_implicit = (struct ``dtrace_scope_test_type *)NULL;
> +	scope_kernel = (struct `task_struct *)NULL;
> +	exit(0);
> +}
> diff --git a/test/unittest/types/tst.scope-user-types.r b/test/unittest/types/tst.scope-user-types.r
> new file mode 100644
> index 00000000..e69de29b
> -- 
> 2.52.0
> 
> 
> _______________________________________________
> DTrace-devel mailing list
> DTrace-devel@oss.oracle.com
> https://oss.oracle.com/mailman/listinfo/dtrace-devel
> 


^ permalink raw reply	[flat|nested] 2+ messages in thread

end of thread, other threads:[~2026-10-03  8:41 UTC | newest]

Thread overview: 2+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-09-28 18:02 [PATCH 5/8] parser: resolve explicitly scoped user objects Kris Van Hees
2026-10-03  8:40 ` [DTrace-devel] " Elena Zannoni

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.