2012-01-19 19 views
5

Me encuentro con una situación extraña al pasar un puntero a una estructura con una matriz muy grande definida en la definición struct {}, una matriz flotante de alrededor de 34MB de tamaño. En pocas palabras, el pseudo-código es el siguiente:Extraño desbordamiento de pila?

typedef config_t{ 
    ... 
    float values[64000][64]; 
} CONFIG; 


int32_t Create_Structures(CONFIG **the_config) 
{ 
    CONFIG *local_config; 
    int32_t number_nodes; 

    number_nodes = Find_Nodes(); 

    local_config = (CONFIG *)calloc(number_nodes,sizeof(CONFIG)); 
    *the_config = local_config; 
    return(number_nodes); 
} 


int32_t Read_Config_File(CONFIG *the_config) 
{ 
    /* do init work here */ 
    return(SUCCESS); 
} 


main() 
{ 
    CONFIG *the_config; 
    int32_t number_nodes,rc; 

    number_nodes = Create_Structures(&the_config); 

    rc = Read_Config_File(the_config); 
    ... 
    exit(0); 
} 

El código compila bien, pero cuando intento ejecutarlo, voy a conseguir un SIGSEGV en el {debajo Read_Config_File().

(gdb) run 
... 
Program received signal SIGSEGV, Segmentation fault. 
0x0000000000407d0a in Read_Config_File (the_config=Cannot access memory at address 0x7ffffdf45428 
) at ../src/config_parsing.c:763 
763 { 
(gdb) bt 
#0 0x0000000000407d0a in Read_Config_File (the_config=Cannot access memory at address 0x7ffffdf45428 
) at ../src/config_parsing.c:763 
#1 0x00000000004068d2 in main (argc=1, argv=0x7fffffffe448) at ../src/main.c:148 

He hecho este tipo de cosas todo el tiempo, con matrices más pequeñas. Y, curiosamente, 0x7fffffffe448 - 0x7ffffdf45428 = 0x20B8EF8, o aproximadamente 34MB de mi matriz flotante.

Valgrind me dará un resultado similar:

==10894== Warning: client switching stacks? SP change: 0x7ff000290 --> 0x7fcf47398 
==10894==   to suppress, use: --max-stackframe=34311928 or greater 
==10894== Invalid write of size 8 
==10894== at 0x407D0A: Read_Config_File (config_parsing.c:763) 
==10894== by 0x4068D1: main (main.c:148) 
==10894== Address 0x7fcf47398 is on thread 1's stack 

Los mensajes de error apuntan a mí clobbering el puntero de pila, pero a) nunca me he encontrado con uno que se estrella en la entrada de la función y b) Estoy pasando punteros, no la matriz real.

¿Alguien me puede ayudar con esto? Estoy en una caja de CentOS de 64 bits ejecutando kernel 2.6.18 y gcc 4.1.2

¡Gracias!

Matt

+9

El pseudocódigo de publicación solo obtendrá pseudo respuestas. El diablo está en los detalles, y probablemente todos importen. –

+2

¿Podríamos ver el origen de 'Read_Config_File'? Ahí es donde parece que está el problema, en el bloque que eliras. – Borealid

+0

No está probando el valor de retorno de calloc(), que podría fallar. –

Respuesta

1

Has volado la pila asignando una de estas enormes estructuras config_t en ella. Los dos indicadores de pila en la evidencia en la salida de gdb, 0x7fffffffe448 y 0x7ffffdf45428, son muy sugerentes de esto.

$ gdb 
GNU gdb 6.3.50-20050815 ...blahblahblah... 
(gdb) p 0x7fffffffe448 - 0x7ffffdf45428 
$1 = 34312224 

Tiene su constante ~ 34MB que coincide con el tamaño de la estructura config_t. Los sistemas no le dan ese espacio de pila por defecto, así que mueva el objeto de la pila o aumente su espacio de pila.

+0

¿Hay alguna herramienta similar a una "pelusa" que pueda decirme cuánto apilará una función? En retrospectiva, ahora es bastante obvio cuál fue el mal funcionamiento, pero me encantaría saber por adelantado si existen tales problemas. – tranzmatt

+0

gcc tiene -fstack-limit- * para comprobaciones de tiempo de ejecución, pero no conozco nada que advierta sobre asignaciones de pila excesivamente grandes en tiempo de compilación. –

1

La respuesta corta es que tiene que haber una config_t declarada como una variable local en algún lugar, lo que pondría en la pila. Probablemente un error tipográfico: falta * después de una declaración CONFIG en algún lugar.

+0

Ese fue el problema. Olvidé que había guardado una copia temporal de la estructura config_t en la función antes de atascar la matriz dentro. Moví la matriz a otra parte y ahora no seg seg. Gracias. – tranzmatt

Cuestiones relacionadas