This is the mail archive of the systemtap@sourceware.org mailing list for the systemtap project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[patch] Close fds before execute a cmd


Hi, all

	case 1:
stap -c 'sleep 100' -e 'probe begin{}'
# killing SIGUSR1 to "sleep 100" does not work as expected

	case 2:
trap "" SIGSEGV # set SIGSEGV's handler as SIG_IGN
stap -c 'sleep 100' -e 'probe begin{}'
# killing SIGSEGV still works.

	The bug reasons of case1 and case2 are same: the signal
handlers are not restored before exec().
	It's not a serious bug, but it's not friendly to users.
This bug can be fixed by the patch below(Restore signals except
SIGINT).
	There is also another good way: unblock all signals and
set signals' handlers as SIG_DFL **EXPLICITLY** before exec().

Signed-off-by: Lai Jiangshan <laijs@cn.fujitsu.com>

diff -Nur src/runtime/staprun/common.c src.new/runtime/staprun/common.c
--- src/runtime/staprun/common.c	2007-08-20 23:02:47.000000000 +0900
+++ src.new/runtime/staprun/common.c	2007-10-12 09:05:21.000000000 +0900
@@ -251,6 +251,12 @@
		_exit(1);
}

+#ifdef SINGLE_THREADED
+#define sig_mask sigprocmask
+#else
+#define sig_mask pthread_sigmask
+#endif
+
void setup_signals(void)
{
	sigset_t s;
@@ -258,11 +264,7 @@

	/* blocking all signals while we set things up */
	sigfillset(&s);
-#ifdef SINGLE_THREADED
-	sigprocmask(SIG_SETMASK, &s, NULL);
-#else
-	pthread_sigmask(SIG_SETMASK, &s, NULL);
-#endif
+	sig_mask(SIG_SETMASK, &s, NULL);
	/* set some of them to be ignored */
	memset(&a, 0, sizeof(a));
	sigfillset(&a.sa_mask);
@@ -282,13 +284,41 @@
	/* unblock all signals */
	sigemptyset(&s);

-#ifdef SINGLE_THREADED
- sigprocmask(SIG_SETMASK, &s, NULL);
-#else
- pthread_sigmask(SIG_SETMASK, &s, NULL);
-#endif
+ sig_mask(SIG_SETMASK, &s, NULL);
+}
+
+static sigset_t saved_sigmask;
+static int saved_sig[] = {SIGTERM, SIGHUP, SIGQUIT,
+ SIGCHLD, SIGUSR1, SIGUSR2, SIGPIPE, SIGBUS,
+ SIGFPE, SIGILL, SIGSEGV, SIGXCPU, SIGXFSZ};
+static struct sigaction saved_sa[sizeof(saved_sig) / sizeof(saved_sig[0])]; +
+int save_signals(void)
+{
+ if(sig_mask(SIG_SETMASK, NULL, &saved_sigmask))
+ return -1;
+ int i = sizeof(saved_sig) / sizeof(saved_sig[0]);
+ while (i--) {
+ if (sigaction(saved_sig[i], NULL, &saved_sa[i]))
+ return -1;
+ }
+ return 0;
}


+int restore_signals(void)
+{
+	if(sig_mask(SIG_SETMASK, &saved_sigmask, NULL))
+		return -1;
+	int i = sizeof(saved_sig) / sizeof(saved_sig[0]);
+	while (i--) {
+		if (sigaction(saved_sig[i], &saved_sa[i], NULL))
+			return -1;
+	}
+	return 0;
+}
+
+#undef sig_mask
+
/**
 *	send_request - send request to kernel over control channel
 *	@type: the relay-app command id
diff -Nur src/runtime/staprun/mainloop.c src.new/runtime/staprun/mainloop.c
--- src/runtime/staprun/mainloop.c	2007-09-15 01:11:12.000000000 +0900
+++ src.new/runtime/staprun/mainloop.c	2007-10-10 16:04:40.000000000 +0900
@@ -90,6 +90,7 @@
		
		/* wait here until signaled */
		sigwait(&usrset, &signum);
+		restore_signals();

		if (execl("/bin/sh", "sh", "-c", target_cmd, NULL) < 0)
			perror(target_cmd);
@@ -112,6 +113,7 @@
		_perr("fork");
	} else if (pid == 0) {
		setpriority (PRIO_PROCESS, 0, 0);
+		restore_signals();
		if (execl("/bin/sh", "sh", "-c", cmd, NULL) < 0)
			perr("%s", cmd);
		_exit(1);
diff -Nur src/runtime/staprun/stapio.c src.new/runtime/staprun/stapio.c
--- src/runtime/staprun/stapio.c	2007-08-15 00:23:59.000000000 +0900
+++ src.new/runtime/staprun/stapio.c	2007-10-10 16:03:28.000000000 +0900
@@ -26,6 +26,7 @@

int main(int argc, char **argv)
{
+	save_signals();
	setup_signals();
	
	parse_args(argc, argv);
diff -Nur src/runtime/staprun/staprun.c src.new/runtime/staprun/staprun.c
--- src/runtime/staprun/staprun.c	2007-08-16 02:37:21.000000000 +0900
+++ src.new/runtime/staprun/staprun.c	2007-10-10 16:05:17.000000000 +0900
@@ -55,6 +55,8 @@
			}
		}

+		restore_signals();
+
		/* Actually run the command. */
		if (execv(path, argv) < 0)
			perror(path);
@@ -149,6 +151,7 @@
{
	int rc;

+	save_signals();
	if (atexit(exit_cleanup)) {
		_perr("cannot set exit function");
		exit(1);
diff -Nur src/runtime/staprun/staprun.h src.new/runtime/staprun/staprun.h
--- src/runtime/staprun/staprun.h	2007-08-15 00:23:59.000000000 +0900
+++ src.new/runtime/staprun/staprun.h	2007-10-10 16:00:38.000000000 +0900
@@ -151,6 +151,8 @@
void usage(char *prog);
void parse_modpath(const char *);
void setup_signals(void);
+int save_signals(void);
+int restore_signals(void);

/*
* variables



Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]