Ya he logrado dominar el mundo

Ya está. Ya podeis dejar de hacer lo que estabais haciendo. ¿Tratando de dominar el mundo antes que yo? Mala suerte. Ya he terminado. He logrado dominar el mundo hasta un punto que ya es irreversible. No os trastorneis, ni penseis en ello. Simplemente adorad a vuestro nuevo líder.

Piramide

Quiero agradecer a todos aquellos que han hecho posible mi dominio. En especial a los illuminati, a la cienciología (ahora se llama Scientology™), a los programas de telebasura (bueno, en realidad a la televisión general puesto que TELEVISIÓN EN EL MUNDO = TELEBASURA GLOBAL), a la gente que da opiniones sin informarse antes (hay que majos son, que tierna es su manipulación), a las diversas sectas de nuestro bonito panorama internacional, a los aburridos (muy aburridos estaban), a los habitantes de Isla Malvada y por supuesto a mi kit de Dominium mundi, que le faltaban piezas (concretamente el Santo Grial, reclamé a los templarios pero no hicieron ni caso “No, nosotros no sabemos. Lo andábamos buscando también, fíjate que casualidad”).

Mundo

No voy a negarlo, me ha sido muy fácil dominar el mundo, tomar el control de todas las cosas y personas del orbe para poder ejercer poder y tiranía sin límites. Mi plan era absurdo pero eso lo comentaré otro día.

DominarMundo

Ahora voy a empezar a aplicar mi poder. Algunas ideas que tengo son:

  • Hacer una ola con todas las personas de la Tierra. Tengo mis dudas si en el hemisferio sur y debido al efecto Coriolis las personas girarán sus brazos en sentido opuesto.
  • Registrar los silbidos y cobrar un canon
  • Quitarles los caramelos a los niños
  • Instaurar el culto a 42
  • Inventarme un mito tipo La Eneida o Gilgamesh, donde yo soy el héroe supremo
  • Hacer un pacto con los delfines, a fin de poner límites a los imperios. Ellos el agua, yo la superficie
  • Introducirme en la organización de los Anunaki e ir escalando puestos socialmente poco a poco.
  • Añadir una sustancia de control mental en la vacuna de la gripe, y si no funciona, reeducacioncilla (si, al estilo Ned Flanders)
  • Publicar en una página web todas las cosas tiránicas que hago a modo de denuncia. Seré a la vez tirano y salvador. Pero usaré un pseudónimo guay tipo Sr. X
  • Ir al pasado y matarme para así evitar la destrucción del mundo, pero no podré ir al pasado por las paradojas de “¿cómo llegaste al pasado para matarte, jovencito? ¿no estarías ya muerto y en ese caso no podrías haber ido al pasado a asesinarte?”.

DominarMundo-2

¿Sabías qué…

… la mayoría de los que han intentado dominar el mundo han fracasado?

… yo no?

… feliz día de los Santos Inocentes, aunque si te lo estabas creyendo quizá te habías tomado drogas de más?

Patos

El pájaro que nunca deja de beber

No sé si alguien se acuerda de las dos apariciones estelares en Los Simpsons de un cacharro, con forma de pájaro, que bebe todo el agua. Como si tuviera el movimiento perpetuo.

Hace poco me encontré en una feria con el dichoso pájaro y no me pude resistir. ¡Me lo compré!

Mi primer debug. Primeros pasos con gdb, Valgrind y strace.

¿A quién no le ha pasado? Estas programando en C++ y de repente cuando antes todo iba bien, ahora el programa se cierra inesperadamente (un crash) y no sabes el motivo. En algunos lenguajes como Rust, el propio compilador y el lenguaje evitan estas situaciones, pero en C++ la situación es mucho más estimulante.

Recientemente, trabajando en Kovel tuve uno de estos incidentes inesperados. Pero más inesperada fue su aparición, pues en Debian, donde programo actualmente, el programa se ejecutaba normalmente. Sin embargo en Windows el programa no llegaba a arrancar. Pensé que sería una diferencia Linux-Windows pero al probar en Fedora ocurrió lo mismo que en Windows, no llegaba a arrancar. Si encontraba el fallo en Fedora, que no se daba en Debian, resolvería también el fallo en Windows.

Preparando la aplicación y el entorno

Símbolos de depuración

Aunque no es obligatorio, es recomedable compilar los ejecutables que vayamos a someter a depuración con símbolos de depuración. En Windows se usan archivos independientes (ficheros PDB) mientras que en Linux se usan los mismos ejecutables con más metadatos en su interior. En GCC simplemente hay que añadir la opción -g para retener los datos de depuración.

Ficheros core

Ahora sería conveniente activar la generación de los ficheros core en el sistema. En algunas distro ya está activado:

Los ficheros core los usaremos si nuestra aplicación se paró en un punto de difícil acceso o que no podemos recrear nosotros mismos.

Instalar gdb, Valgrind y los símbolos de las librerías

Ahora vamos a instalar el componente más importante, el debugger, la aplicación que usaremos para analizar la ejecución del programa.

gdb

Además querremos tener los símbolos de depuración de las bibliotecas que use nuestro ejecutable. Con DNF, en Fedora, el proceso usa un comando específico:

Y si queremos mantener los símbolos de depuración actualizados:

Vamos a usar Valgrind también, aunque menos

Cazando al vuelo

Supongamos que sabemos como generar el error. Llamamos a nuestro programa desde gdb:

Entraremos en gdb, con su propios comandos de herramientas. Lo primero que haremos será iniciar el programa, con el comando run o r

El programa se iniciará. Nosotros provocaremos el error. Una vez lo hayamos provocado podremos introducir más comandos. Vamos a ver que pasos se han seguido para producir el error.

Y desde aquí podemos inspeccionar que funciones fueron llamadas justo antes de que el programa petase. En este punto también podemos buscar el valor de ciertas variables que nos interesen con p nombrevariable.

Volviendo al pasado

No sabemos como se produjo el error, pero tenemos un fichero core que nos va a permitir restablecer la situación del pasado para poder analizarla. Llamamos a gdb con el fichero core y nuestra aplicación.

Una vez dentro podemos dirigirnos al punto crítico.

Y analizamos como antes.

Valgrind y fugas de memoria

Valgrind es muy usado para comprobar en que partes nuestro programa tiene fugas de memoria. En determinados casos puede ser más útil que gdb.

Nuestro programa se ejecutará aproximadamente 20 o 30 veces más lento, pero se nos informará en todo momento de la gestión errónea de memoria que está produciéndose. En alguna situación será interesante saber de donde provienen estos fallos con mayor precisión, la opción –track-origins=yes es nuestra amiga.

Valgrind es muy estricto y puede generar falsos positivos. Hay varias GUI disponibles para Valgrind, una de ellas es KCacheGrind.

KCacheGrind

Otra de ellas es Valkyrie

Valkyrie

¿Y si algún fichero no existe?

Para terminar vamos a suponer que nuestro programa falla porque hay un archivo que no logra encontrar y no puede abrirlo. Gracias a strace es posible saber que archivos está abriendo el programa.

Y nos saldrá en tiempo real los archivos que ha abierto nuestro programa.

Strace

Y espero que con este pequeño resumen ya sepais que hacer cuando vuestro programa se cierra inesperadamente.

Emulando a Linus Torvalds: Crea tu propio sistema operativo desde 0 (VIII)

Este artículo lo escribí para el blog en español DesdeLinux el 23 de diciembre de 2014 y ahora lo dejo aquí, en mi blog personal. El artículo está tal cual, sin ninguna modificación desde aquella fecha.

Volvemos a la serie de tutoriales sobre como crear nuestro propio sistema operativo. Supongo que este capítulo os gustará mucho porque por fin podremos interactuar con nuestro sistema operativo. Hoy leeremos la entrada del teclado. Para ello el esquema es similar al del timer. Tenemos que usar los IRQ igualmente así que empezaremos igual que con el timer.

Nuestro handler de teclado sin embargo es algo más complejo ya que vamos leyendo las teclas y las vamos depositando en un buffer.

Podemos comprobar como llamamos a una función llamada ND::Keyboard::GetChar. Allí obtenemos el caracter y después si no es un caracter vacío (aquí he usado 255, habría que usar un sistema mejor) ponemos el caracter en pantalla y lo almacenamos en un buffer simple de chars (esto también es susceptible de mejora, el sistema actual puede desbordarse).

Aquí podemos ver como se obtiene la tecla que ha sido pulsada. En 0x60 siempre va a estar la última tecla pulsada. De hecho se puede leer directamente sin tener que usar el IRQ, pero entonces no sabremos indentificar cuando se ha producido un cambio. Allí comprobamos con la operación AND que el código de obtuvimos corresponde a una tecla que se ha dejado de pulsar.

En ese caso devolvemos 255 (porque luego lo ignoraremos) y en caso contrario la tecla ha sido pulsada. En ese caso devolvemos la posición de un array llamado enUS. ¿Qué información contiene este array? Este array es lo que llamaríamos un keymap o un mapa de caracteres. Como sabrán diferentes idiomas tienen diferentes teclados y no son compatibles ya que sobreescriben las teclas. Así enUS nos dará la tecla correspondiente a cada código y funcionará en un teclado americano.

También había una función definida que obtenía una frase. El propósito es simplemente obtener acceso más fácilmente a los strings desde las aplicaciones que lo necesiten, de momento solo una. Hablo de NextShellLite, una versión reducida del posible futuro shell que tendría NextDivel. El propósito de NextShellLite es únicamente el de proveer de un shell reducido para ir probando poco a poco nuevas funcionalidades. No voy a poner el código del shell aquí pero lo he incluido dentro del código de NextDivel.

De momento no funciona como un programa aparte sino como una función que llama el kernel, principalmente porque todavía no añadimos la opción de ejecutar ejecutables. Y claro, unas imágenes de como funciona el shell con las nuevas funciones de entrada de teclado.

NextShellLite

Emulando a Linus Torvalds: Crea tu propio sistema operativo desde 0 (VII)

Este artículo lo escribí para el blog en español DesdeLinux el 25 de agosto de 2014 y ahora lo dejo aquí, en mi blog personal. El artículo está tal cual, sin ninguna modificación desde aquella fecha.

Bienvenidos a otro post sobre cómo crear nuestro propio sistema operativo. Ha pasado mucho tiempo desde el último post, debido principalmente a un bug que encontré en lo que nos toca hoy. Veremos cómo manejar el reloj en arquitecturas x86.

Anteriormente habíamos activado los IRQ de manera genérica, pero hubo un pequeño problema ya que no los activábamos correctamente y pasábamos datos extra. Finalmente lo solucionamos carlosorta y yo y os puedo seguir comentando cómo seguir.

Bien, el reloj es un IRQ, concretamente el primero. Para configurarlo usaremos la función que definimos anteriormente para instalar de manera genérica los IRQ, la NDIRQInstallHandler.

El código se ejecuta de la siguiente manera: el sistema de inicialización llama a ND::Timer::Setup, que llama a NDIRQInstallHandler para insertar en la primera posición, el IRQ0, una función de callback cuando el evento se produzca, esa es NDTimerHandler que aumenta los ticks. Como hemos puesto la velocidad del reloj a 18 Hz, como veremos más adelante, si lo dividiésemos entre 18 y nos diese entero habría pasado un segundo.

La función ND::Timer::Phase nos sirve para ajustar la velocidad del timer, ese número tan extravagante es 1.19 MHz que es un valor común. Bien, esta función la deberemos llamar si quisiésemos cambiar la velocidad del timer, por defecto va a 18,22 Hz, un valor peculiar que debió de decidir alguien dentro de IBM y se ha quedado hasta nuestros días.

La función ND::Timer::Wait es bastante simple, solamente espera con un bucle while hasta que se hayan alcanzado los ticks necesarios para continuar.

En la imagen podemos comprobar que si descomentamos el código dentro del NDTimerHandler obtenemos esto:

NextDivelSegundos