[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