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

Amin Khorsandi amin.khorsandi at gmail.com
Fri Aug 12 10:19:39 UTC 2016


On Tue, Aug 9, 2016 at 10:47 PM, Dmitry V. Levin <ldv at altlinux.org> wrote:

> On Wed, Aug 03, 2016 at 06:19:30PM +0200, Amin Khorsandi wrote:
> > ---
> >  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 */
>
> You are asking for trouble: QUAL_LIST == QUAL_READ|QUAL_WRITE
>
> >  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
>
> The longer I look at this extension, the more I inclined to add a new
> option.  For example, how would you like "-l trace" that lists all syscalls
> selected using traditional "-e trace=set" syntax?
>
> I could use a new separate flag for this but not that many alphabets are
available.

> >  .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;
>
> Here you rely on the linker that would hopefully place all identical
> strings at same addresses.  This is fragile.
>
> > +     }
> > +     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;
>
> Wouldn't this cause a stack overflow if
> nsyscall_vec[2] > 1 + MAX_NSYSCALLS/3 ?
>
> Try e.g. "strace -e list_syscalls=all" on x86_64.
>
> I tried this on x86_64 and power pc machines, got no error!


> > +     }
> > +
> > +     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]);
> > +     }
>
> The output should go to shared_log instead of stdout.
>
> Is shared_log available in syscalls.c? Or should I move the print function
to strace.c?

>
> --
> ldv
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.strace.io/pipermail/strace-devel/attachments/20160812/cbfb1580/attachment.html>


More information about the Strace-devel mailing list