Aprende a usar GDB, el depurador de C
-
Upload
sergio-gomez -
Category
Education
-
view
137 -
download
0
Transcript of Aprende a usar GDB, el depurador de C
¿Cómo se produce un Segmentation Fault?
Básicamente al acceder a una zona de memoria a la que no tenemos acceso.
¿Cómo se produce un Segmentation Fault?
Acceso a memoria de solo lectura
int main(void) { char *s = "hello world"; *s = 'H'; // Segfault }
¿Cómo se produce un Segmentation Fault?
Acceso a memoria de solo lectura
int main(void) { char s[] = "hello world"; *s = 'H'; // OK }
¿Cómo se produce un Segmentation Fault?
Referencias a punteros nulos
int main(void) { int *ptr = NULL; printf("%d", *ptr); // Segfault }
¿Cómo se produce un Segmentation Fault?
Desbordamiento de bufferint main(void) { char A[8] = ""; unsigned short B = 1979; strcpy(A, "excessive"); }
¿Cómo se produce un Segmentation Fault?
Desbordamiento de bufferint main(void) { char A[8] = ""; unsigned short B = 1979; strcpy(A, "excessive"); }
int main(void) { char *ptr = (char *) malloc (sizeof(char) * 4); }
¿Cuál es el tamaño en bytes del bloque de memoria reservado para ptr?
4 bytes 5 bytes (4 + ‘/0’)
Más de 5 Ninguna es correcta
int main(void) { char *ptr = (char *) malloc (sizeof(char) * 4); }
¿Cuál es el tamaño en bytes del bloque de memoria reservado para ptr?
5 bytes (4 + ‘/0’)
Más de 5
int main(void) { char *ptr = (char *) malloc (sizeof(char) * 4); }
¿Cuál es el tamaño en bytes del bloque de memoria reservado para ptr?
Más de 5
Razones para no usar printf
1) No es una herramienta de depuración2) Nos obliga a ir probando para acotar el fallo
Razones para no usar printf
1) No es una herramienta de depuración2) Nos obliga a ir probando para acotar el fallo
3) Nos puede engañar
int mi_funcion(int *array, char *array2) {
asdasdksd saj dhljkdh sd has d SDa sd
asd asd asdasd sad adds sad sadsad sdas
asdasdasds adSD SDsd asdas dsad
d aSDSADASD ASD DDSDSADJKSHDKL JKSAHD JHJADHASD
ASDHASJDHKJASDHASKJDHAS
DASDJÑASKLDJAKSLDJÑALSKDJÑASKLDJASKDJAKSDJÑALSD
ASDÑKASDJÑLKASDJÑASKDJ
sadkjadsÑKLjdsadkalsdjñlaskjdñaskldjñalS
ASDKJÑDKLJasñkdljsñkdjasñkld
askljd ska ids ajdk sdjsakdñad }
int mi_funcion(int *array, char *array2) {
asdasdksd saj dhljkdh sd has d SDa sd printf(“A”);
asd asd asdasd sad adds sad sadsad sdas
asdasdasds adSD SDsd asdas dsad printf(“B”);
d aSDSADASD ASD DDSDSADJKSHDKL JKSAHD JHJADHASD
ASDHASJDHKJASDHASKJDHAS printf(“C”);
DASDJÑASKLDJAKSLDJÑALSKDJÑASKLDJASKDJAKSDJÑALSD
ASDÑKASDJÑLKASDJÑASKDJ
sadkjadsÑKLjdsadkalsdjñlaskjdñaskldjñalS printf(“D”);
ASDKJÑDKLJasñkdljsñkdjasñkld
askljd ska ids ajdk sdjsakdñad }
bash$ gcc code.c -o code bash$ ./code AB Segmentation fault. bash$
¿Dónde está el fallo?
Entre A y B Entre B y C
Entre C y D Ninguna es correcta
int mi_funcion(int *array, char *array2) { printf(“A”);
asdasdasds adSD SDsd asdas dsad printf(“B”);
ASDHASJDHKJASDHASKJDHAS printf(“C”);
sadkjadsÑKLjdsadkalsdjñlaskjdñaskldjñalS printf(“D”);
askljd ska ids ajdk sdjsakdñad }
bash$ gcc code.c -o code bash$ ./code AB Segmentation fault. bash$
¿Dónde está el fallo?
Entre C y D Ninguna es correcta
int mi_funcion(int *array, char *array2) { printf(“A”);
asdasdasds adSD SDsd asdas dsad printf(“B”);
ASDHASJDHKJASDHASKJDHAS printf(“C”);
sadkjadsÑKLjdsadkalsdjñlaskjdñaskldjñalS printf(“D”);
askljd ska ids ajdk sdjsakdñad }
bash$ gcc code.c -o code bash$ ./code AB Segmentation fault. bash$
¿Dónde está el fallo?
Ninguna es correcta
int mi_funcion(int *array, char *array2) { printf(“A”);
asdasdasds adSD SDsd asdas dsad printf(“B”);
ASDHASJDHKJASDHASKJDHAS printf(“C”);
sadkjadsÑKLjdsadkalsdjñlaskjdñaskldjñalS printf(“D”);
askljd ska ids ajdk sdjsakdñad }
printf usa el canal stdoutint mi_funcion(int *array, char *array2) { printf(“A”);
asdasdasds adSD SDsd asdas dsad printf(“B”);
ASDHASJDHKJASDHASKJDHAS printf(“C”);
sadkjadsÑKLjdsadkalsdjñlaskjdñaskldjñalS printf(“D”);
askljd ska ids ajdk sdjsakdñad }
Buffer
Consola
printf usa el canal stdoutint mi_funcion(int *array, char *array2) { printf(“A”);
asdasdasds adSD SDsd asdas dsad printf(“B”);
ASDHASJDHKJASDHASKJDHAS printf(“C”);
sadkjadsÑKLjdsadkalsdjñlaskjdñaskldjñalS printf(“D”);
askljd ska ids ajdk sdjsakdñad }
Buffer
Consola
A
printf usa el canal stdoutint mi_funcion(int *array, char *array2) { printf(“A”);
asdasdasds adSD SDsd asdas dsad printf(“B”);
ASDHASJDHKJASDHASKJDHAS printf(“C”);
sadkjadsÑKLjdsadkalsdjñlaskjdñaskldjñalS printf(“D”);
askljd ska ids ajdk sdjsakdñad }
Buffer
Consola
A B
printf usa el canal stdoutint mi_funcion(int *array, char *array2) { printf(“A”);
asdasdasds adSD SDsd asdas dsad printf(“B”);
ASDHASJDHKJASDHASKJDHAS printf(“C”);
sadkjadsÑKLjdsadkalsdjñlaskjdñaskldjñalS printf(“D”);
askljd ska ids ajdk sdjsakdñad }
Buffer
Consola
A B
printf usa el canal stdoutint mi_funcion(int *array, char *array2) { printf(“A”);
asdasdasds adSD SDsd asdas dsad printf(“B”);
ASDHASJDHKJASDHASKJDHAS printf(“C”);
sadkjadsÑKLjdsadkalsdjñlaskjdñaskldjñalS printf(“D”);
askljd ska ids ajdk sdjsakdñad }
Buffer
ConsolaAB
printf usa el canal stdoutint mi_funcion(int *array, char *array2) { printf(“A”);
asdasdasds adSD SDsd asdas dsad printf(“B”);
ASDHASJDHKJASDHASKJDHAS printf(“C”);
sadkjadsÑKLjdsadkalsdjñlaskjdñaskldjñalS printf(“D”);
askljd ska ids ajdk sdjsakdñad }
Buffer
ConsolaAB
C
printf usa el canal stdoutint mi_funcion(int *array, char *array2) { printf(“A”);
asdasdasds adSD SDsd asdas dsad printf(“B”);
ASDHASJDHKJASDHASKJDHAS printf(“C”);
sadkjadsÑKLjdsadkalsdjñlaskjdñaskldjñalS printf(“D”);
askljd ska ids ajdk sdjsakdñad }
Buffer
ConsolaAB
C D
printf usa el canal stdoutint mi_funcion(int *array, char *array2) { printf(“A”);
asdasdasds adSD SDsd asdas dsad printf(“B”);
ASDHASJDHKJASDHASKJDHAS printf(“C”);
sadkjadsÑKLjdsadkalsdjñlaskjdñaskldjñalS printf(“D”);
askljd ska ids ajdk sdjsakdñad }
Buffer
ConsolaAB
C D
printf usa el canal stdoutint mi_funcion(int *array, char *array2) { printf(“A”);
asdasdasds adSD SDsd asdas dsad printf(“B”);
ASDHASJDHKJASDHASKJDHAS printf(“C”);
sadkjadsÑKLjdsadkalsdjñlaskjdñaskldjñalS printf(“D”);
askljd ska ids ajdk sdjsakdñad }
Buffer
ConsolaAB
C D
printf usa el canal stdoutint mi_funcion(int *array, char *array2) { printf(“A”);
asdasdasds adSD SDsd asdas dsad printf(“B”);
ASDHASJDHKJASDHASKJDHAS printf(“C”);
sadkjadsÑKLjdsadkalsdjñlaskjdñaskldjñalS printf(“D”);
askljd ska ids ajdk sdjsakdñad }
Buffer
ConsolaABSegmentation fault.
Razones para no usar printf
1) No es una herramienta de depuración2) Nos obliga a ir probando para acotar el fallo
3) Nos puede engañar
Razones para no usar fprintf
1) No es una herramienta de depuración2) Nos obliga a ir probando para acotar el fallo
3) Nos puede engañar
#include <stdlib.h> #include <stdio.h>
int main (int argc, char* argv[]) { int *s = NULL; printf("A"); printf("B"); printf("%d", *s); printf("C"); printf("D"); return 0; }
bash$ gcc code.c -o code -gbash$ ./codeSegmentation fault.bash$ gdb code(gdb) runProgram received signal SIGSEGV, Segmentation fault.
bash$ gcc code.c -o code -gbash$ ./codeSegmentation fault.bash$ gdb code(gdb) runProgram received signal SIGSEGV, Segmentation fault.0x08048439 in main (argc=1, argv=0xffffd364) at code.c:9
bash$ gcc code.c -o code -gbash$ ./codeSegmentation fault.bash$ gdb code(gdb) runProgram received signal SIGSEGV, Segmentation fault.0x08048439 in main (argc=1, argv=0xffffd364) at code.c:99 printf("%d", *s);
Órdenes usuales- l, list ! Muestra las líneas de código - b, break ! Crea un breakpoint - d, delete ! Borra un breakpoint - clear ! Borra uno o varios breakpoints - info b ! Muestra la lista de breakpoints - c, continue ! Continúa la ejecución - n, next ! Ejecuta la siguiente línea - s, step ! Como next pero entra en subrutinas - display ! Muestra una expresión por parada - print ! Muestra una expresión - bt, where ! Muestra pila funciones (backtrace) - set ! Asigna un valor a una variable
¿Verdadero o Falso?
Verdadero Falso
int main(int argc, char const *argv[]) { if ( 0.1 + 0.2 == 0.3 ) { puts ("Verdadero"); } else { puts ("Falso"); }
return 0; }
Segmentation Fault Ninguna es correcta
¿Verdadero o Falso?
Falso
int main(int argc, char const *argv[]) { if ( 0.1 + 0.2 == 0.3 ) { puts ("Verdadero"); } else { puts ("Falso"); }
return 0; }
Consejos- Siempre inicializar las variables. SIEMPRE. int i = 0; for (i = 0; i < 10; i++);
- Usar calloc mejor que malloc. int *ptr = (int *) malloc (sizeof(int) * 15); int *ptr = (int ) calloc (15, sizeof(int));
Consejos- Código limpio, máximo 80 caracteres por linea.printf(“%s %s %s”, game->player[1]->score, game->player[1]->highscore, game->player[1]->name);printf(“%s %s %s”, game->player[1]->score, game->player[1]->highscore, game->player[1]->name ); - En las comparaciones, las constantes primeroif (variable = 6) {} // Compila if (6 = variable) {} // No compila if (6 == variable) {} // Correcto