2010-04-02 6 views
11

Ich habe ein Programm, das mehrere heuristische Suchalgorithmen und mehrere Domänen implementiert, entworfen, um die verschiedenen Algorithmen experimentell zu bewerten. Das Programm ist in C++ geschrieben, mit der GNU-Toolchain erstellt und läuft auf einem 64-Bit-Ubuntu-System. Wenn ich meine Experimente durchführe, verwende ich den Befehl ulimit von bash, um die Menge an virtuellem Speicher zu begrenzen, den der Prozess verwenden kann, so dass mein Testsystem nicht mit dem Austausch beginnt.Warum segmentiert mein Programm gelegentlich, wenn nicht genügend Arbeitsspeicher vorhanden ist, anstatt std :: bad_alloc zu werfen?

Bestimmte Algorithmen/Test-Instanz-Kombinationen treffen auf das von mir definierte Speicherlimit. In den meisten Fällen löst das Programm eine std :: bad_alloc-Ausnahme aus, die vom Standardhandler ausgegeben wird. An diesem Punkt wird das Programm beendet. Gelegentlich, anstatt dass dies geschieht, segmentiert das Programm einfach.

Warum segmentiert mein Programm gelegentlich, wenn nicht genügend Arbeitsspeicher vorhanden ist, anstatt einen unbehandelten std :: bad_alloc zu melden und zu beenden?

+0

segfault kann nicht nur verursacht werden, weil Sie Limit des Speichers – Andrey

+0

Ich bin mir ziemlich bewusst. In den Fällen, in denen ich einen Segfault gesehen habe, verwendet der Prozess Speichermengen in der Nähe des von mir angegebenen Grenzwerts. Ich bin ziemlich zuversichtlich, dass die Segfaults, die ich sah, nicht auf Fehler in meinem Code zurückzuführen waren. –

+1

Haben Sie einen einfachen Lauf in GDB (gut einige von ihnen) in Betracht gezogen, um zu sehen, welcher Teil des Codes seg-Fehler? – Shiroko

Antwort

8

Ein Grund könnte sein, dass Linux standardmäßig den Speicher überbrückt. Das Anfordern von Speicher aus dem Kernel scheint in Ordnung zu sein, aber später, wenn Sie den Speicher tatsächlich verwenden, bemerkt der Kernel "Oh Mist, ich habe keinen Speicher mehr", ruft den OOM-Killer auf, der einige auswählt Opfer Prozess und tötet es.

Eine Beschreibung dieses Verhaltens finden Sie http://lwn.net/Articles/104185/

+0

Möglicherweise. Noch ein paar Infos, die ich als einziger Benutzer auf dem Testsystem ausgeführt habe, das 48 GB Arbeitsspeicher hat. Ich habe mit einem virtuellen Speicher-Ulimit von 47 GB ausgeführt, was viel Kernspeicher für das Betriebssystem übrig lassen sollte. Der verlinkte Artikel stammt aus dem Jahr 2004. Ist er noch heute relevant? –

1

Was janneb sagte. In der Tat Linux standardmäßig nie löst std :: bad_alloc (oder gibt NULL von malloc()).

+0

Ich nehme an, du meinst "std :: bad_alloc wird niemals standardmäßig auf Linux geworfen". Warum habe ich dann std :: bad_alloc aus C++ - Programmen auf mehreren Linux-Systemen geworfen, wenn das Programm das Speicherlimit erreicht? –

+0

Außerdem denke ich, du meinst "malloc" anstatt "frei". Die Linux-Manpage für malloc lässt es nicht klingen, dass NULL nie zurückgegeben wird. –

+0

@Bradford. Natürlich hast du recht. Fest. –

1

Es könnte Code sein, der No-Throw New verwendet und den Rückgabewert nicht überprüft.

Oder irgendein Code könnte die Ausnahme abfangen und sie nicht behandeln oder sie erneut auslösen.

Verwandte Themen