grep segfaults, wenn "-r" und "--exclude-dir" übergeben werden und stdin eine Pipe ist

765
Jonathan Hartley

Wenn ich Daten in grep übergebe und das "-r" -Flag übergebe (recurse-Unterverzeichnisse) UND das "--exclude-dir" -Flag übergeben (z. B. um ".git" -Verzeichnisse zu überspringen), dann fallen die Fehler auf. Wenn eines dieser Dinge fehlt, ist es in Ordnung.

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

Kann jemand anderes dieses Verhalten sehen?

Ich verwende grep 2.11 (das neueste), das von Homebrew unter OSX installiert wird, weil das integrierte OSX-grep so alt ist, dass es nicht die von mir häufig verwendeten Funktionen wie "--exclude-dir" unterstützt.

Sie wundern sich vielleicht, warum ich diese Flags übergeben habe, da beide bedeutungslos sind, wenn grep stdin filtert (im Gegensatz zum Durchsuchen von Dateien). Der Grund ist, dass ich diese Flags in einem Alias ​​"grp" angegeben habe:

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

weil ich möchte, dass sie standardmäßig jedes Mal aktiviert werden, wenn ich grp manuell von einer Befehlszeile aus aufrufe. Mein eigentliches 'GRP' enthält viel mehr Flaggen als dieses, aber das sind die, die mir heute Probleme bereiten.

Daher sind diese Flags nützlich (und funktionieren gut), wenn ich gehe:

grp pattern . 

was ich glaube muss sich erweitern auf:

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

Die Flags sind jedoch immer noch vorhanden, wenn ich grep im Modus "alternate-fire" verwende, in dem Zeilen auf stdin gefiltert werden:

ll | grp pattern 

was ich glaube muss sich erweitern auf:

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

und das ist, was segfaults. Wenn Sie entweder '-r' oder '--exclude-dir' oder die Pipe auf stdin entfernen, wird der Segfault entfernt.

Ich habe mir das produzierte Corefile angesehen und folgendes gefunden:

$ 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 

Es ist also ein Segfaulting in strlen, das von 'excluded_file_name' aufgerufen wird. Das klingt relevant, aber ich weiß nicht, was ich mit diesen Informationen anfangen soll.

Früher funktionierte dieses Arrangement gut mit grep von MacPorts (und Ubuntu davor), sodass ich dachte, mein Problem könnte von Homebrew verursacht werden. Also habe ich versucht, mein eigenes grep aus gnu 2.11 zu kompilieren, aber das Verhalten bleibt bestehen. Ich kann nicht zu MacPorts zurückkehren - ich musste aus anderen Gründen zu Homebrew wechseln, und wenn ich es verstehe, spielen sie nicht gut zusammen.

Übrigens mag ich die Umgebungsvariable GREP_OPTIONS nicht zum Festlegen meiner Standardeinstellungen verwenden, da dadurch alle von mir ausgeführten Tools, die intern grep aufrufen, beschädigt werden.

Meine Fragen sind also:

  • Hat jemand anderes dieses Verhalten oder ist es nur ich?
  • Kann ich verhindern, dass Grep segfaulting ist? Oder einfach nur mehr darüber verstehen, warum es Segfaulting ist?
  • Wie würde ich meinen Alias ​​so ändern, dass '-r' aus dem Befehl entfernt wird, wenn stdin aus einer Pipe kommt?
2

1 Antwort auf die Frage

1
l0b0

Sieht so aus, als könnte es sich um eine Regression im Zusammenhang mit der neuesten Version handeln :

** Neue Eigenschaften

Wenn kein Dateioperand angegeben ist und eine Befehlszeilenoption -r oder eine entsprechende Option angegeben wird, durchsucht grep jetzt das Arbeitsverzeichnis. Früher ignorierte grep die Option -r und durchsuchte die Standardeingabe nicht rekursiv. Ein in GREP_OPTIONS gefundenes -r hat diesen neuen Effekt nicht.

Mit anderen Worten, das Verhalten von hat sich -rgeändert und wurde vor der Veröffentlichung möglicherweise nicht ausführlich getestet. Ich würde einen Fehlerbericht an sie senden - wahrscheinlich führt dies wahrscheinlich zu einer Korrektur.

Gute Idee. FWIW: https://savannah.gnu.org/bugs/index.php?35915 Jonathan Hartley vor 12 Jahren 0
Es ist ein bekannter Fehler in der neuesten Version von grep, der in der nächsten Version behoben wird. Das Festschreiben von Commit ist dieses: http://git.savannah.gnu.org/cgit/grep.git/commit/?id=12c957f786b12a4dd116f9c40a715d671d17fa16 Jonathan Hartley vor 12 Jahren 0