Как закрыть дескриптор файла с помощью команды оболочки Linux - PullRequest
13 голосов
/ 13 мая 2011

В /proc/pid/fd/ слишком много дескрипторов файлов. Могу ли я использовать команду оболочки, чтобы закрыть эти файловые дескрипторы?

Ответы [ 5 ]

32 голосов
/ 21 августа 2012

Вы можете определенно закрыть файлы других запущенных процессов, если у вас есть для этого разрешения.

Сначала найдите PID.

Затем запустите GDB и присоедините к процессу:

gdb -p 1598

Затем вызовите системный вызов close для fd, который вы хотите закрыть:

(gdb) call close(999)
$1 = 0

Если дескриптор файла был утечкой, то программа никогда не будет пытаться использовать его снова, и это не должно вызывать каких-либо проблем. Однако в программе, скорее всего, есть ошибка.

5 голосов
/ 13 мая 2011

Вы можете закрыть FD n текущего процесса в bash следующим образом:

exec n<&-
2 голосов
/ 23 февраля 2016

Я работал в аналогичной ситуации, но там, где gdb не было выбора, поскольку это нарушило ограничения моего приложения в реальном времени и исказило мой тест.

Итак, я придумал быстрое правило iptables. Необязательные аргументы, заключенные в квадратные скобки ([ opt ]) .

  1. Найти адрес и порт назначения :

    netstat --program [ --numeric-host --numeric-ports ] | grep [<pid>]/[<appname>]

    $ netstat --program --numeric-ports | grep 8812/
    tcp        0      0 ysc.xxx:54055          10.56.1.152:30000           ESTABLISHED 8812/my-application
    tcp        0      0 ysc.xxx:46786          postgres.xxx:5432           ESTABLISHED 8812/my-application
    tcp        0      0 ysc.xxx:36090          10.56.4.79:57000            ESTABLISHED 8812/my-application
                                          ...
    unix  2      [ ]         DGRAM                    7177020 8812/my-application
    

    Здесь я бы хотел сократить 10.56.4.79:57000.

  2. Создайте правило iptables для вырезания сокета :

    iptables -A OUTPUT [ --out-interface <if> --protocol <tcp|udp|unix> ] --destination <addr> --dport <port> --jump DROP

    $ iptables -A OUTPUT --destination 10.56.4.79 --dport 57000 --jump DROP
    $
    
  3. На этом этапе ваша программа не может отправлять пакеты на удаленный хост. В большинстве случаев TCP-соединение закрывается . Вы можете продолжить свои тесты, если они есть.

    $ netstat --program --numeric-ports | grep 8812/
    tcp        0      0 ysc.xxx:54055          10.56.1.152:30000           ESTABLISHED 8812/my-application
    tcp        0      0 ysc.xxx:46786          postgres.xxx:5432           ESTABLISHED 8812/my-application
                                          ...
    unix  2      [ ]         DGRAM                    7177020 8812/my-application
    
  4. Удалить правило iptables :

    Вы просто вводите то же правило iptables, заменяя A на D.

    $ iptables -D OUTPUT --destination 10.56.4.79 --dport 57000 --jump DROP
    $
    
0 голосов
/ 15 ноября 2018

@ Томас ответ действителен только при установленной отладочной информации для close() вызова.

Без отладочной информации, gdb отказывается звонить close():

(gdb) call close(3)
'close' has unknown return type; cast the call to its declared return type

Самый простой способ сделать GDB-вызов close() в этом случае - привести вызов к close() типу возврата:

(gdb) call (int)close(3)
$1 = 0

См. Документацию GDB :

Иногда в функции, которую вы хотите вызвать, отсутствует отладочная информация. В таком случае GDB не знает тип функции, включая типы параметров функции. Чтобы не звать низшего функционировать неправильно, что может привести к вызываемой функции ошибочно функционирующий и даже терпящий крах, GDB отказывается называть функция, если вы не укажете ей тип функции.

Для прототипированных функций (то есть в стиле ANSI / ISO) существует два способа сделай это. Самое простое - это вызвать вызов функции, объявленной тип возврата.

0 голосов
/ 14 мая 2011

Нельзя просто закрывать дескрипторы файлов других процессов и ожидать, что они продолжат работать.

Исправлена ​​ошибка, из-за которой программа открывала слишком много файлов. Это может быть изменение конфигурации или изменение источника и т. Д. Вы не можете просто закрыть файлы для него.

...