grep segfaults quando passado "-r" e "--exclude-dir" e stdin é um pipe

2

Se eu canalizar dados para o grep E passar o sinalizador "-r" (recursar subdiretórios) E passar o flag "--exclude-dir" (por exemplo, para pular diretórios ".git"), então ele segfaults. Se qualquer uma dessas coisas estiver faltando, tudo bem.

$ ls | grep -r --exclude-dir=\.git pattern
Segmentation fault

Alguém mais vê esse comportamento?

Estou usando o grep 2.11 (o mais recente) instalado pelo Homebrew no OSX, porque o built-in do OSX grep é tão antigo que ele não suporta recursos que eu uso muito, como '--exclude-dir' .

Você pode estar se perguntando por que estou passando esses sinalizadores, já que ambos são sem sentido quando o grep está filtrando stdin (em vez de pesquisar arquivos), mas a razão é que tenho esses sinalizadores especificados em um alias, 'grp':

alias grp='grep -r --exclude-dir=\.git'

porque eu quero que eles sejam on-by-default toda vez que invoco manualmente grp de uma linha de comando. Meu 'grp' real contém muito mais bandeiras do que isso, mas estas são as que estão me causando problemas hoje em dia.

Por isso, esses sinalizadores são úteis (e funcionam bem) quando eu vou:

grp pattern .

que, acredito, deve estar se expandindo para:

grep -r --exclude-dir=\.git pattern .

Mas os sinalizadores ainda estão presentes quando eu uso o grep em seu modo "alternate-fire", onde ele filtra as linhas no stdin:

ll | grp pattern

que, acredito, deve estar se expandindo para:

ll | grep -r --exclude-dir=\.git pattern

e isso é o que segfaults. Remover o '-r' ou '--exclude-dir', ou o pipe no stdin, faz com que o segfault desapareça.

Eu dei uma olhada no corefile produzido e encontrei isto:

$ 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

Portanto, ele é segmentado no strlen chamado de "excluded_file_name". Isso soa relevante, mas não sei o que fazer com essa informação.

Esse arranjo costumava funcionar bem com o grep do MacPorts (e no Ubuntu antes disso), então imaginei que meu problema poderia ser causado pelo Homebrew. Então eu tentei compilar meu próprio grep a partir do gnu 2.11 source, mas o comportamento persiste. Eu não posso voltar para o MacPorts - eu tive que mudar para o Homebrew por outras razões, e pelo que entendi, eles não tocam muito bem juntos.

Por acaso, eu não gosto de usar a variável de ambiente GREP_OPTIONS para definir meus padrões, já que ele quebra qualquer ferramenta que eu invoco que invoca o grep internamente.

Então, minhas perguntas são:

  • Alguém mais vê esse comportamento ou é só eu?
  • Posso parar o grep de segfaulting? Ou apenas entender mais sobre por que é segmentado?
  • Como eu mudaria meu alias para que ele removesse '-r' do comando quando stdin está vindo de um cano?
por Jonathan Hartley 17.03.2012 / 14:28

1 resposta

1

Parece que pode haver uma regressão relacionada à última versão :

** New features

If no file operand is given, and a command-line -r or equivalent option is given, grep now searches the working directory. Formerly grep ignored the -r and searched standard input nonrecursively. An -r found in GREP_OPTIONS does not have this new effect.

Em outras palavras, o comportamento de -r mudou e talvez não tenha sido exaustivamente testado antes do lançamento. Eu colocaria um relatório de bug para eles - provavelmente é mais provável que resulte em uma correção.

    
por 20.03.2012 / 16:36