2010-04-02 11 views
11

Ho un programma che implementa diversi algoritmi di ricerca euristica e diversi domini, progettati per valutare sperimentalmente i vari algoritmi. Il programma è scritto in C++, costruito utilizzando la toolchain GNU ed eseguito su un sistema Ubuntu a 64 bit. Quando eseguo i miei esperimenti, utilizzo il comando ulimit di bash per limitare la quantità di memoria virtuale che il processo può utilizzare, in modo che il mio sistema di test non inizi a scambiare.Perché il mio programma occasionalmente segfault quando esaurisce la memoria anziché lanciare std :: bad_alloc?

Determinate combinazioni di istanze di algoritmi/test hanno raggiunto il limite di memoria che ho definito. La maggior parte delle volte, il programma genera un'eccezione std :: bad_alloc, che viene stampata dal gestore predefinito, a quel punto il programma termina. Occasionalmente, piuttosto che questo accade, il programma semplicemente segfaults.

Perché il mio programma occasionalmente segfault quando esaurisce la memoria, invece di segnalare un std :: bad_alloc non gestito e che termina?

+0

segfault può essere causato non solo perché si raggiunge limite di memoria – Andrey

+0

Sono a conoscenza. Nei casi in cui ho visto un segfault, il processo ha utilizzato quantità di memoria vicine al limite che ho specificato. Sono abbastanza fiducioso che i segfault che ho visto non erano dovuti a bug nel mio codice. –

+1

Hai considerato una semplice esecuzione in GDB (alcuni di loro) per vedere quale parte del codice segna errori? – Shiroko

risposta

8

Un motivo potrebbe essere che, per impostazione predefinita, la memoria overcommit di Linux. La richiesta di memoria dal kernel sembra funzionare, ma in seguito, quando in realtà inizierai a utilizzare la memoria, il kernel avverte "Oh crap, sto esaurendo la memoria", invoca l'assassino out-of-memory (OOM) che seleziona alcuni processo della vittima e lo uccide.

Per una descrizione di questo comportamento, vedere http://lwn.net/Articles/104185/

+0

Possibilmente. Altre informazioni, ho eseguito come unico utente sul sistema di test, che ha 48 GB di memoria. Ho eseguito con un ulimit memoria virtuale da 47 GB, che dovrebbe lasciare un sacco di memoria di base per il sistema operativo. L'articolo collegato è del 2004. È ancora attuale oggi? –

1

Cosa janneb detto. In effetti, Linux per impostazione predefinita mai genera std :: bad_alloc (o restituisce NULL da malloc()).

+0

Suppongo tu voglia dire "std :: bad_alloc non viene mai generato di default su Linux". Perché, quindi, ho visto std :: bad_alloc generato da programmi C++ su diversi sistemi Linux quando il programma raggiunge il limite di memoria? –

+0

Inoltre, penso che tu intenda "malloc" piuttosto che "libero". La pagina man di Linux per malloc non fa sembrare che NULL non verrà mai restituito. –

+0

@Bradford. Certo, hai ragione. Fisso. –

1

Potrebbe essere un codice che utilizza no-throw new e non controlla il valore restituito.

O un po 'di codice potrebbe catturare l'eccezione e non gestirla o rilanciarla.

Problemi correlati