[DTrace-devel] [PATCH 3/9] Dedicate space for call stacks

eugene.loh at oracle.com eugene.loh at oracle.com
Thu Oct 5 21:14:01 UTC 2023


From: Eugene Loh <eugene.loh at oracle.com>

In the dctx->mem memory block, storage for a call stack and storage
for tstrings overlapped.  The rationale was that a stack() action and
temporary strings would never co-exist.

However, the call stack storage wasn't being used for stack() (or ustack
or jstack) actions at all.  It was being used for stackdepth (and
ustackdepth and jstackdepth) built-in variables.  And they could
co-exist with temporary strings.

So make the call stack storage its own area within dctx->mem.

Add a test to check for the overlap bug.

Signed-off-by: Eugene Loh <eugene.loh at oracle.com>
---
 bpf/get_bvar.c                                |  3 ++-
 libdtrace/dt_bpf.h                            |  1 +
 libdtrace/dt_cc.c                             |  3 +++
 libdtrace/dt_dctx.h                           | 14 +++++++------
 libdtrace/dt_dlibs.c                          |  1 +
 .../codegen/tst.tstring_overlap_bug.d         | 21 +++++++++++++++++++
 .../codegen/tst.tstring_overlap_bug.r         |  4 ++++
 7 files changed, 40 insertions(+), 7 deletions(-)
 create mode 100644 test/unittest/codegen/tst.tstring_overlap_bug.d
 create mode 100644 test/unittest/codegen/tst.tstring_overlap_bug.r

diff --git a/bpf/get_bvar.c b/bpf/get_bvar.c
index de3fdbc6..ee8f756f 100644
--- a/bpf/get_bvar.c
+++ b/bpf/get_bvar.c
@@ -27,6 +27,7 @@ extern uint64_t PC;
 extern uint64_t STBSZ;
 extern uint64_t STKSIZ;
 extern uint64_t BOOTTM;
+extern uint64_t MEM_STACK;
 
 #define error(dctx, fault, illval) \
 	({ \
@@ -64,7 +65,7 @@ noinline uint64_t dt_get_bvar(const dt_dctx_t *dctx, uint32_t id, uint32_t idx)
 	case DIF_VAR_USTACKDEPTH: {
 		uint32_t bufsiz = (uint32_t) (uint64_t) (&STKSIZ);
 		uint64_t flags = 0 & BPF_F_SKIP_FIELD_MASK;
-		char *buf = dctx->mem;
+		char *buf = dctx->mem + (uint64_t)(&MEM_STACK);
 		uint64_t stacksize;
 
 		if (id == DIF_VAR_USTACKDEPTH)
diff --git a/libdtrace/dt_bpf.h b/libdtrace/dt_bpf.h
index 0fee533b..0b883936 100644
--- a/libdtrace/dt_bpf.h
+++ b/libdtrace/dt_bpf.h
@@ -40,6 +40,7 @@ extern "C" {
 #define DT_CONST_RODATA_OFF		19
 #define DT_CONST_RODATA_SIZE		20
 #define DT_CONST_ZERO_OFF		21
+#define DT_CONST_MEM_STACK		22
 
 #define DT_BPF_LOG_SIZE_DEFAULT	(UINT32_MAX >> 8)
 #define DT_BPF_LOG_SIZE_SMALL	4096
diff --git a/libdtrace/dt_cc.c b/libdtrace/dt_cc.c
index a42109f1..b35b8821 100644
--- a/libdtrace/dt_cc.c
+++ b/libdtrace/dt_cc.c
@@ -1173,6 +1173,9 @@ dt_link_construct(dtrace_hdl_t *dtp, const dt_probe_t *prp, dtrace_difo_t *dp,
 			case DT_CONST_ZERO_OFF:
 				nrp->dofr_data = dtp->dt_zerooffset;
 				continue;
+			case DT_CONST_MEM_STACK:
+				nrp->dofr_data = DMEM_STACK(dtp);
+				continue;
 			default:
 				/* probe name -> value is probe id */
 				if (strchr(idp->di_name, ':') != NULL)
diff --git a/libdtrace/dt_dctx.h b/libdtrace/dt_dctx.h
index 319e4233..1422ad24 100644
--- a/libdtrace/dt_dctx.h
+++ b/libdtrace/dt_dctx.h
@@ -97,11 +97,11 @@ typedef struct dt_dctx {
  * The dctx->mem pointer references a block of memory that contains:
  *
  *                       +----------------+----------------+
- *                  0 -> | Stack          :     tstring    | \
- *                       |   trace     (shared)   storage  |  |
- *                       |     storage    :                |  |
- *                       +----------------+----------------+   > DMEM_SIZE
+ *                  0 -> |        tstring storage          | \
+ *                       +----------------+----------------+  |
  *        DMEM_STRTOK -> |     strtok() internal state     |  |
+ *                       +---------------------------------+   > DMEM_SIZE
+ *        DMEM_STACK  -> |          stack storage          |  |
  *                       +---------------------------------+  |
  *        DMEM_TUPLE  -> |       tuple assembly area       | /
  *                       +---------------------------------+
@@ -127,9 +127,11 @@ typedef struct dt_dctx {
  * Macros to determine the offset of the components of dctx->mem.
  */
 #define DMEM_STRTOK(dtp) \
-		MAX(DMEM_STACK_SZ(dtp), DMEM_TSTR_SZ(dtp))
-#define DMEM_TUPLE(dtp) \
+		DMEM_TSTR_SZ(dtp)
+#define DMEM_STACK(dtp) \
 		(DMEM_STRTOK(dtp) + DMEM_STRTOK_SZ(dtp))
+#define DMEM_TUPLE(dtp) \
+		(DMEM_STACK(dtp) + DMEM_STACK_SZ(dtp))
 
 /*
  * Macro to determine the total size of the mem area.
diff --git a/libdtrace/dt_dlibs.c b/libdtrace/dt_dlibs.c
index 02a24ad2..bdd02f4a 100644
--- a/libdtrace/dt_dlibs.c
+++ b/libdtrace/dt_dlibs.c
@@ -94,6 +94,7 @@ static const dt_ident_t		dt_bpf_symbols[] = {
 	DT_BPF_SYMBOL_ID(RODATA_OFF, DT_IDENT_SCALAR, DT_CONST_RODATA_OFF),
 	DT_BPF_SYMBOL_ID(RODATA_SIZE, DT_IDENT_SCALAR, DT_CONST_RODATA_SIZE),
 	DT_BPF_SYMBOL_ID(ZERO_OFF, DT_IDENT_SCALAR, DT_CONST_ZERO_OFF),
+	DT_BPF_SYMBOL_ID(MEM_STACK, DT_IDENT_SCALAR, DT_CONST_MEM_STACK),
 
 	/* End-of-list marker */
 	{ NULL, }
diff --git a/test/unittest/codegen/tst.tstring_overlap_bug.d b/test/unittest/codegen/tst.tstring_overlap_bug.d
new file mode 100644
index 00000000..df2f87db
--- /dev/null
+++ b/test/unittest/codegen/tst.tstring_overlap_bug.d
@@ -0,0 +1,21 @@
+/*
+ * 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.
+ */
+
+/*
+ * Check for a bug in which tstrings and stackdepth scratch overlapped.
+ */
+
+#pragma D option quiet
+
+BEGIN
+{
+	printf("stack depth is %d\n", stackdepth);
+	i = stackdepth;
+	printf("substring is |%s|\n", substr(strjoin("abcdefghijkl", "mnopqrstuvwxyz"), i));
+	printf("substring is |%s|\n", substr(strjoin("abcdefghijkl", "mnopqrstuvwxyz"), stackdepth));
+	exit(0);
+}
diff --git a/test/unittest/codegen/tst.tstring_overlap_bug.r b/test/unittest/codegen/tst.tstring_overlap_bug.r
new file mode 100644
index 00000000..dc92dbbc
--- /dev/null
+++ b/test/unittest/codegen/tst.tstring_overlap_bug.r
@@ -0,0 +1,4 @@
+stack depth is 0
+substring is |abcdefghijklmnopqrstuvwxyz|
+substring is |abcdefghijklmnopqrstuvwxyz|
+
-- 
2.18.4




More information about the DTrace-devel mailing list