Files
2026-10-07 03:45:29 +02:00

123 lines
7.7 KiB
Markdown

# 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`). |
| `man 3 memcpy` | Documentación de una función de la librería de C: cabecera, firma y comportamiento. `man 2` para llamadas al sistema. |
| `echo \| gcc -std=c17 -dM -E - \| grep __STDC_VERSION__` | Qué versión del estándar de C usa el compilador: `201710L` es C17, `202311L` es C23. |
| `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. |
| `Ctrl+C` (dentro de gdb, con el programa en marcha) | Detiene el programa donde esté. Para encontrar bucles infinitos. |
| `break f.c:42` / `next` / `step` / `continue` | Dentro de gdb: punto de parada, siguiente línea, entrar en la función, seguir. |
| `p &x` / `p *p` / `p/x *p@n` | Dentro de gdb: dirección de `x`, lo que hay en la dirección de `p`, y `n` elementos seguidos desde `p` en hexadecimal. |
| `info proc mappings` | Dentro de gdb: mapa de memoria del proceso (`[heap]`, `[stack]`, librerías). Dice en qué zona cae una dirección. |
### VS Code
| Atajo | Qué hace |
|---|---|
| F5 | Compila con `make` y depura `build/hello` |
| F9 o clic junto al número de línea | Punto de parada |
| F10 / F11 / Shift+F11 | Siguiente línea / entrar en la función / salir de la función |
| Ctrl+Shift+B | `make` |
| *Terminal → Run Task* | `make clean`, `make (clang)`, `valgrind` |
| `*buffer->data@10` en *Watch* | Ver los 10 primeros bytes de un puntero |
## 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. |
| `uname -s` | Nombre del sistema: `Linux` en Fedora, `UCRT64_NT-...` en la terminal UCRT64 de Windows. |
| `echo $MSYSTEM` | Entorno de MSYS2 activo. Tiene que ser `UCRT64`. |
| `pacman -S mingw-w64-ucrt-x86_64-clang` | Instala clang para el entorno UCRT64. |
| `pacman -S vim` | Instala `xxd` (viene con vim). Sin él, usa `hexdump -C fichero.bin`. |
## 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`). |