[eside-ghost] GDB y stack frames

Alfredo Beaumont alfredo.beaumont en gmail.com
Jue Mayo 1 12:59:31 CEST 2008


Og, 2008eko Mairen 01a(e)an, Arkaitz(e)k idatzi zuen:
> Aupa, tengo una duda con gdb,
> He estado debugeando este simple programa y veo alguna pequenia diferencia
> que no acabo de seguir.
> Como se ve, he metido un breakpoint en la llamada al sleep y examino la
> pila.
> El gdb me canta una direccion de arglist 0xbfe7ad18, pero como se ve en
> realidad, el 5 que le paso al sleep esta en 0xbfe7ad20, osea, 8 bytes mas a
> tarde. Pensaba que podria ser rollo direccion de retorno y asi, pero en ese
> caso no entiendo porque GDB me canta eso con el label arglist, la direccion
> del frame la pone en ad50, pero entiendo que esta mas tarde porque crece
> hacia arriba.
> Alguna pista?
>
> (gdb) list main
> 1       #include <sys/types.h>
> 2
> 3       int main(){
> 4               printf("%d\n",sizeof(size_t));
> 5               sleep(5);
> 6       }
> 7
> (gdb) bt
> #0  0x0086c4d6 in sleep () from /lib/tls/libc.so.6
> #1  0x080483d4 in main () at main.c:5
> (gdb) frame 0
> #0  0x0086c4d6 in sleep () from /lib/tls/libc.so.6
> (gdb) info frame
> Stack level 0, frame at 0xbfe7ad20:
>  eip = 0x86c4d6 in sleep; saved eip 0x80483d4
>  called by frame at 0xbfe7ad50
>  Arglist at 0xbfe7ad18, args:
>  Locals at 0xbfe7ad18, Previous frame's sp is 0xbfe7ad20
>  Saved registers:
>   ebp at 0xbfe7ad18, eip at 0xbfe7ad1c
> (gdb) x/8x 0xbfe7ad18
> 0xbfe7ad18:     0xbfe7ad48      0x080483d4      0x00000005      0x00000004
> 0xbfe7ad28:     0xbfe7ad48      0x080483f6      0x00907ff4      0x00907ff4

El propio backtrace te está dando la información. Cuando haces una llamada a 
una función en C, lo que se hace es guardar en la pila los argumentos y 
también la dirección de retorno. Además, la función, al ser llamada, lo que 
hace es almacenar también el base pointer anterior, antes de sobreescribirlo 
con el nuevo. Eso quiere decir que en primer lugar tendrás el base pointer 
viejo (ebp viejo), y en segundo lugar la dirección de retorno (eip viejo). 
Eso es precisamente lo que te está indicando en "Saved registers":

 * Contenido anterior del ebp en 0xbf7ad18, que contiene 0xbfe7ad48, que es el 
valor del base pointer viejo.
 * Dirección de retorno en 0xbfad1c, que contiene 0x08r83d4 que si te fijas 
está en main, que es la función que ha llamado

Esto quiere decir que los argumentos empiezan a aparecer después de esos 2 
registros (de 4 bytes): 0xbfe7ad20

Saludos
-- 
Alfredo Beaumont Sainz
http://www.alfredobeaumont.org/blog.cgi


Más información sobre la lista de distribución eside-ghost