2011-12-18 13 views
5

fragmentos de código de dos archivos de código fuente C:puntero después de la llamada a la función

Ac

Channel *testChannelGet() 
{ 
    Channel *ch = channelGet (parser,parserCh); 
    return ch; 
} 

Bc

Channel *channelGet(UINT8 parser, UINT16 parserCh) 
{ 
    chnl.player = &solPlayer; 
    return((Channel *)&chnl); 
} 

Compilo ambos archivos y crear una estática y una biblioteca compartida . Ahora llamo TestChannelGet desde un programa de ejemplo. Cuando lo conecto contra la biblioteca estática, funciona perfectamente. Pero si lo conecto contra la biblioteca compartida, es SEGFAULTing. La depuración me dice que el puntero devuelto por channelGet está cambiando en el momento en que regresa. GDB salida a continuación.

174   Channel *ch = channelGet (parser,parserCh); 
(gdb) s 
channelGet (parser=1 '\001', parserCh=1) at B.c:15174 
15174   chnl.player = &solPlayer; 
(gdb) n 
15175   return((Channel *)&chnl); 
(gdb) p ((Channel *)&chnl) 
$1 = (Channel *) 0x7ffff7fed1a0 
(gdb) n 
15176 } 
(gdb) n 
testChannelGet at A.c:175 
175   return ch; 
(gdb) p ch 
$2 = (Channel *) 0xfffffffff7fed1a0 

parece que los puntos de valor de dirección a un desplazamiento diferente ahora - 0xfffffffff7fed1a0 vs 0x7ffff7fed1a0. Los últimos bytes en ambas direcciones son iguales.

¿Alguna pista? He intentado la opción -fPIC inútilmente.

+0

¿Qué es 'chnl' y dónde está definido? – Jan

+0

Es una variable global definida en B.c - Channel chnl; e inicializado en otro archivo, chnl = malloc (sizeof (Channel *)); – Vasu

+0

¿Podría ser que cuando llame a la lib dinámica no se realice la inicialización? –

Respuesta

5

¿Hay un prototipo en el alcance para channelGet() en A.c?

Si no es así, los resultados que estamos viendo podría explicarse de la siguiente manera:

  • channelGet() se supone volver int (debido a la falta de prototipo), por lo que el resultado se trunca a 0xf7fed1a0
  • entonces se echó a un puntero de 64 bits, así que se pone signo extendido a 0xfffffffff7fed1a0

(debe obtener quejas sobre esto si se compila con las advertencias activadas, por supuesto ...)

+0

+1: los moldes son casi siempre incorrectos en C :) – pmg

+0

Tengo el prototipo en un archivo de encabezado, que está incluido tanto en Ac como en Bc¿Y funcionaría para las bibliotecas estáticas si el problema fuera la falta de prototipo? – Vasu

+0

BTW cuando uso la biblioteca estática, las direcciones siempre están en el rango de 32 bits. ¿Necesito alguna bandera del compilador cuando creo la lib compartida? Estoy usando - gcc -fPIC -shared -Wl, -soname – Vasu

1

Ejecute su programa bajo valgrind. Encuentra y soluciona los errores que informa.

+0

funciona perfectamente en valgrind! Eso me molesta también :( – Vasu

+1

Luego trata de convertir tu problema en un ejemplo completo pero mínimo y lo intentaremos. No olvides incluir el proceso de compilación que estás usando, que podría ser el culpable. –

Cuestiones relacionadas