<div dir="ltr"><br><div class="gmail_extra"><br><div class="gmail_quote">On Tue, Aug 9, 2016 at 10:47 PM, Dmitry V. Levin <span dir="ltr"><<a href="mailto:ldv@altlinux.org" target="_blank">ldv@altlinux.org</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><span class="">On Wed, Aug 03, 2016 at 06:19:30PM +0200, Amin Khorsandi wrote:<br>
> ---<br>
>  defs.h    |  1 +<br>
>  strace.1  |  7 +++++++<br>
>  syscall.c | 57 ++++++++++++++++++++++++++++++<wbr>++++++++++++++++++++++++---<br>
>  3 files changed, 62 insertions(+), 3 deletions(-)<br>
><br>
> diff --git a/defs.h b/defs.h<br>
> index 4b7e8ed..a8e71c8 100644<br>
> --- a/defs.h<br>
> +++ b/defs.h<br>
> @@ -363,6 +363,7 @@ struct tcb {<br>
>  #define QUAL_SIGNAL  0x010   /* report events with this signal */<br>
>  #define QUAL_READ    0x020   /* dump data read on this file descriptor */<br>
>  #define QUAL_WRITE   0x040   /* dump data written to this file descriptor */<br>
> +#define QUAL_LIST    0x060   /* this system call should be listed */<br>
<br>
</span>You are asking for trouble: QUAL_LIST == QUAL_READ|QUAL_WRITE<br>
<span class=""><br>
>  typedef uint8_t qualbits_t;<br>
><br>
>  #define DEFAULT_QUAL_FLAGS (QUAL_TRACE | QUAL_ABBREV | QUAL_VERBOSE)<br>
> diff --git a/strace.1 b/strace.1<br>
> index 6cc17c5..2c06bbd 100644<br>
> --- a/strace.1<br>
> +++ b/strace.1<br>
> @@ -481,6 +481,13 @@ Note that this is independent from the normal tracing of the<br>
>  system call which is controlled by the option<br>
>  .BR -e "\ " trace = write .<br>
>  .TP<br>
> +\fB\-e\ list_syscalls\fR=\,\fIset\fR<br>
> +List system calls available on the current platform in the specified set.<br>
> +For example,<br>
> +.BR -e "\ " list_syscalls = file<br>
> +lists all system calls related to the file operations available in the current<br>
> +platform.<br>
> +.TP<br>
<br>
</span>The longer I look at this extension, the more I inclined to add a new<br>
option.  For example, how would you like "-l trace" that lists all syscalls<br>
selected using traditional "-e trace=set" syntax?<br>
<div><div class="h5"><br></div></div></blockquote><div>I could use a new separate flag for this but not that many alphabets are available. </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div><div class="h5">
>  .BI "\-I " interruptible<br>
>  When strace can be interrupted by signals (such as pressing ^C).<br>
>  1: no signals are blocked; 2: fatal signals are blocked while decoding syscall<br>
> diff --git a/syscall.c b/syscall.c<br>
> index 6af0dec..c083e7c 100644<br>
> --- a/syscall.c<br>
> +++ b/syscall.c<br>
> @@ -360,6 +360,7 @@ update_personality(struct tcb *tcp, unsigned int personality)<br>
>  #endif<br>
><br>
>  static int qual_syscall(), qual_signal(), qual_desc();<br>
> +static void print_syscalls(const char *list);<br>
><br>
>  static const struct qual_options {<br>
>       unsigned int bitflag;<br>
> @@ -384,6 +385,8 @@ static const struct qual_options {<br>
>       { QUAL_WRITE,   "write",        qual_desc,      "descriptor"    },<br>
>       { QUAL_WRITE,   "writes",       qual_desc,      "descriptor"    },<br>
>       { QUAL_WRITE,   "w",            qual_desc,      "descriptor"    },<br>
> +     { QUAL_LIST,    "list_syscalls",        qual_syscall,   "system call"   },<br>
> +     { QUAL_LIST,    "l",    qual_syscall,   "system call"   },<br>
>       { 0,            NULL,           NULL,           NULL            },<br>
>  };<br>
><br>
> @@ -484,6 +487,42 @@ qual_desc(const char *s, const unsigned int bitflag, const int not)<br>
>  }<br>
><br>
>  static int<br>
> +value_already_in_list(const char *value, const char ** list, int size)<br>
> +{<br>
> +     int i;<br>
> +     for (i=0; i < size; i++) {<br>
> +             if (list[i] == value)<br>
> +                     return 1;<br>
<br>
</div></div>Here you rely on the linker that would hopefully place all identical<br>
strings at same addresses.  This is fragile.<br>
<span class=""><br>
> +     }<br>
> +     return 0;<br>
> +}<br>
> +<br>
> +static void<br>
> +print_syscalls(const char *set)<br>
> +{<br>
> +     unsigned int p, i;<br>
> +     const char *syscalls_list[MAX_NSYSCALLS] = {NULL};<br>
> +<br>
> +     for (p = 0; p < SUPPORTED_PERSONALITIES; p++) {<br>
> +             for (i = 0; i<nsyscall_vec[p]; i++)<br>
> +                     if(((qual_vec[p][i] & QUAL_LIST) == QUAL_LIST) &&<br>
> +                             (sysent_vec[p][i].sys_name != NULL))<br>
> +                             if (!value_already_in_list(<wbr>sysent_vec[p][i].sys_name,<br>
> +                                     syscalls_list, MAX_NSYSCALLS))<br>
> +                                     syscalls_list[p*i+i] = sysent_vec[p][i].sys_name;<br>
<br>
</span>Wouldn't this cause a stack overflow if<br>
nsyscall_vec[2] > 1 + MAX_NSYSCALLS/3 ?<br>
<br>
Try e.g. "strace -e list_syscalls=all" on x86_64.<br>
<span class=""><br></span></blockquote><div>I tried this on x86_64 and power pc machines, got no error!</div><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><span class="">
> +     }<br>
> +<br>
> +     fprintf(stdout, "System calls in %s (current platform):\n", set);<br>
> +     fprintf(stdout, "-----------------------------<wbr>-------------------\n");<br>
> +<br>
> +     for (i=0; i < MAX_NSYSCALLS; i++){<br>
> +             if (syscalls_list[i] != NULL)<br>
> +                     fprintf(stdout,  "%s\n", syscalls_list[i]);<br>
> +     }<br>
<br>
</span>The output should go to shared_log instead of stdout.<br>
<span class="HOEnZb"><font color="#888888"><br></font></span></blockquote><div>Is shared_log available in syscalls.c? Or should I move the print function</div><div>to strace.c?  </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><span class="HOEnZb"><font color="#888888">
<br>
--<br>
ldv<br>
</font></span></blockquote></div><br></div></div>