Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

script: Add report-open-files.py #286

Open
wants to merge 1 commit into
base: master
Choose a base branch
from

Conversation

honggyukim
Copy link
Collaborator

@honggyukim honggyukim commented Dec 12, 2017

This patch adds report-open-files.py that collects all the open files
based on open() calls and shows its summary at the end of execution.

The output of this script is as follows:

  $ uftrace record -S scripts/report-open-files.py /usr/bin/gcc ~/hello.c
    # 160 files are opened by 'cc1' (pid: 31754)

           open mode    pathname
    =================  ================================================
            O_NOCTTY    /usr/lib/gcc/x86_64-linux-gnu/5/include-fixed/bits/types.h
            O_NOCTTY    /usr/lib/gcc/x86_64-linux-gnu/5/include-fixed/stdlib.h
            O_NOCTTY    /usr/include/x86_64-linux-gnu/bits/waitstatus.h
            O_NOCTTY    /usr/local/include/bits/types.h
            O_NOCTTY    /usr/lib/gcc/x86_64-linux-gnu/5/include/bits/stdio_lim.h
            O_NOCTTY    /usr/lib/gcc/x86_64-linux-gnu/5/include/libio.h
            O_NOCTTY    /usr/include/x86_64-linux-gnu/sys/mman.h
               ...        ...

  # 0 files are opened by 'as' (pid: 31755)

  # 11 files are opened by 'ld' (pid: 31757)

         open mode    pathname
  =================  ================================================
          O_RDONLY    /usr/lib/gcc/x86_64-linux-gnu/5/../../../x86_64-linux-gnu/crti.o
          O_RDONLY    /usr/lib/gcc/x86_64-linux-gnu/5/crtbegin.o
          O_RDONLY    /lib/x86_64-linux-gnu/ld-linux-x86-64.so.2
          O_RDONLY    /usr/lib/gcc/x86_64-linux-gnu/5/../../../x86_64-linux-gnu/crt1.o
          O_RDONLY    /usr/lib/gcc/x86_64-linux-gnu/5/libgcc_s.so
          O_RDONLY    /usr/lib/x86_64-linux-gnu/libc_nonshared.a
          O_RDONLY    /lib/x86_64-linux-gnu/libc.so.6
          O_RDONLY    /usr/lib/gcc/x86_64-linux-gnu/5/../../../x86_64-linux-gnu/libc.so
          O_RDONLY    /tmp/ccQpg4sP.o
          O_RDONLY    /usr/lib/gcc/x86_64-linux-gnu/5/../../../x86_64-linux-gnu/crtn.o
          O_RDONLY    /usr/lib/gcc/x86_64-linux-gnu/5/crtend.o
             ...        ...

  # 2 files are opened by 'collect2' (pid: 31756)

                 open mode    pathname
  =========================  ================================================
  O_CREAT|O_WRONLY|O_TRUNC    /tmp/ccGNm49Q.le
  O_CREAT|O_WRONLY|O_TRUNC    /tmp/ccwGj2HX.ld

  # 0 files are opened by 'gcc' (pid: 31743)

Signed-off-by: Honggyu Kim [email protected]

@honggyukim honggyukim force-pushed the script/report-open-files branch 3 times, most recently from ebc159a to f676cdc Compare December 12, 2017 06:50
@namhyung
Copy link
Owner

Hmm.. I don't get what is the purpose of this script. Is it just for an example? Current output doesn't seem to have much difference than the plain replay with -F open.

@honggyukim honggyukim force-pushed the script/report-open-files branch from f676cdc to 7fa4ab2 Compare December 14, 2017 16:19
@honggyukim
Copy link
Collaborator Author

I think it can better handle enum types rather than manually writing options for -F open.

$ uftrace record --nest-libcall -T open@filter,arg1/s,arg2/e:uft_open_flag,retval -- /usr/bin/gcc hello.c

Especially arg2/e:uft_open_flag is not for general users.

@namhyung
Copy link
Owner

You can use -A open for auto-args.

@namhyung
Copy link
Owner

namhyung commented Jan 4, 2018

You need to reconsider open mode flag processing. IIRC the last 2 bits is used to mask the read-write mode and 0 is used for "read-only". It has a problem when used with other flags like O_NOCTTY - in fact, the right flag is O_NOCTTY|O_RDONLY.

@namhyung
Copy link
Owner

Something like this ?

diff --git a/scripts/report-open-files.py b/scripts/report-open-files.py
index c188c96a..ccdd3db7 100644
--- a/scripts/report-open-files.py
+++ b/scripts/report-open-files.py
@@ -9,10 +9,10 @@ import os
 
 UFTRACE_FUNC = [ "open" ]
 
+UFT_OPEN_MODE_MASK = 0x3
+uft_open_mode = [ "O_RDONLY", "O_WRONLY", "O_RDWR", "O_XXX" ]
+
 uft_open_flag = {
-        "O_RDONLY": 00,
-        "O_WRONLY": 01,
-        "O_RDWR": 02,
         "O_CREAT": 0100,
         "O_EXCL": 0200,
         "O_NOCTTY": 0400,
@@ -77,11 +77,10 @@ def uftrace_end():
     print("")
 
 def get_mode_str(mode):
-    mode_str = ""
+    mode_str = uft_open_mode[mode & UFT_OPEN_MODE_MASK]
+
     for key, value in uft_open_flag.items():
-        if mode == 0:
-            mode_str = "O_RDONLY"
-        elif mode & uft_open_flag[key] > 0:
+        if mode & uft_open_flag[key] > 0:
             if mode_str == "":
                 mode_str = key
             else:

@honggyukim honggyukim force-pushed the script/report-open-files branch from 7fa4ab2 to c6a709d Compare September 13, 2018 06:45
@honggyukim
Copy link
Collaborator Author

Thanks for the fix. I've updated including the change.

@honggyukim
Copy link
Collaborator Author

It seems that adding fopen can be better for this. It misses many opened files.

@namhyung
Copy link
Owner

Or you can use --nest-libcall. Hmm.. maybe openat() was used instead.

@honggyukim
Copy link
Collaborator Author

--nest-libcall is already in uftrace-option.

# uftrace-option: --nest-libcall -T open@filter,arg1/s,arg2/e:uft_open_flag,retval

@honggyukim honggyukim force-pushed the script/report-open-files branch from c6a709d to 8f3bf55 Compare September 13, 2018 08:10
@honggyukim
Copy link
Collaborator Author

Updated with handling openat and fopen as well as open.

@honggyukim
Copy link
Collaborator Author

An example output is as follows:

  $ uftrace record -S scripts/report-open-files.py /usr/bin/gcc -save-temps ~/hello.c
    # 161 files are opened by 'cc1' (pid: 176695)

            open mode    pathname
    ==================  ================================================
    O_RDONLY|O_NOCTTY    /usr/lib/gcc/x86_64-linux-gnu/5/include-fixed/bits/types.h
    O_RDONLY|O_NOCTTY    /usr/lib/gcc/x86_64-linux-gnu/5/include-fixed/stdlib.h
    O_RDONLY|O_NOCTTY    /usr/include/x86_64-linux-gnu/bits/waitstatus.h
    O_RDONLY|O_NOCTTY    /usr/local/include/bits/types.h
               ...        ...
                    w    hello.i

    # 3 files are opened by 'cc1' (pid: 176696)

            open mode    pathname
    ==================  ================================================
             O_RDONLY    /dev/urandom
    O_RDONLY|O_NOCTTY    hello.i
                    w    hello.s

    # 1 files are opened by 'as' (pid: 176697)

           open mode    pathname
    =================  ================================================
                   r    hello.s

    # 12 files are opened by 'ld' (pid: 176699)

           open mode    pathname
    =================  ================================================
            O_RDONLY    /usr/lib/gcc/x86_64-linux-gnu/5/../../../x86_64-linux-gnu/crti.o
            O_RDONLY    /usr/lib/gcc/x86_64-linux-gnu/5/crtbegin.o
            O_RDONLY    /lib/x86_64-linux-gnu/ld-linux-x86-64.so.2
            O_RDONLY    /usr/lib/gcc/x86_64-linux-gnu/5/../../../x86_64-linux-gnu/crt1.o
            O_RDONLY    /usr/lib/gcc/x86_64-linux-gnu/5/libgcc_s.so
            O_RDONLY    /usr/lib/x86_64-linux-gnu/libc_nonshared.a
            O_RDONLY    /lib/x86_64-linux-gnu/libc.so.6
            O_RDONLY    /usr/lib/gcc/x86_64-linux-gnu/5/../../../x86_64-linux-gnu/libc.so
            O_RDONLY    hello.o
            O_RDONLY    /usr/lib/gcc/x86_64-linux-gnu/5/../../../x86_64-linux-gnu/crtn.o
            O_RDONLY    /usr/lib/gcc/x86_64-linux-gnu/5/crtend.o
                   r    /usr/lib/gcc/x86_64-linux-gnu/5/../../../x86_64-linux-gnu/libc.so

    # 4 files are opened by 'collect2' (pid: 176698)

                   open mode    pathname
    =========================  ================================================
    O_WRONLY|O_TRUNC|O_CREAT    /tmp/ccVDJ3He.le
    O_WRONLY|O_TRUNC|O_CREAT    /tmp/cciG4DMx.ld
                           r    /tmp/cciG4DMx.ld
                           r    /tmp/ccVDJ3He.le

    # 0 files are opened by 'gcc' (pid: 176684)

@honggyukim honggyukim force-pushed the script/report-open-files branch from 8f3bf55 to a44a07f Compare September 13, 2018 08:33
@honggyukim
Copy link
Collaborator Author

Hmm.. I tried to remove some functions that returned -1 because there's no such file, but python return value is a bit tricky.

def uftrace_exit(ctx):
    global open_pathname
    if ctx.has_key("retval"):
    #if "retval" in ctx:
        if ctx["name"] == "open":
            #if ctx["retval"] == -1:
            if ctx["retval"] == 18446744073709551615:
                del open_set[open_pathname]
        elif ctx["name"] == "openat":
            #if ctx["retval"] == -1:
            if ctx["retval"] == 18446744073709551615:
                del openat_set[open_pathname]
        elif ctx["name"] == "fopen":
            if ctx["retval"] == 0:
                del fopen_set[open_pathname]

-1 is actually passed as 18446744073709551615 so comparison have to be changed as above. The result is same even if I changed the return type as retval/i.

@honggyukim
Copy link
Collaborator Author

After removing failed open files, the number of open files are reduced a lot from 161 to 41.

  # 41 files are opened by 'cc1' (pid: 178306)

          open mode    pathname
  ==================  ================================================
  O_RDONLY|O_NOCTTY    /usr/include/x86_64-linux-gnu/bits/stdio_lim.h
  O_RDONLY|O_NOCTTY    /usr/include/x86_64-linux-gnu/sys/select.h
  O_RDONLY|O_NOCTTY    /usr/include/x86_64-linux-gnu/bits/endian.h
  O_RDONLY|O_NOCTTY    /usr/include/x86_64-linux-gnu/bits/select.h
  O_RDONLY|O_NOCTTY    /usr/include/libio.h
  O_RDONLY|O_NOCTTY    /usr/include/xlocale.h
  O_RDONLY|O_NOCTTY    /usr/include/x86_64-linux-gnu/gnu/stubs-64.h
  O_RDONLY|O_NOCTTY    /usr/include/x86_64-linux-gnu/bits/sys_errlist.h
  O_RDONLY|O_NOCTTY    /usr/include/x86_64-linux-gnu/bits/wordsize.h
  O_RDONLY|O_NOCTTY    /usr/include/x86_64-linux-gnu/sys/mman.h
  O_RDONLY|O_NOCTTY    /usr/include/_G_config.h
  O_RDONLY|O_NOCTTY    /usr/include/stdc-predef.h
  O_RDONLY|O_NOCTTY    /usr/include/x86_64-linux-gnu/bits/waitstatus.h
  O_RDONLY|O_NOCTTY    /usr/include/wchar.h
  O_RDONLY|O_NOCTTY    /usr/lib/gcc/x86_64-linux-gnu/5/include/stddef.h
  O_RDONLY|O_NOCTTY    /usr/include/x86_64-linux-gnu/bits/typesizes.h
  O_RDONLY|O_NOCTTY    /usr/include/x86_64-linux-gnu/bits/types.h
  O_RDONLY|O_NOCTTY    /usr/include/x86_64-linux-gnu/bits/time.h
  O_RDONLY|O_NOCTTY    /usr/include/x86_64-linux-gnu/bits/mman-linux.h
  O_RDONLY|O_NOCTTY    /usr/include/x86_64-linux-gnu/bits/byteswap.h
  O_RDONLY|O_NOCTTY    /usr/include/x86_64-linux-gnu/sys/types.h
  O_RDONLY|O_NOCTTY    /usr/include/string.h
  O_RDONLY|O_NOCTTY    /usr/include/x86_64-linux-gnu/bits/waitflags.h
  O_RDONLY|O_NOCTTY    /usr/include/x86_64-linux-gnu/bits/stdlib-float.h
  O_RDONLY|O_NOCTTY    /usr/include/x86_64-linux-gnu/sys/sysmacros.h
  O_RDONLY|O_NOCTTY    /usr/include/features.h
  O_RDONLY|O_NOCTTY    /home/honggyu/hello.c
  O_RDONLY|O_NOCTTY    /usr/include/x86_64-linux-gnu/bits/pthreadtypes.h
  O_RDONLY|O_NOCTTY    /usr/include/x86_64-linux-gnu/sys/cdefs.h
  O_RDONLY|O_NOCTTY    /usr/include/x86_64-linux-gnu/bits/byteswap-16.h
           O_RDONLY    /dev/urandom
  O_RDONLY|O_NOCTTY    /usr/include/time.h
  O_RDONLY|O_NOCTTY    /usr/include/alloca.h
  O_RDONLY|O_NOCTTY    /usr/lib/gcc/x86_64-linux-gnu/5/include/stdarg.h
  O_RDONLY|O_NOCTTY    /usr/include/x86_64-linux-gnu/bits/sigset.h
  O_RDONLY|O_NOCTTY    /usr/include/endian.h
  O_RDONLY|O_NOCTTY    /usr/include/x86_64-linux-gnu/gnu/stubs.h
  O_RDONLY|O_NOCTTY    /usr/include/x86_64-linux-gnu/bits/mman.h
  O_RDONLY|O_NOCTTY    /usr/include/stdlib.h
  O_RDONLY|O_NOCTTY    /usr/include/stdio.h
                  w    hello.i

@honggyukim honggyukim force-pushed the script/report-open-files branch 3 times, most recently from 59c4b02 to bbeaede Compare September 13, 2018 08:42
@namhyung
Copy link
Owner

The manual (man fopen) says following conversion - but I cannot find it on the internet:

fopen() mode open() flags
"r" O_RDONLY
"w" O_WRONLY | O_CREAT | O_TRUNC
"a" O_WRONLY | O_CREAT | O_APPEND
"r+" O_RDWR
"w+" O_RDWR | O_CREAT | O_TRUNC
"a+" O_RDWR | O_CREAT | O_APPEND

Also glibc added following extensions:

fopen() mode open() flags
"e" O_CLOEXEC
"x" O_EXCL

@honggyukim
Copy link
Collaborator Author

Thanks for the useful info, but I just wanted to leave fopen mode as is to distinguish them.
Do you think it's better to convert them into the mode format in open call? If so, I will update it again. Thanks!

@honggyukim
Copy link
Collaborator Author

Hmm.. it can be combination with other characters in fopen mode such as b for binary, but I'm not sure if there's a way to represent b in open mode. I think we better leave it as is to give clear idea to users.

fopen_map = {}
open_pathname = ""

def uftrace_begin():
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

One small nitpicking.. please add a 'ctx' argument

if ctx.has_key("retval"):
if ctx["name"] == "open":
#if ctx["retval"] == -1:
if ctx["retval"] == 18446744073709551615:
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is because python deals with big numbers more than 64 bit. It's hex: 0xffffffffffffffff. I don't know what's the best way to handle this.

Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

how about this?

minus_one = (1 << 64) - 1
...

   if ctx["retval"] == minus_one:

This patch adds report-open-files.py that collects all the open files
based on open, openat, and fopen calls and shows its summary at the end
of execution.

An example output of this script is as follows:

  $ uftrace record -S scripts/report-open-files.py /usr/bin/gcc -save-temps ~/hello.c
    # 161 files are opened by 'cc1' (pid: 176695)

            open mode    pathname
    ==================  ================================================
    O_RDONLY|O_NOCTTY    /usr/lib/gcc/x86_64-linux-gnu/5/include-fixed/bits/types.h
    O_RDONLY|O_NOCTTY    /usr/lib/gcc/x86_64-linux-gnu/5/include-fixed/stdlib.h
    O_RDONLY|O_NOCTTY    /usr/include/x86_64-linux-gnu/bits/waitstatus.h
    O_RDONLY|O_NOCTTY    /usr/local/include/bits/types.h
               ...        ...
                    w    hello.i

    # 3 files are opened by 'cc1' (pid: 176696)

            open mode    pathname
    ==================  ================================================
             O_RDONLY    /dev/urandom
    O_RDONLY|O_NOCTTY    hello.i
                    w    hello.s

    # 1 files are opened by 'as' (pid: 176697)

           open mode    pathname
    =================  ================================================
                   r    hello.s

    # 12 files are opened by 'ld' (pid: 176699)

           open mode    pathname
    =================  ================================================
            O_RDONLY    /usr/lib/gcc/x86_64-linux-gnu/5/../../../x86_64-linux-gnu/crti.o
            O_RDONLY    /usr/lib/gcc/x86_64-linux-gnu/5/crtbegin.o
            O_RDONLY    /lib/x86_64-linux-gnu/ld-linux-x86-64.so.2
            O_RDONLY    /usr/lib/gcc/x86_64-linux-gnu/5/../../../x86_64-linux-gnu/crt1.o
            O_RDONLY    /usr/lib/gcc/x86_64-linux-gnu/5/libgcc_s.so
            O_RDONLY    /usr/lib/x86_64-linux-gnu/libc_nonshared.a
            O_RDONLY    /lib/x86_64-linux-gnu/libc.so.6
            O_RDONLY    /usr/lib/gcc/x86_64-linux-gnu/5/../../../x86_64-linux-gnu/libc.so
            O_RDONLY    hello.o
            O_RDONLY    /usr/lib/gcc/x86_64-linux-gnu/5/../../../x86_64-linux-gnu/crtn.o
            O_RDONLY    /usr/lib/gcc/x86_64-linux-gnu/5/crtend.o
                   r    /usr/lib/gcc/x86_64-linux-gnu/5/../../../x86_64-linux-gnu/libc.so

    # 4 files are opened by 'collect2' (pid: 176698)

                   open mode    pathname
    =========================  ================================================
    O_WRONLY|O_TRUNC|O_CREAT    /tmp/ccVDJ3He.le
    O_WRONLY|O_TRUNC|O_CREAT    /tmp/cciG4DMx.ld
                           r    /tmp/cciG4DMx.ld
                           r    /tmp/ccVDJ3He.le

    # 0 files are opened by 'gcc' (pid: 176684)

Signed-off-by: Honggyu Kim <[email protected]>
@honggyukim honggyukim force-pushed the script/report-open-files branch from bbeaede to 6d31a62 Compare April 23, 2023 13:58
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants