Pregunta de C
Alvaro Herrera
alvherre en commandprompt.com
Mie Mayo 10 10:55:56 CLT 2006
rodrigo ahumada escribió:
> On Tue, 9 May 2006 20:07:10 -0400
> Alvaro Herrera <alvherre en alvh.no-ip.org> wrote:
>
> > Se aprecia que las variables arr y nulls son creadas como arreglos del
> > tamaño especificado que no es constante en tiempo de compilacion, sino
> > que se determina en tiempo de ejecucion dependiendo del contenido del
> > struct Relation.
> >
> > Es valido esto? Debo mencionar que compila perfectamente sin ningun
> > warning (con varias opciones -W), y que funciona perfectamente para
> > algunos valores de foo->natts. Sin embargo, el programa se cae en un
> > caso muy particular que es cuando foo->natts es 61, un valor superior a
> > los valores tipicos. (natts es el numero de columnas de una tabla; por
> > lo tanto 61 es un valor perfectamente valido pero tipicamente los
> > valores andan cercanos a la veintena).
>
> [...]
>
> yo hice este codigo:
>
> [...]
> y al ver el .s que sale:
> (lo estuve siguiendo un poco, no se si lo hice bien, pero se nota que
> en la funcion rareza, en dos partes se guardan bytes en el stack
> segun el valor de [ebp+8] (valor))
Gracias! Yo no se leer assembly lamentablemente :-( Pero creo que tu
interpretacion tiene sentido, e indica que no hay un bug realmente, sino
que el codigo deberia funcionar.
> ...
> .globl rareza
> .type rareza, @function
> rareza:
> push %ebp
> mov %ebp, %esp
> push %ebx
> sub %esp, 36 ; reserva 36 bytes en el stack
> mov DWORD PTR [%ebp-12], %esp ; guarda el tope del stack dentro de esos 36 bytes
>
> mov %edx, DWORD PTR [%ebp+8] ; edx = valor
> lea %eax, [%edx+15] ; eax = valor +15
> add %eax, 15 ; eax = valor + 15 +15
> shr %eax, 4 ; eax = (valor + 15 +15) / 16
> sal %eax, 4 ; eax = ((valor + 15 +15) / 16) * 16 ¿?
> sub %esp, %eax ; reserva EAX bytes mas en el stack
> lea %eax, [%esp+8] ; eax = 8 bytes antes del tope del stack
> add %eax, 15 ;
> shr %eax, 4
> sal %eax, 4
> mov DWORD PTR [%ebp-16], %eax
Segun esto, estaria reservando en el stack tanto espacio como sea
necesario para guardar el arreglo.
> el programa lo he probado con numeros mas grandes que 61 y no se me ha caido...
> de todas formas, al compilar da ni una queja, y alojar memoria el el stack
> segun el valor de una variable... (!)
Ok, tengo que acotar que el problema parece ser que al llegar a un
cierto tope escribiendo en el arreglo, empieza a escribir en la variable
que viene despues en el stack. O sea creo que algo asi deberia mostrar
el problema -- sin embargo, el programa funciona perfectamente y el
canario no se muere.
#include <stdio.h>
#include <stdlib.h>
struct foo
{
int bar;
};
int buggy(struct foo *a_foo)
{
int tam = a_foo->bar;
char *valor[tam];
int canario = 0x7e7e7e7e;
int i;
printf("canario: %d\n", canario);
for (i = 0; i < tam; i++)
{
valor[tam] = "hey";
}
printf("canario: %d (%d veces)\n", canario, i);
return canario;
}
int main(int argc, char **argv)
{
struct foo a_foo;
if (argc >= 2)
a_foo.bar = atoi(argv[1]);
else
a_foo.bar = 100;
printf("ret: %d\n", buggy(&a_foo));
return 0;
}
--
Alvaro Herrera http://www.CommandPrompt.com/
PostgreSQL Replication, Consulting, Custom Development, 24x7 support
Más información sobre la lista de distribución Linux