]> sourceware.org Git - systemtap.git/commitdiff
Added dtrace testcases for clone, fork/exec, and vfork/exec.
authorDavid Smith <dsmith@redhat.com>
Mon, 4 Oct 2010 20:48:18 +0000 (15:48 -0500)
committerDavid Smith <dsmith@redhat.com>
Mon, 4 Oct 2010 20:48:18 +0000 (15:48 -0500)
* testsuite/systemtap.clone/Makefile.clone: New file.
* testsuite/systemtap.clone/Makefile.fork_exec: Ditto.
* testsuite/systemtap.clone/Makefile.vfork_exec: Ditto.
* testsuite/systemtap.clone/dtrace_child.c: Ditto.
* testsuite/systemtap.clone/dtrace_child_probes.d: Ditto.
* testsuite/systemtap.clone/dtrace_clone.c: Ditto.
* testsuite/systemtap.clone/dtrace_clone.exp: Ditto.
* testsuite/systemtap.clone/dtrace_clone.stp: Ditto.
* testsuite/systemtap.clone/dtrace_clone_probes.d: Ditto.
* testsuite/systemtap.clone/dtrace_fork_exec.exp: Ditto.
* testsuite/systemtap.clone/dtrace_fork_exec.stp: Ditto.
* testsuite/systemtap.clone/dtrace_fork_parent.c: Ditto.
* testsuite/systemtap.clone/dtrace_fork_parent_probes.d: Ditto.
* testsuite/systemtap.clone/dtrace_vfork_exec.exp: Ditto.
* testsuite/systemtap.clone/dtrace_vfork_exec.stp: Ditto.
* testsuite/systemtap.clone/dtrace_vfork_parent.c: Ditto.
* testsuite/systemtap.clone/dtrace_vfork_parent_probes.d: Ditto.
* testsuite/systemtap.clone/test_progs.tcl: Ditto.

18 files changed:
testsuite/systemtap.clone/Makefile.clone [new file with mode: 0644]
testsuite/systemtap.clone/Makefile.fork_exec [new file with mode: 0644]
testsuite/systemtap.clone/Makefile.vfork_exec [new file with mode: 0644]
testsuite/systemtap.clone/dtrace_child.c [new file with mode: 0644]
testsuite/systemtap.clone/dtrace_child_probes.d [new file with mode: 0644]
testsuite/systemtap.clone/dtrace_clone.c [new file with mode: 0644]
testsuite/systemtap.clone/dtrace_clone.exp [new file with mode: 0644]
testsuite/systemtap.clone/dtrace_clone.stp [new file with mode: 0644]
testsuite/systemtap.clone/dtrace_clone_probes.d [new file with mode: 0644]
testsuite/systemtap.clone/dtrace_fork_exec.exp [new file with mode: 0644]
testsuite/systemtap.clone/dtrace_fork_exec.stp [new file with mode: 0644]
testsuite/systemtap.clone/dtrace_fork_parent.c [new file with mode: 0644]
testsuite/systemtap.clone/dtrace_fork_parent_probes.d [new file with mode: 0644]
testsuite/systemtap.clone/dtrace_vfork_exec.exp [new file with mode: 0644]
testsuite/systemtap.clone/dtrace_vfork_exec.stp [new file with mode: 0644]
testsuite/systemtap.clone/dtrace_vfork_parent.c [new file with mode: 0644]
testsuite/systemtap.clone/dtrace_vfork_parent_probes.d [new file with mode: 0644]
testsuite/systemtap.clone/test_progs.tcl [new file with mode: 0644]

diff --git a/testsuite/systemtap.clone/Makefile.clone b/testsuite/systemtap.clone/Makefile.clone
new file mode 100644 (file)
index 0000000..f704e90
--- /dev/null
@@ -0,0 +1,24 @@
+CFLAGS += -g -O2
+
+DTRACE := dtrace
+
+OBJS := dtrace_clone.o dtrace_clone_probes.o
+
+TARGETS := dtrace_clone
+
+BUILT_SOURCES := dtrace_clone_probes.h
+
+all: $(TARGETS)
+
+dtrace_clone: $(OBJS)
+
+dtrace_clone.c: dtrace_clone_probes.h
+
+%.h: %.d
+       $(DTRACE) -C -h -s $< -o $@
+
+%.o: %.d
+       $(DTRACE) -C -G -s $< -o $@
+
+clean:
+       rm -f $(OBJS) $(TARGETS) $(BUILT_SOURCES)
diff --git a/testsuite/systemtap.clone/Makefile.fork_exec b/testsuite/systemtap.clone/Makefile.fork_exec
new file mode 100644 (file)
index 0000000..919a9ba
--- /dev/null
@@ -0,0 +1,32 @@
+PWD := $(shell pwd)
+
+CFLAGS += -g -O2 -DTEST_DIR="$(PWD)"
+
+DTRACE := dtrace
+
+PARENT_OBJS := dtrace_fork_parent.o dtrace_fork_parent_probes.o
+
+CHILD_OBJS := dtrace_child.o dtrace_child_probes.o
+
+TARGETS := dtrace_fork_parent dtrace_child
+
+BUILT_SOURCES := dtrace_fork_parent_probes.h dtrace_child_probes.h
+
+all: $(TARGETS)
+
+dtrace_fork_parent: $(PARENT_OBJS)
+
+dtrace_fork_parent.c: dtrace_fork_parent_probes.h
+
+dtrace_child: $(CHILD_OBJS)
+
+dtrace_child.c: dtrace_child_probes.h
+
+%.h: %.d
+       $(DTRACE) -C -h -s $< -o $@
+
+%.o: %.d
+       $(DTRACE) -C -G -s $< -o $@
+
+clean:
+       rm -f $(PARENT_OBJS) $(CHILD_OBJS) $(TARGETS) $(BUILT_SOURCES)
diff --git a/testsuite/systemtap.clone/Makefile.vfork_exec b/testsuite/systemtap.clone/Makefile.vfork_exec
new file mode 100644 (file)
index 0000000..58a24c7
--- /dev/null
@@ -0,0 +1,32 @@
+PWD := $(shell pwd)
+
+CFLAGS += -g -O2 -DTEST_DIR="$(PWD)"
+
+DTRACE := dtrace
+
+PARENT_OBJS := dtrace_vfork_parent.o dtrace_vfork_parent_probes.o
+
+CHILD_OBJS := dtrace_child.o dtrace_child_probes.o
+
+TARGETS := dtrace_vfork_parent dtrace_child
+
+BUILT_SOURCES := dtrace_vfork_parent_probes.h dtrace_child_probes.h
+
+all: $(TARGETS)
+
+dtrace_vfork_parent: $(PARENT_OBJS)
+
+dtrace_vfork_parent.c: dtrace_vfork_parent_probes.h
+
+dtrace_child: $(CHILD_OBJS)
+
+dtrace_child.c: dtrace_child_probes.h
+
+%.h: %.d
+       $(DTRACE) -C -h -s $< -o $@
+
+%.o: %.d
+       $(DTRACE) -C -G -s $< -o $@
+
+clean:
+       rm -f $(PARENT_OBJS) $(CHILD_OBJS) $(TARGETS) $(BUILT_SOURCES)
diff --git a/testsuite/systemtap.clone/dtrace_child.c b/testsuite/systemtap.clone/dtrace_child.c
new file mode 100644 (file)
index 0000000..34c6758
--- /dev/null
@@ -0,0 +1,22 @@
+/* Systemtap test case
+ * Copyright (C) 2010, Red Hat Inc.
+ *                                                          
+ * This file is part of systemtap, and is free software.  You can
+ * redistribute it and/or modify it under the terms of the GNU General
+ * Public License (GPL); either version 2, or (at your option) any
+ * later version.
+ */
+
+#include <stdio.h>
+#include <sys/types.h>
+#include <unistd.h>
+#include "dtrace_child_probes.h"
+
+int
+main(int argc, char **argv)
+{
+    if (CHILD_MAIN_ENABLED()) {
+       CHILD_MAIN(getpid());
+    }
+    return 0;
+}
diff --git a/testsuite/systemtap.clone/dtrace_child_probes.d b/testsuite/systemtap.clone/dtrace_child_probes.d
new file mode 100644 (file)
index 0000000..0f9c434
--- /dev/null
@@ -0,0 +1,3 @@
+provider child {
+        probe main(pid_t pid);
+};
diff --git a/testsuite/systemtap.clone/dtrace_clone.c b/testsuite/systemtap.clone/dtrace_clone.c
new file mode 100644 (file)
index 0000000..59d7ef1
--- /dev/null
@@ -0,0 +1,126 @@
+/* Systemtap test case
+ * Copyright (C) 2010, Red Hat Inc.
+ *                                                          
+ * This file is part of systemtap, and is free software.  You can
+ * redistribute it and/or modify it under the terms of the GNU General
+ * Public License (GPL); either version 2, or (at your option) any
+ * later version.
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <string.h>
+#include <fcntl.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <sys/wait.h>
+#include <sched.h>
+#include <errno.h>
+#include "dtrace_clone_probes.h"
+
+#if !defined(CLONE_NEWPID)
+#define CLONE_NEWPID 0
+#endif
+
+#define CLONE_FLAGS (CLONE_NEWPID|CLONE_FILES|CLONE_FS|CLONE_VM|SIGCHLD)
+
+void *stack_base2 = NULL;
+void *stack_top2 = NULL;
+
+static int uprobes_ns_child2(void *argv __attribute__((__unused__)))
+{
+    if (TEST_CHILD2_ENABLED()) {
+       TEST_CHILD2(getpid());
+    }
+    _exit(0);
+}
+
+static int uprobes_ns_child1(void *argv __attribute__((__unused__)))
+{
+    int pid;
+    int rc = 0;
+
+    /* Create the second clone. */
+    if (TEST_CHILD1_ENABLED()) {
+       TEST_CHILD1(getpid());
+    }
+
+    pid = clone(uprobes_ns_child2, stack_top2, CLONE_FLAGS, NULL);
+    if (TEST_CHILD2_PID_ENABLED()) {
+       TEST_CHILD2_PID(pid);
+    }
+    if (pid < 0) {
+       /* Error. */
+       char *msg2 = "clone 2 failed\n";
+       write(2, msg2, strlen(msg2));
+       rc = errno;
+    }
+    else {
+       int status;
+
+       waitpid(pid, &status, 0);
+       rc = WEXITSTATUS(status);
+    }
+    _exit(rc);
+}
+
+int
+main(int argc, char **argv)
+{
+    long pagesize = sysconf(_SC_PAGESIZE);
+    void *stack_base1, *stack_top1;
+    int pid;
+    int rc = 0;
+
+    /* Allocate both stacks here. */
+    stack_base1 = calloc(pagesize * 4, 1);
+    if (stack_base1 == NULL) {
+       perror("calloc 1 failed:");
+       return -1;
+    }
+    stack_base2 = calloc(pagesize * 4, 1);
+    if (stack_base2 == NULL) {
+       perror("calloc 2 failed:");
+       return -1;
+    }
+
+    /*
+     * Get top of stacks.  According to the clone() manpage:
+     *   Stacks grow downwards on all processors that run Linux
+     *   (except the HP PA processors), so child_stack usually points
+     *   to the topmost address of the memory space set up for the
+     *   child stack. 
+     */
+    stack_top1 = stack_base1 + (pagesize * 4);
+    stack_top2 = stack_base2 + (pagesize * 4);
+
+    /* Create the first clone (which will create the 2nd). */
+    if (TEST_MAIN_ENABLED()) {
+       TEST_MAIN(getpid());
+    }
+    pid = clone(uprobes_ns_child1, stack_top1, CLONE_FLAGS, NULL);
+    if (TEST_CHILD1_PID_ENABLED()) {
+       TEST_CHILD1_PID(pid);
+    }
+    if (pid < 0) {
+       /* error */
+       perror("clone 1 failed:");
+       rc = -1;
+    }
+    else {
+       int status;
+
+       /* Wait on the first clone to finish. */
+       waitpid(pid, &status, 0);
+       rc = WEXITSTATUS(status);
+    }
+    /* Cleanup */
+    free(stack_base1);
+    free(stack_base2);
+    if (TEST_MAIN2_ENABLED()) {
+       TEST_MAIN2();
+    }
+
+    return rc;
+}
diff --git a/testsuite/systemtap.clone/dtrace_clone.exp b/testsuite/systemtap.clone/dtrace_clone.exp
new file mode 100644 (file)
index 0000000..130327a
--- /dev/null
@@ -0,0 +1,46 @@
+set TEST_NAME "dtrace_clone"
+set build_dir ""
+set test_progs {"dtrace_clone"}
+
+if {![installtest_p]} { untested $TEST_NAME; return }
+if {![uprobes_p]} { untested $TEST_NAME; return }
+
+source $srcdir/$subdir/test_progs.tcl
+
+# Build everything
+set TEST_NAME "dtrace_clone1"
+if {[build_test_progs "Makefile.clone" $test_progs] == 0} {
+    fail "$TEST_NAME - build failure"
+    cleanup_test_progs
+    return
+} else {
+    pass "$TEST_NAME - build success"
+}
+
+# We have to be root to use CLONE_NEWPID.
+proc run_test_prog {} {
+    global build_dir
+    as_root $build_dir/dtrace_clone
+    return 0
+}
+
+# Run the test.
+#
+# Here's an explanation of the output.  On kernels that support
+# CLONE_NEWPID (new pid namespace), we'll see the following output:
+#   main - pid: XXX
+#   main - child pid: YYY
+#   child1 - pid: 1
+#   child1 - child2 pid: 2
+#   child2 - pid: 1
+#   main - finished
+# On kernels with CLONE_NEWPID, the pids assigned to the children are
+# fixed since they exist in their own pid namespace.  Because not all
+# kernels support CLONE_NEWPID, we have to accept all pids.
+set TEST_NAME "dtrace_clone2"
+set output_string "main - pid: \[0-9\]+\r\nmain - child pid: \[0-9\]+\r\nchild1 - pid: \[0-9\]+\r\nchild1 - child2 pid: \[0-9\]+\r\nchild2 - pid: \[0-9\]+\r\nmain - finished\r\n"
+stap_run $TEST_NAME run_test_prog $output_string \
+  $srcdir/$subdir/dtrace_clone.stp $build_dir/dtrace_clone
+
+# Cleanup
+cleanup_test_progs
diff --git a/testsuite/systemtap.clone/dtrace_clone.stp b/testsuite/systemtap.clone/dtrace_clone.stp
new file mode 100644 (file)
index 0000000..fb1dbdb
--- /dev/null
@@ -0,0 +1,44 @@
+global output_string
+
+# Original (parent) probes
+probe process(@1).mark("main")
+{
+       output_string .= sprintf("main - pid: %d\n", $arg1)
+}
+probe process(@1).mark("child1_pid")
+{
+       output_string .= sprintf("main - child pid: %d\n", $arg1)
+}
+probe process(@1).mark("main2")
+{
+       output_string .= sprintf("main - finished\n")
+       exit()
+}
+
+# Child1 probes
+probe process(@1).mark("child1") 
+{
+       output_string .= sprintf("child1 - pid: %d\n", $arg1)
+}
+probe process(@1).mark("child2_pid")
+{
+       output_string .= sprintf("child1 - child2 pid: %d\n", $arg1)
+}
+
+# Child2 probes
+probe process(@1).mark("child2")
+{
+       output_string .= sprintf("child2 - pid: %d\n", $arg1)
+}
+
+# Testsuite glue
+probe begin
+{
+       printf("systemtap starting probe\n");
+}
+
+probe end
+{
+       printf("systemtap ending probe\n");
+       printf("%s", output_string);
+}
diff --git a/testsuite/systemtap.clone/dtrace_clone_probes.d b/testsuite/systemtap.clone/dtrace_clone_probes.d
new file mode 100644 (file)
index 0000000..00a5b11
--- /dev/null
@@ -0,0 +1,8 @@
+provider test {
+        probe main(pid_t pid);
+        probe main2();
+        probe child1(pid_t pid);
+        probe child1_pid(pid_t pid);
+        probe child2(pid_t pid);
+        probe child2_pid(pid_t pid);
+};
diff --git a/testsuite/systemtap.clone/dtrace_fork_exec.exp b/testsuite/systemtap.clone/dtrace_fork_exec.exp
new file mode 100644 (file)
index 0000000..4da9226
--- /dev/null
@@ -0,0 +1,33 @@
+set TEST_NAME "dtrace_fork_exec"
+set build_dir ""
+set test_progs {"dtrace_fork_parent" "dtrace_child"}
+
+if {![installtest_p]} { untested $TEST_NAME; return }
+if {![uprobes_p]} { untested $TEST_NAME; return }
+
+source $srcdir/$subdir/test_progs.tcl
+
+# Build everything
+if {[build_test_progs "Makefile.fork_exec" $test_progs] == 0} {
+    fail "$TEST_NAME - build failure"
+    cleanup_test_progs
+    return
+} else {
+    pass "$TEST_NAME - build success"
+}
+
+proc run_test_prog {} {
+    global build_dir
+    catch { exec $build_dir/dtrace_fork_parent $build_dir/dtrace_child }
+    return 0
+}
+
+# Run the test
+set TEST_NAME "dtrace_fork_exec2"
+set output_string "parent - pid: \[0-9\]+\r\nparent - child pid: \[0-9\]+\r\nparent - child pid before exec: \[0-9\]+\r\nchild - pid: \[0-9\]+\r\nparent - finished\r\n"
+stap_run $TEST_NAME run_test_prog $output_string \
+  $srcdir/$subdir/dtrace_fork_exec.stp $build_dir/dtrace_fork_parent \
+  $build_dir/dtrace_child
+
+# Cleanup
+cleanup_test_progs
diff --git a/testsuite/systemtap.clone/dtrace_fork_exec.stp b/testsuite/systemtap.clone/dtrace_fork_exec.stp
new file mode 100644 (file)
index 0000000..b6bf694
--- /dev/null
@@ -0,0 +1,38 @@
+global output_string
+
+# Parent probes
+probe process(@1).mark("main")
+{
+       output_string .= sprintf("parent - pid: %d\n", $arg1)
+}
+probe process(@1).mark("child")
+{
+       output_string .= sprintf("parent - child pid before exec: %d\n", $arg1)
+}
+probe process(@1).mark("child_pid")
+{
+       output_string .= sprintf("parent - child pid: %d\n", $arg1)
+}
+probe process(@1).mark("finished")
+{
+       output_string .= sprintf("parent - finished\n")
+       exit()
+}
+
+# Child probes
+probe process(@2).mark("main")
+{
+       output_string .= sprintf("child - pid: %d\n", $arg1)
+}
+
+# Testsuite glue
+probe begin
+{
+       printf("systemtap starting probe\n");
+}
+
+probe end
+{
+       printf("systemtap ending probe\n");
+       printf("%s", output_string);
+}
diff --git a/testsuite/systemtap.clone/dtrace_fork_parent.c b/testsuite/systemtap.clone/dtrace_fork_parent.c
new file mode 100644 (file)
index 0000000..ba88500
--- /dev/null
@@ -0,0 +1,57 @@
+/* Systemtap test case
+ * Copyright (C) 2010, Red Hat Inc.
+ *                                                          
+ * This file is part of systemtap, and is free software.  You can
+ * redistribute it and/or modify it under the terms of the GNU General
+ * Public License (GPL); either version 2, or (at your option) any
+ * later version.
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <string.h>
+#include <sched.h>
+#include <errno.h>
+#include "dtrace_fork_parent_probes.h"
+
+int
+main(int argc, char **argv)
+{
+    int pid;
+    int rc = 0;
+    char *child_argv[] = { argv[1], NULL };
+
+    /* Create the child. */
+    if (PARENT_MAIN_ENABLED()) {
+       PARENT_MAIN(getpid());
+    }
+    pid = fork();
+    if (pid == 0) {                    /* child */
+       if (PARENT_CHILD_ENABLED()) {
+           PARENT_CHILD(getpid());
+       }
+       rc = execve(argv[1], child_argv, NULL);
+       _exit(rc);
+    }
+
+    if (PARENT_CHILD_PID_ENABLED()) {
+       PARENT_CHILD_PID(pid);
+    }
+    if (pid < 0) {
+       /* error */
+       perror("fork failed:");
+       rc = -1;
+    }
+    else {
+       int status;
+
+       waitpid(pid, &status, 0);
+       rc = WEXITSTATUS(status);
+    }
+
+    if (PARENT_FINISHED_ENABLED()) {
+       PARENT_FINISHED();
+    }
+    return rc;
+}
diff --git a/testsuite/systemtap.clone/dtrace_fork_parent_probes.d b/testsuite/systemtap.clone/dtrace_fork_parent_probes.d
new file mode 100644 (file)
index 0000000..f8af024
--- /dev/null
@@ -0,0 +1,6 @@
+provider parent {
+        probe main(pid_t pid);
+        probe child(pid_t pid);
+        probe child_pid(pid_t pid);
+        probe finished();
+};
diff --git a/testsuite/systemtap.clone/dtrace_vfork_exec.exp b/testsuite/systemtap.clone/dtrace_vfork_exec.exp
new file mode 100644 (file)
index 0000000..5530c61
--- /dev/null
@@ -0,0 +1,33 @@
+set TEST_NAME "dtrace_vfork_exec"
+set build_dir ""
+set test_progs {"dtrace_vfork_parent" "dtrace_child"}
+
+if {![installtest_p]} { untested $TEST_NAME; return }
+if {![uprobes_p]} { untested $TEST_NAME; return }
+
+source $srcdir/$subdir/test_progs.tcl
+
+# Build everything
+if {[build_test_progs "Makefile.vfork_exec" $test_progs] == 0} {
+    fail "$TEST_NAME - build failure"
+    cleanup_test_progs
+    return
+} else {
+    pass "$TEST_NAME - build success"
+}
+
+proc run_test_prog {} {
+    global build_dir
+    catch { exec $build_dir/dtrace_vfork_parent $build_dir/dtrace_child }
+    return 0
+}
+
+# Run the test
+set TEST_NAME "dtrace_vfork_exec2"
+set output_string "parent - pid: \[0-9\]+\r\nparent - child pid: \[0-9\]+\r\nchild - pid: \[0-9\]+\r\nparent - finished\r\n"
+stap_run $TEST_NAME run_test_prog $output_string \
+  $srcdir/$subdir/dtrace_vfork_exec.stp $build_dir/dtrace_vfork_parent \
+  $build_dir/dtrace_child
+
+# Cleanup
+cleanup_test_progs
diff --git a/testsuite/systemtap.clone/dtrace_vfork_exec.stp b/testsuite/systemtap.clone/dtrace_vfork_exec.stp
new file mode 100644 (file)
index 0000000..0c137c2
--- /dev/null
@@ -0,0 +1,34 @@
+global output_string
+
+# Parent probes
+probe process(@1).mark("main")
+{
+       output_string .= sprintf("parent - pid: %d\n", $arg1)
+}
+probe process(@1).mark("child_pid")
+{
+       output_string .= sprintf("parent - child pid: %d\n", $arg1)
+}
+probe process(@1).mark("finished")
+{
+       output_string .= sprintf("parent - finished\n")
+       exit()
+}
+
+# Child probes
+probe process(@2).mark("main")
+{
+       output_string .= sprintf("child - pid: %d\n", $arg1)
+}
+
+# Testsuite glue
+probe begin
+{
+       printf("systemtap starting probe\n");
+}
+
+probe end
+{
+       printf("systemtap ending probe\n");
+       printf("%s", output_string);
+}
diff --git a/testsuite/systemtap.clone/dtrace_vfork_parent.c b/testsuite/systemtap.clone/dtrace_vfork_parent.c
new file mode 100644 (file)
index 0000000..4433059
--- /dev/null
@@ -0,0 +1,54 @@
+/* Systemtap test case
+ * Copyright (C) 2010, Red Hat Inc.
+ *                                                          
+ * This file is part of systemtap, and is free software.  You can
+ * redistribute it and/or modify it under the terms of the GNU General
+ * Public License (GPL); either version 2, or (at your option) any
+ * later version.
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <string.h>
+#include <sched.h>
+#include <errno.h>
+#include "dtrace_vfork_parent_probes.h"
+
+int
+main(int argc, char **argv)
+{
+    int pid;
+    int rc = 0;
+    char *child_argv[] = { argv[1], NULL };
+
+    /* Create the child. */
+    if (PARENT_MAIN_ENABLED()) {
+       PARENT_MAIN(getpid());
+    }
+    pid = vfork();
+    if (pid == 0) {                    /* child */
+       rc = execve(argv[1], child_argv, NULL);
+       _exit(rc);
+    }
+
+    if (PARENT_CHILD_PID_ENABLED()) {
+       PARENT_CHILD_PID(pid);
+    }
+    if (pid < 0) {
+       /* error */
+       perror("fork failed:");
+       rc = -1;
+    }
+    else {
+       int status;
+
+       waitpid(pid, &status, 0);
+       rc = WEXITSTATUS(status);
+    }
+
+    if (PARENT_FINISHED_ENABLED()) {
+       PARENT_FINISHED();
+    }
+    return rc;
+}
diff --git a/testsuite/systemtap.clone/dtrace_vfork_parent_probes.d b/testsuite/systemtap.clone/dtrace_vfork_parent_probes.d
new file mode 100644 (file)
index 0000000..6a56e90
--- /dev/null
@@ -0,0 +1,5 @@
+provider parent {
+        probe main(pid_t pid);
+        probe child_pid(pid_t pid);
+        probe finished();
+};
diff --git a/testsuite/systemtap.clone/test_progs.tcl b/testsuite/systemtap.clone/test_progs.tcl
new file mode 100644 (file)
index 0000000..0691920
--- /dev/null
@@ -0,0 +1,38 @@
+proc build_test_progs {Makefile test_progs} {
+    global build_dir
+    global srcdir subdir
+    global env
+
+    # Create the build directory and populate it
+    if {[catch {exec mktemp -d staptestXXXXXX} build_dir]} {
+       verbose -log "Failed to create temporary directory: $build_dir"
+       return 0
+    }
+    foreach f [glob $srcdir/$subdir/*.c $srcdir/$subdir/*.d] {
+       exec cp $f $build_dir/
+    }
+    exec cp $srcdir/$subdir/$Makefile $build_dir/Makefile
+
+    # Run make.
+    set includes "-isystem$env(SYSTEMTAP_INCLUDES)"
+    verbose -log "exec make -C $build_dir CFLAGS=$includes"
+    set res [catch "exec make -C $build_dir CFLAGS=$includes" output]
+    verbose -log "$output"
+
+    # Check that the test progs were created
+    foreach f $test_progs {
+       if {![file exists $build_dir/$f]} {
+           verbose -log "Test program $f doesn't exist!"
+           return 0
+       }
+    }
+    return 1
+}
+
+proc cleanup_test_progs {} {
+    global build_dir
+    catch { exec kill -INT -[exp_pid] }
+    if {$build_dir != ""} {
+       catch { exec rm -rf $build_dir }
+    }
+}
This page took 0.072491 seconds and 5 git commands to generate.