From: Amin Khorsandi <amin.khorsa...@infinera.com> --- defs.h | 1 + strace.1 | 7 +++++++ syscall.c | 56 +++++++++++++++++++++++++++++++++++++++++++++++++++++--- 3 files changed, 61 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..4b9343e 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,41 @@ 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 +575,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 +588,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 +600,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; } -- 2.4.10 ------------------------------------------------------------------------------ _______________________________________________ Strace-devel mailing list Strace-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/strace-devel