6.3 KiB
6.3 KiB
Chuleta de comandos
Comandos que hemos usado, agrupados por tarea. Los flags del proyecto son
-std=c17 -Wall -Wextra -Wpedantic -g.
Compilar paso a paso
| Comando | Qué hace |
|---|---|
gcc -E -Iinclude src/escpos.c -o build/escpos.i |
Solo preprocesa. Genera el .i: C con los .h pegados. |
gcc -S ... |
Para después de compilar. Genera el .s (ensamblador). |
gcc <flags> -Iinclude -c src/escpos.c -o build/escpos.o |
Compila hasta el .o (fichero objeto), sin enlazar. |
gcc <flags> -c build/escpos.i -o build/escpos.o |
Compila partiendo de un .i. No hace falta -I. |
gcc <flags> -Iinclude -save-temps -c src/escpos.c |
Cadena completa, conservando .i, .s y .o. |
gcc build/hello.o build/escpos.o -o build/hello |
Enlaza los .o en un ejecutable. |
./build/hello |
Ejecuta un programa de la carpeta actual. |
Si juntas dos flags de parada (-E -S), gana la que para antes.
Inspeccionar ficheros
| Comando | Qué hace |
|---|---|
nm build/hello.o |
Lista símbolos: T definido y visible, t definido y static, U usado pero definido en otro sitio. |
wc -l fichero |
Cuenta líneas (por ejemplo, para comparar .c y .i). |
ls -l build/ |
Muestra la fecha de modificación: sirve para ver qué .o está obsoleto. |
file fichero |
Dice qué es: ELF (Linux), COFF o PE (Windows)... |
strings fichero.o |
Muestra las cadenas legibles que hay dentro de un binario. |
objdump -d fichero.o |
Desensambla el código máquina. |
objdump --dwarf=info fichero.o |
Muestra la información de depuración que añade -g. |
xxd fichero.bin |
Volcado hexadecimal (para revisar los bytes ESC/POS). |
tail -c 5 fichero | xxd |
Muestra los últimos bytes: sirve para ver si el fichero acaba en 0a (\n). |
echo $? |
Código de salida del último comando: 0 es éxito. |
Memoria
| Comando | Qué hace |
|---|---|
valgrind ./build/hello |
Sin --leak-check: errores de acceso (Invalid write, Invalid free) y de dónde viene cada dirección. |
valgrind --leak-check=full ./build/hello |
Ejecuta vigilando la memoria: fugas, use after free, lecturas sin inicializar. Solo Linux. |
cat /proc/self/maps |
Mapa de memoria virtual del proceso: código, [heap], [stack], librerías. Con <pid> en vez de self, el de otro proceso. |
journalctl -k | grep -i "out of memory" |
Ver si el OOM killer del núcleo ha matado algún proceso. |
pgrep -a nombre |
Lista los procesos cuyo nombre contiene nombre, con su PID y su línea de comandos. |
pgrep -o nombre |
PID del proceso más antiguo con ese nombre (normalmente el principal). |
grep -E 'VmSize|VmRSS' /proc/<pid>/status |
Memoria virtual reservada (VmSize) frente a RAM física en uso (VmRSS). |
grep -E 'heap|stack' /proc/<pid>/maps |
Rangos de direcciones del montón y de la pila de un proceso. |
pmap -x <pid> |
Mapa de memoria con tamaño virtual y residente de cada zona. |
ulimit -s |
Tamaño máximo de la pila en KB (8192 = 8 MB). |
go build -gcflags=-m |
(Go) Muestra qué variables escapan al montón. |
Depurar
| Comando | Qué hace |
|---|---|
gdb ./build/hello |
Abre el programa en el depurador (hace falta -g). |
run / bt / print x |
Dentro de gdb: ejecutar, ver la pila de llamadas, ver una variable. |
break f.c:42 / next / step / continue |
Dentro de gdb: punto de parada, siguiente línea, entrar en la función, seguir. |
Solo en Windows (MSYS2)
| Comando | Qué hace |
|---|---|
objdump -p hello.exe | grep "DLL Name" |
Lista las DLL de las que depende el ejecutable. |
strip hello.exe |
Quita símbolos e información de depuración. |
gcc -static ... |
Enlaza estáticamente todas las librerías posibles. |
Make
| Comando | Qué hace |
|---|---|
make |
Construye el primer objetivo del Makefile. |
make build/escpos.o |
Construye un objetivo concreto. |
make CC=clang |
Sobrescribe una variable del Makefile para esta ejecución. No recompila lo que ya está al día. |
make clean |
Borra lo generado (si el Makefile tiene esa regla y está en .PHONY). |
touch fichero |
Actualiza la fecha del fichero sin cambiar su contenido. Make lo verá como modificado. |
cat -A Makefile |
Muestra los caracteres invisibles: ^I es un tabulador y $ es el fin de línea. |
Errores típicos y qué significan
| Mensaje | Quién lo da | Causa |
|---|---|---|
fichero.c:línea:col: error: |
Compilador | Error en el código fuente. |
undefined reference to 'x' |
Enlazador (ld, collect2) |
Un U sin ninguna T: falta pasar un .o o una librería. |
multiple definition of 'x' |
Enlazador | Dos T con el mismo nombre. A menudo, un cuerpo de función en un .h. |
missing separator |
Make | La receta empieza por espacios en vez de tabulador. |
'x' is up to date |
Make | No es un error: el objetivo es más nuevo que todos sus prerrequisitos. Si x es una acción (clean), falta en .PHONY. |
no newline at end of file |
Clang | El fichero no termina en \n. |
unknown type name 'uint8_t' / identifier ... is undefined |
Compilador / VS Code | Falta el #include que declara ese tipo (<stdint.h>, <stddef.h>...). |
makes integer from pointer without a cast |
Compilador | Se pasa una dirección (puntero) donde se espera un número. Por ejemplo, "A" en vez de 'A'. |
pointer targets ... differ in signedness |
Compilador | Se mezclan char * y uint8_t * (unsigned char *). |
Segmentation fault (core dumped) (código 139) |
Núcleo | Acceso a una dirección no mapeada; casi siempre un puntero NULL. Usa gdb. |
free(): invalid pointer / Aborted (código 134) |
glibc | free de algo que no dio malloc: dirección de la pila (&x), literal, interior de un bloque o double free. Usa Valgrind. |
comparison of constant -1 with expression of type 'uint8_t' is always false |
Clang / VS Code | Comparas un tipo sin signo con un negativo: nunca puede ser igual. Revisa el tipo. |
useless storage class specifier in empty declaration |
Compilador | Un typedef sin nombre nuevo al final. |
Go equivalente
| Go | C |
|---|---|
go build -x |
Ver los comandos que se ejecutan por dentro. |
go build -work |
Conservar los intermedios (como -save-temps). |
go build -ldflags="-s -w" |
Quitar símbolos (como strip). |