[PATCH v3] Add possibility for the user to print system calls available in the platform.

Amin Khorsandi amin.khorsandi at gmail.com
Wed Aug 3 16:19:30 UTC 2016


---
 defs.h    |  1 +
 strace.1  |  7 +++++++
 syscall.c | 57 ++++++++++++++++++++++++++++++++++++++++++++++++++++++---
 3 files changed, 62 insertions(+), 3 deletions(-)

diff --git a/defs.h b/defs.h
index 4b7e8ed..a8e71c8 100644
--- a/defs.h
+++ b/defs.h
@@ -363,6 +363,7 @@ struct tcb {
 #define QUAL_SIGNAL	0x010	/* report events with this signal */
 #define QUAL_READ	0x020	/* dump data read on this file descriptor */
 #define QUAL_WRITE	0x040	/* dump data written to this file descriptor */
+#define QUAL_LIST	0x060   /* this system call should be listed */
 typedef uint8_t qualbits_t;
 
 #define DEFAULT_QUAL_FLAGS (QUAL_TRACE | QUAL_ABBREV | QUAL_VERBOSE)
diff --git a/strace.1 b/strace.1
index 6cc17c5..2c06bbd 100644
--- a/strace.1
+++ b/strace.1
@@ -481,6 +481,13 @@ Note that this is independent from the normal tracing of the
 system call which is controlled by the option
 .BR -e "\ " trace = write .
 .TP
+\fB\-e\ list_syscalls\fR=\,\fIset\fR
+List system calls available on the current platform in the specified set.
+For example,
+.BR -e "\ " list_syscalls = file
+lists all system calls related to the file operations available in the current
+platform.
+.TP
 .BI "\-I " interruptible
 When strace can be interrupted by signals (such as pressing ^C).
 1: no signals are blocked; 2: fatal signals are blocked while decoding syscall
diff --git a/syscall.c b/syscall.c
index 6af0dec..c083e7c 100644
--- a/syscall.c
+++ b/syscall.c
@@ -360,6 +360,7 @@ update_personality(struct tcb *tcp, unsigned int personality)
 #endif
 
 static int qual_syscall(), qual_signal(), qual_desc();
+static void print_syscalls(const char *list);
 
 static const struct qual_options {
 	unsigned int bitflag;
@@ -384,6 +385,8 @@ static const struct qual_options {
 	{ QUAL_WRITE,	"write",	qual_desc,	"descriptor"	},
 	{ QUAL_WRITE,	"writes",	qual_desc,	"descriptor"	},
 	{ QUAL_WRITE,	"w",		qual_desc,	"descriptor"	},
+	{ QUAL_LIST,	"list_syscalls",	qual_syscall,	"system call"	},
+	{ QUAL_LIST,	"l",	qual_syscall,	"system call"	},
 	{ 0,		NULL,		NULL,		NULL		},
 };
 
@@ -484,6 +487,42 @@ qual_desc(const char *s, const unsigned int bitflag, const int not)
 }
 
 static int
+value_already_in_list(const char *value, const char ** list, int size) 
+{
+	int i;
+	for (i=0; i < size; i++) {
+		if (list[i] == value)
+			return 1;
+	}
+	return 0;
+}
+
+static void
+print_syscalls(const char *set)
+{
+	unsigned int p, i;
+	const char *syscalls_list[MAX_NSYSCALLS] = {NULL};
+
+	for (p = 0; p < SUPPORTED_PERSONALITIES; p++) {
+		for (i = 0; i<nsyscall_vec[p]; i++)
+			if(((qual_vec[p][i] & QUAL_LIST) == QUAL_LIST) &&
+				(sysent_vec[p][i].sys_name != NULL))
+				if (!value_already_in_list(sysent_vec[p][i].sys_name,
+					syscalls_list, MAX_NSYSCALLS))
+					syscalls_list[p*i+i] = sysent_vec[p][i].sys_name;
+	}
+
+	fprintf(stdout, "System calls in %s (current platform):\n", set);
+	fprintf(stdout, "------------------------------------------------\n");
+
+	for (i=0; i < MAX_NSYSCALLS; i++){
+		if (syscalls_list[i] != NULL)
+			fprintf(stdout,  "%s\n", syscalls_list[i]);
+	}
+	exit(0);
+}
+
+static int
 lookup_class(const char *s)
 {
 	if (strcmp(s, "file") == 0)
@@ -537,7 +576,12 @@ qualify(const char *s)
 		for (i = 0; i < num_quals; i++) {
 			qualify_one(i, opt->bitflag, not, -1);
 		}
-		return;
+		if (strcmp(opt->option_name, "list_syscalls") == 0 ||
+			strcmp(opt->option_name, "l") == 0) {
+			print_syscalls(s);
+		} else {
+			return;
+		}
 	}
 	for (i = 0; i < num_quals; i++) {
 		qualify_one(i, opt->bitflag, !not, -1);
@@ -545,7 +589,8 @@ qualify(const char *s)
 	copy = xstrdup(s);
 	for (p = strtok(copy, ","); p; p = strtok(NULL, ",")) {
 		int n;
-		if (opt->bitflag == QUAL_TRACE && (n = lookup_class(p)) > 0) {
+		if ((opt->bitflag == QUAL_TRACE || opt->bitflag == QUAL_LIST)
+			 && (n = lookup_class(p)) > 0) {
 			unsigned pers;
 			for (pers = 0; pers < SUPPORTED_PERSONALITIES; pers++) {
 				for (i = 0; i < nsyscall_vec[pers]; i++)
@@ -556,9 +601,15 @@ qualify(const char *s)
 		}
 		if (opt->qualify(p, opt->bitflag, not)) {
 			error_msg_and_die("invalid %s '%s'",
-				opt->argument_name, p);
+				  opt->argument_name, p);
 		}
 	}
+
+	if (strcmp(opt->option_name, "list_syscalls") == 0 ||
+		strcmp(opt->option_name, "l") == 0) {
+		print_syscalls(s);
+	}
+
 	free(copy);
 	return;
 }
-- 
1.9.1





More information about the Strace-devel mailing list