2010-04-02 19 views
11

Tengo un programa que implementa varios algoritmos de búsqueda heurística y varios dominios, diseñados para evaluar experimentalmente los diversos algoritmos. El programa está escrito en C++, construido utilizando la cadena de herramientas GNU, y se ejecuta en un sistema Ubuntu de 64 bits. Cuando ejecuto mis experimentos, uso el comando ulimit de bash para limitar la cantidad de memoria virtual que el proceso puede usar, de modo que mi sistema de prueba no comience a intercambiarse.¿Por qué mi programa ocasionalmente segfault cuando falta memoria en lugar de tirar std :: bad_alloc?

Ciertas combinaciones de algoritmo/instancia de prueba alcanzan el límite de memoria que he definido. La mayoría de las veces, el programa arroja una excepción std :: bad_alloc, que es impresa por el controlador predeterminado, en cuyo punto finaliza el programa. Ocasionalmente, en lugar de que esto suceda, el programa simplemente segfaults.

¿Por qué mi programa ocasionalmente segfault cuando falta la memoria, en lugar de informar un std :: bad_alloc no administrado y la terminación?

+0

Segfault puede ser causado no solo porque tocas el límite de memoria – Andrey

+0

Estoy muy consciente. En los casos en que he visto una segfault, el proceso ha estado usando cantidades de memoria cercanas al límite que he especificado. Estoy bastante seguro de que los segmentos que vi no se debieron a errores en mi código. –

+1

¿Ha considerado una ejecución simple en GDB (bueno, algunos de ellos) para ver qué parte del código seg-fault? – Shiroko

Respuesta

8

Una razón podría ser que, por defecto, Linux excede la memoria. Solicitar memoria del kernel parece funcionar bien, pero más tarde cuando realmente empiezas a usar la memoria, el kernel nota "Oh, mierda, me estoy quedando sin memoria", invoca al asesino de memoria insuficiente (OOM) que selecciona algunos proceso de la víctima y lo mata.

Para una descripción de este comportamiento, consulte http://lwn.net/Articles/104185/

+0

Posiblemente. Algo más de información, he estado corriendo como el único usuario en el sistema de prueba, que tiene 48GB de memoria. He corrido con un ulimit de memoria virtual de 47 GB, que debería dejar bastante memoria para el sistema operativo. El artículo vinculado es de 2004. ¿Sigue siendo relevante hoy? –

1

Lo janneb dijo. De hecho, Linux por defecto nunca arroja std :: bad_alloc (o devuelve NULL desde malloc()).

+0

Supongo que quiere decir "std :: bad_alloc nunca se arroja por defecto en Linux". ¿Por qué, entonces, he visto std :: bad_alloc lanzado desde programas C++ en varios sistemas Linux cuando el programa alcanza su límite de memoria? –

+0

Además, creo que te refieres a 'malloc 'en lugar de' libre'. La página man de Linux para malloc no hace que suene como NULL nunca será devuelto. –

+0

@radford. Por supuesto, tienes razón. Fijo. –

1

Podría ser algún código que use no-throw new y no verifique el valor de retorno.

O algún código podría estar atrapando la excepción y no manejarlo o volver a lanzarlo.

Cuestiones relacionadas