более длинная строка для tr вызывает зависание и всплеск процессора

MacOS Yosemite (10.10.5). Я знаю, что это раздел Unix / Linux … но этот вопрос, вероятно, подходит лучше, чем в MacOS.

Мой терминал начал зависать при запуске, прежде чем показывать подсказку … и одновременное использование процессора. Я могу CTRL-C, а затем получить подсказку (предположительно выходящую из висячего / работающего .bashrc / .profile / etc).

Я быстро понял, что некоторые строки в моем .bashrc вызывают зависание. Это новое (т. Е. Я ничего не менял в своем .bashrc, и все было хорошо работает), поэтому что-то изменилось в системе.

Кажется, что некоторые более длинные строки приводят к всплеску зависания / процессора.

Я могу воспроизвести это, передав строку в tr -d '\n' и увидев, если она зависает.

 macattack:~ $ openssl rand -base64 93 | tr -d '\n' eDsz4JqFX/HAVjplNI6WDWwPRp9l9snp6UKp/pLn+GbBvJx0+ZMvSJFS/SuCwjMRRXVXfUvBdkaH1R0UgCr2UOf283MvHVTRusLFEVPcGCIz1t3sFMU/3foRzNWVmattp@macattack:~ $ openssl rand -base64 94 | tr -d '\n' ^C mattp@macattack:~ $ openssl rand -base64 94 | tr -du '\n' ^C 

Кажется, что 93 символа – это магическое число, где tr начинает зависать. openssl не висит (т. е. если я удаляю трубку до tr все выйдет). Однако моя оригинальная проблемная линия оказалась разной длины.

 mattp@macattack:~ $ echo 'echo -e "$TS\t${TERM_SESSION_ID}\t$(pwd)\t$(history 1 | cut -c 8-)\n" >> $HOME/.history/history-$(date "+%Y-%m-%d")-${USER}.log;' | tr -d '\n' ^C-bash: echo: write error: Interrupted system call mattp@macattack:~ $ echo 'echo -e "$TS\t${TERM_SESSION_ID}\t$(pwd)\t$(history 1 | cut -c 8-)\n" >> $HOME/.history/history-$(date "+%Y-%m-%d")-${USER}.log' | tr -d '\n' mattp@macattack:~ $ echo 'echo -e "$TS\t${TERM_SESSION_ID}\t$(pwd)\t$(history 1 | cut -c 8-)\n" >> $HOME/.history/history-$(date "+%Y-%m-%d")-${USER}.log' | wc -c 128 mattp@macattack:~ $ 

Вероятно, это проблема с трубкой, а не проблема tr . Я могу воспроизвести ту же проблему с sed (команда не имеет смысла … просто иллюстрирует зависание).

 mattp@macattack:~ $ echo 'echo -e "$TS\t${TERM_SESSION_ID}\t$(pwd)\t$(history 1 | cut -c 8-)\n" >> $HOME/.history/history-$(date "+%Y-%m-%d")-${USER}.log;' | sed 's/\n/ /g' ^C-bash: echo: write error: Interrupted system call mattp@macattack:~ $ echo 'echo -e "$TS\t${TERM_SESSION_ID}\t$(pwd)\t$(history 1 | cut -c 8-)\n" >> $HOME/.history/history-$(date "+%Y-%m-%d")-${USER}.log' | sed 's/\n/ /g' echo -e "$TS\t${TERM_SESSION_ID}\t$(pwd)\t$(history 1 | cut -c 8-)\n" >> $HOME/.history/history-$(date "+%Y-%m-%d")-${USER}.log mattp@macattack:~ 

У меня не хватало идей для устранения этой проблемы.
Команды подвески выполняются нормально на случайном сервере linux centos. До недавнего времени команды выполнялись отлично на macos. Раньше я никогда не сталкивался с трубкой. Я подумал, может быть, это были странные символы ввода, вызывающие проблему … но случайная строка openssl показывает иначе. Улимиты такие же, как на другом маке, у которого нет этой же проблемы.

 mattp@macattack:~ $ ulimit -a core file size (blocks, -c) 0 data seg size (kbytes, -d) unlimited file size (blocks, -f) unlimited max locked memory (kbytes, -l) unlimited max memory size (kbytes, -m) unlimited open files (-n) 7168 pipe size (512 bytes, -p) 1 stack size (kbytes, -s) 8192 cpu time (seconds, -t) unlimited max user processes (-u) 709 virtual memory (kbytes, -v) unlimited 

Используя dtruss on tr похоже, он зависает на вызове read_nocancel.

Обновить

Продвигается. Нашел комментарий о размерах висячих и трубных буферов. Снял тестовый скрипт отсюда: насколько большой буфер для буфера?

Запуск, пока происходит проблема, показывает буфер буфера 128 байтов. Перезагрузка (проблема временно уходит), а буфер канала – 65536 байт. См. Тестовый результат ниже.

Итак, теперь возникает вопрос: почему / как «что-то» уменьшает размер буфера в системе.

С проблемой

 $ /bin/bash -c 'for p in {0..18}; do pipe-buffer-test.sh $((2 ** $p)) 0.5; done' write size: 1; bytes successfully before error: 128 write size: 2; bytes successfully before error: 128 write size: 4; bytes successfully before error: 128 write size: 8; bytes successfully before error: 128 write size: 16; bytes successfully before error: 128 write size: 32; bytes successfully before error: 128 write size: 64; bytes successfully before error: 128 write size: 128; bytes successfully before error: 128 write size: 256; bytes successfully before error: 0 write size: 512; bytes successfully before error: 0 write size: 1024; bytes successfully before error: 0 write size: 2048; bytes successfully before error: 0 write size: 4096; bytes successfully before error: 0 write size: 8192; bytes successfully before error: 0 write size: 16384; bytes successfully before error: 0 write size: 32768; bytes successfully before error: 0 write size: 65536; bytes successfully before error: 0 write size: 131072; bytes successfully before error: 0 write size: 262144; bytes successfully before error: 0 

После перезагрузки (проблема временно исчезла)

 $ /bin/bash -c 'for p in {0..18}; do pipe-buffer-test.sh $((2 ** $p)) 0.5; done' write size: 1; bytes successfully before error: 65536 write size: 2; bytes successfully before error: 65536 write size: 4; bytes successfully before error: 65536 write size: 8; bytes successfully before error: 65536 write size: 16; bytes successfully before error: 65536 write size: 32; bytes successfully before error: 65536 write size: 64; bytes successfully before error: 65536 write size: 128; bytes successfully before error: 65536 write size: 256; bytes successfully before error: 65536 write size: 512; bytes successfully before error: 65536 write size: 1024; bytes successfully before error: 65536 write size: 2048; bytes successfully before error: 65536 write size: 4096; bytes successfully before error: 65536 write size: 8192; bytes successfully before error: 65536 write size: 16384; bytes successfully before error: 65536 write size: 32768; bytes successfully before error: 65536 write size: 65536; bytes successfully before error: 65536 write size: 131072; bytes successfully before error: 0 write size: 262144; bytes successfully before error: 0 

  • Запустить fgrep multicore mac os x
  • Почему ядро ​​может быть дросселировано?
  • Пробелы как разрывы строк из команды inline for loop
  • Что такое PATH на Mac OS?
  • Могу ли я отменить SSH (после его использования для просмотра) без выхода из системы?
  • Как скопировать пасту на удаленный сервер?
  • Mac OS X find / grep генерирует "unknown --devices option"
  • Как работают локализация имен папок?
  • One Solution collect form web for “более длинная строка для tr вызывает зависание и всплеск процессора”

    Основываясь на комментарии @ Barmar о утечке ядровых буферов, я взглянул на текущие не-OS kexts. Я понял, что существует относительно новая из недавней установки BlockBlock ( https://objective-see.com/products/blockblock.html ).

    Удален BlockBlock, перезапущен, и проблема не возникла. Поэтому BlockBlock был виновником в этом деле, и я сообщил об этом автору.

    Однако это не особенно удовлетворительно, так как я использовал метод «догадки и проверки», чтобы понять причину, и, честно говоря, я действительно не понимаю основную причину (с точки зрения ОС), что означает, что я не являюсь -wiser для устранения этой проблемы в будущем.

    Если кто-то сталкивается с этим и может объяснить, что происходит более подробно и обеспечить подход к поиску и устранению неполадок, это будет гораздо лучший ответ, чем «удалить BlockBlock».

    Linux и Unix - лучшая ОС в мире.