【问题标题】:gdb: howto list open filesgdb:如何列出打开的文件
【发布时间】:2010-02-09 18:28:36
【问题描述】:

我想知道是否有可能从 GDB 本身获取被调试的应用程序已打开但未关闭的文件/目录列表?

目前我设置了一个断点,然后我使用像 lsof 这样的外部程序来检查打开的文件。

但是这种做法真的很烦人。

环境:Debian-Lenny 与 gdb v6.8

编辑:我问是因为我的应用程序在某些情况下会泄漏文件句柄

【问题讨论】:

    标签: gdb


    【解决方案1】:

    如果您的系统上没有lsof(我遇到过这样的问题),您可以使用gdb info os files。它打印有关所有进程的打开文件的信息。

    【讨论】:

    • 这是在 GDB 中作为单个命令实现此目的最直接的方法,无需编写脚本!
    • 实际答案,谢谢!其他一切都只是掉入 shell 并从 /proc 中提取相同的信息。
    【解决方案2】:

    在 Linux 上,您也可以只查看 /proc/<pid>/fd。从 GDB 执行此操作(例如,如果您想将其附加到断点)非常简单。当然,你也可以只使用 lsof。

    (gdb) info proc
    process 5262
    cmdline = '/bin/ls'
    cwd = '/afs/acm.uiuc.edu/user/njriley'
    exe = '/bin/ls'
    (gdb) shell ls -l /proc/5262/fd
    total 0
    lrwx------ 1 njriley users 64 Feb  9 12:45 0 -> /dev/pts/14
    lrwx------ 1 njriley users 64 Feb  9 12:45 1 -> /dev/pts/14
    lrwx------ 1 njriley users 64 Feb  9 12:45 2 -> /dev/pts/14
    lr-x------ 1 njriley users 64 Feb  9 12:45 3 -> pipe:[62083274]
    l-wx------ 1 njriley users 64 Feb  9 12:45 4 -> pipe:[62083274]
    lr-x------ 1 njriley users 64 Feb  9 12:45 5 -> /bin/ls
    (gdb) shell lsof -p 5262
    COMMAND  PID    USER   FD   TYPE DEVICE    SIZE     NODE NAME
    ls      5262 njriley  cwd    DIR   0,18   14336   262358 /afs/acm.uiuc.edu/user/njriley
    ls      5262 njriley  rtd    DIR    8,5    4096        2 /
    ls      5262 njriley  txt    REG    8,5   92312     8255 /bin/ls
    ls      5262 njriley  mem    REG    8,5   14744   441594 /lib/libattr.so.1.1.0
    ls      5262 njriley  mem    REG    8,5    9680   450321 /lib/i686/cmov/libdl-2.7.so
    ls      5262 njriley  mem    REG    8,5  116414   450307 /lib/i686/cmov/libpthread-2.7.so
    ls      5262 njriley  mem    REG    8,5 1413540   450331 /lib/i686/cmov/libc-2.7.so
    ls      5262 njriley  mem    REG    8,5   24800   441511 /lib/libacl.so.1.1.0
    ls      5262 njriley  mem    REG    8,5   95964   441580 /lib/libselinux.so.1
    ls      5262 njriley  mem    REG    8,5   30624   450337 /lib/i686/cmov/librt-2.7.so
    ls      5262 njriley  mem    REG    8,5  113248   441966 /lib/ld-2.7.so
    ls      5262 njriley    0u   CHR 136,14               16 /dev/pts/14
    ls      5262 njriley    1u   CHR 136,14               16 /dev/pts/14
    ls      5262 njriley    2u   CHR 136,14               16 /dev/pts/14
    ls      5262 njriley    3r  FIFO    0,6         62083274 pipe
    ls      5262 njriley    4w  FIFO    0,6         62083274 pipe
    ls      5262 njriley    5r   REG    8,5   92312     8255 /bin/ls
    

    【讨论】:

    • 有没有办法实现自动化?
    • 您可以将断点命令列表 (sourceware.org/gdb/current/onlinedocs/gdb/Break-Commands.html) 附加到任何断点,从而在断点上运行 lsof。如果您需要跟踪 fds 的打开位置,您还可以尝试 valgrind 的 --track-fds 选项。
    • rr 下不起作用,因为正在重放的进程有点“沙盒”并且在/proc/ 下实际上没有文件。所以gdb会抱怨“警告:无法打开/proc文件'/proc/400176/cmdline”。
    【解决方案3】:

    在 Nicholas 的帮助下,我能够通过定义宏来完全自动化任务。

    .gdbinit:

    define lsof
      shell rm -f pidfile
      set logging file pidfile
      set logging on
      info proc
      set logging off
      shell lsof -p `cat pidfile | perl -n -e 'print $1 if /process (.+)/'`
    end
    
    document lsof
      List open files
    end
    

    这是一个使用新宏的会话(程序在 /tmp 目录中打开一个文件):

    file hello    
    break main
    run
    next
    lsof
    

    输出:

    ...
    hello   2683  voku    5r   REG    8,1    37357 11110 /home/voku/hello
    hello   2683  voku    6w   REG    8,1        0  3358 /tmp/testfile.txt
    ...
    

    【讨论】:

    • 无法在目标遥控器上工作:Undefined info command: "proc". Try "help info". :-(.
    【解决方案4】:

    不,但您可以运行 lsof 并过滤到被调试的进程。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2016-06-04
      • 2020-10-17
      • 2019-09-18
      • 2021-12-16
      • 2013-04-21
      • 2023-04-10
      • 2015-04-02
      • 1970-01-01
      相关资源
      最近更新 更多