grep segfaults когда передается "-r" и "--exclude-dir", а stdin - это канал
690
Jonathan Hartley
Если я передаю данные в grep И передаю флаг "-r" (recurse subdirs) И передаю флаг "--exclude-dir" (например, чтобы пропустить каталоги ".git"), то он segfaults. Если что-то из этого отсутствует, то это нормально.
$ ls | grep -r --exclude-dir=\.git pattern Segmentation fault
Кто-нибудь еще видит это поведение?
Я использую grep 2.11 (последний), установленный Homebrew для OSX, потому что встроенный в OSX grep настолько стар, что не поддерживает функции, которыми я интенсивно пользуюсь, например, сам «--exclude-dir».
Вы можете удивиться, почему я передаю эти флаги, так как они оба бессмысленны, когда grep фильтрует стандартный ввод (в отличие от поиска файлов), но причина в том, что эти флаги указаны в псевдониме 'grp':
alias grp='grep -r --exclude-dir=\.git'
потому что я хочу, чтобы они были включены по умолчанию каждый раз, когда я вручную вызываю grp из командной строки. Мой настоящий «grp» содержит гораздо больше флагов, чем этот, но именно они вызывают у меня проблемы сегодня.
Следовательно, эти флаги полезны (и работают нормально), когда я иду:
grp pattern .
который, я считаю, должен расшириться до:
grep -r --exclude-dir=\.git pattern .
Но флаги все еще присутствуют, когда я использую grep в режиме «альтернативного огня», где он фильтрует строки в stdin:
ll | grp pattern
который, я считаю, должен расшириться до:
ll | grep -r --exclude-dir=\.git pattern
и это то, что segfaults. Удаление либо '-r' или '--exclude-dir', либо канала на stdin, убирает segfault.
Я посмотрел на созданный файл corefile и нашел это:
$ gdb grep /cores/core.31786 GNU gdb 6.3.50-20050815 (Apple version gdb-1515) (Sat Jan 15 08:33:48 UTC 2011) ... This GDB was configured as "x86_64-apple-darwin" ... #0 0x00007fff8897ac00 in strlen () (gdb) bt #0 0x00007fff8897ac00 in strlen () #1 0x0000000100015576 in excluded_file_name (ex=0x1001005a0, f=0x0) at exclude.c:445 #2 0x0000000100012305 in grepdir (dir=0x0, stats=0x100048620) at main.c:1364 #3 0x0000000100014048 in main (argc=11, argv=0x7fff5fbff0b8) at main.c:2216
Так что это segfaulting в strlen вызывается из 'exclude_file_name'. Это звучит актуально, но я не знаю, что делать с этой информацией.
Эта схема работала нормально с grep из MacPorts (и до этого в Ubuntu), поэтому я решил, что моя проблема может быть вызвана Homebrew. Поэтому я попытался скомпилировать свой собственный grep из источника GNU 2.11, но поведение сохраняется. Я не могу вернуться к MacPorts - мне пришлось переключиться на Homebrew по другим причинам, и, насколько я понимаю, они не очень хорошо играют вместе.
Между прочим, мне не нравится использовать переменную среды GREP_OPTIONS для установки значений по умолчанию, так как она ломает все инструменты, которые я запускаю, которые вызывают grep внутри.
Итак, мои вопросы:
Кто-нибудь еще видит такое поведение, или это только у меня?
Могу ли я остановить grep от segfaulting? Или просто понять больше о том, почему это segfaulting?
Как бы я изменил свой псевдоним, чтобы он удалял '-r' из команды, когда stdin приходит из канала?
Если файловый операнд не указан и задана опция командной строки -r или эквивалентная, grep теперь выполняет поиск в рабочем каталоге. Ранее grep игнорировал -r и искал стандартный ввод нерекурсивно. -R, найденный в GREP_OPTIONS, не имеет этого нового эффекта.
Другими словами, поведение -rизменилось и, возможно, не было исчерпывающе проверено перед выпуском. Я бы отправил им сообщение об ошибке - это, скорее всего, приведет к исправлению.
Отличная идея. FWIW: https://savannah.gnu.org/bugs/index.php?35915
Jonathan Hartley 12 лет назад
0
Это известная ошибка в последней версии grep, которая будет исправлена в следующей версии. Фиксация фиксации: http://git.savannah.gnu.org/cgit/grep.git/commit/?id=12c957f786b12a4dd116f9c40a715d671d17fa16
Jonathan Hartley 12 лет назад
0