<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>