2010-05-10 19 views
7

La semana pasada estaba depurando un código y surgió una situación extraña: gdb pasa por dos cláusulas de devolución diferentes. Hice un ejemplo simple que ilustra la situación:¿Por qué gdb muestra dos resultados diferentes?

#include <iostream> 

using namespace std; 

int test() { 

    string a = "asd"; 
    string b = "asd"; 

    while (true) { 
     if (a == b) { 
      return 0; 
     } 
    } 
    return -1; 
} 

int main() { 
    int result = test(); 
    cout << "result: " << result << endl; 
} 

Al depurar el código que tengo:

(gdb) b main 
Breakpoint 1 at 0x1d4c: file example.cpp, line 19. 
(gdb) r 
Starting program: /Users/yuppienet/temp/a.out 
Reading symbols for shared libraries +++. done 

Breakpoint 1, main() at example.cpp:19 
19   int result = test(); 
(gdb) s 
test() at example.cpp:7 
7   string a = "asd"; 
(gdb) n 
8   string b = "asd"; 
(gdb) n 
11    if (a == b) { 
(gdb) n 
12     return 0; 
(gdb) n 
15   return -1; 
(gdb) n 
16  } 
(gdb) n 
main() at example.cpp:20 
20   cout << "result: " << result << endl; 
(gdb) n 
result: 0 
21  } 
(gdb) n 
0x00001ab2 in start() 

he observado que incluso si el BGF muestra la línea 15, el valor de retorno es 0 (el comando finish confirma esto también).

Entonces la pregunta es: ¿por qué gdb muestra la línea 15: return -1, incluso si la función realmente no está devolviendo este valor?

Gracias!

Editar: me olvidó mencionar que compilado con la siguiente línea:

g++ -Wall -pedantic -g -pg example.cpp 

Respuesta

4

Sospecho que está viendo el epílogo de la función. Sus dos cadenas tienen destructores, que se invocan implícitamente en el retorno. Checa lo que el desmontaje dice estar seguro, pero sospecho que las dos sentencias de retorno está correlacionando con algo en la línea de:

stash return_value; 
goto epilogue; 

y correspondientemente:

epilogue: 
    destroy a; // on the stack, so destructor will be called 
    destroy b; 
    really_return(stashed value); 

El epílogo parece provenir de la línea 15 como un efecto colateral de cómo g ++ hace la numeración de líneas - un formato bastante simple, realmente solo una lista de etiquetas de la forma "la dirección X proviene del número de línea Y" - y por eso informa 15 como la coincidencia más cercana. Confundir en este caso, pero corregir una gran cantidad de tiempo.

+3

+1 Esta parece ser la respuesta: si cambias ayb para que sean enteros, no ves el retorno -1 –

3

Probablemente porque el registro contador de programa pasa a través de las instrucciones que mejor mapa para el retorno final, es decir, la secuencia de salida de la función. El valor de retorno real probablemente se conserve en un registro, por lo que el primer return solo carga el valor adecuado y salta hasta el final de la función, y luego esa dirección se "retromadea" a la línea de código fuente del return final.

2

No lo dice, pero si compiló con la optimización que es exactamente el tipo de comportamiento que vería en gdb. Verá la primera línea configurando el valor de retorno, y luego saltará a la instrucción de retorno real, pero en C++ verá todo, incluido el valor de retorno.

+0

Actualmente compilé con 'g ++ -Wall -pedantic -g -pg' – YuppieNetworking

Cuestiones relacionadas