Categories
Uncategorized

Moving + new post

I’m moving to http://slackito.com, please update your RSS reader settings :). This is my last post here, although the current contents will stay where they are, so I won’t be broking links through the interwebs. Also, after more than a year of silence I have written a new post: Automatic memoization in C++0x. Happy hacking!

Categories
Code Demoscene Stories

ResaCON 2009

Todo surgió de esta idea:

Con lo interesantes que se ponen las conversaciones a veces cuando nos vamos de cena, ¿por qué no montamos una con y nos contamos las cosas que hacemos como $DEITY manda?

Después de un periodo de incertidumbre y de apurar un poco con las fechas (una deadline es una deadline al fin y al cabo), el pasado fin de semana tuvo lugar la ResaCON 2009: once amigos y yo, cada uno con una presentación bajo el brazo, una pantalla grande, una nevera con refrescos y algo para picar. El resultado fue espectacular: se habló de gráficos, IA, emulación, videojuegos, lenguajes de programación, robotitos, proyectos personales varios, silverlight, profiling y hasta de creación de empresas… todo ello en un ambiente familiar y distendido.

Por supuesto luego hubo tiempo para irnos de cena y de fiesta :D

En definitiva, he disfrutado de lo lindo y espero que repitamos el año que viene (¡muchas gracias a todos, moláis un gritón!) . En los próximos días subiré a algún sitio las presentaciones que me dejen subir, permanezcan en sintonía. De momento os dejo con un enlace a mi presentación de introducción a Clojure.

Categories
Tools

Shell tip: getting a canonical absolute path from a relative path

$ readlink -f relative/path

Gives a full path equivalent to the relative path, and follows every symlink in every component of the name in order to canonicalize it.

Categories
Tools

Useful aliases

alias top = htop

Htop is a top replacement, with colors, per-cpu load indicators, scrolling (specially horizontal scrolling so you can see the whole command line for each process), searching, a nicer interface to kill/renice processes, mouse support, and the ability to call strace/ltrace/lsof easily on the process you want.

alias info = pinfo
alias man  = pinfo -m

Pinfo is a lynx-style info and man browser. The main reason to use this, IMHO, is that GNU Info simply sucks as a browser. I’m not so sure about replacing man, as I’m confortable with less-style keybindings, but the ability to follow links to related manpages is a great feature :D

Both are included in all popular distros, so installation is only a matter of looking for the packages in the distro repositories.

Categories
Code Tools

Valgrind: tracking the origin of undefined values

Today I was wondering if one of those warnings about uninitialized values was located in library code or in my own code, and I noticed a new message in Valgrind’s output:

Use –track-origins=yes to see where uninitialised values come from

This feature was first added to Valgrind 3.4.0 back in January, and it’s great! I wish I had known it before, because it would have spent me a few headaches in the past months, so I decided to write it here just in case I can help someone :)

Categories
Tools

Bash tip

Sometimes we have to do something like this:

$ generate_things > tmp1
$ generate_other_things > tmp2
$ process_both tmp1 tmp2

With bash, it’s possible to avoid creating these temporary files:

$ process_both <(generate_things) <(generate_other_things)

:)

Categories
Code

crash handling

Estaba yo preguntándome esta tarde si sería posible lanzar de forma automática gdb cuando un programa cascara, sin necesidad de ponerse a depurar después, reproducir el bug, etc, al estilo del manejador de errores que instala Visual Studio en Windows que pregunta si se desea depurar la aplicación.

Me ha salido algo como esto (HTML horrible para el coloreado de sintaxis patrocinado por Vim):

#include <sys/types.h>
#include <unistd.h>
#include <signal.h>
#include <stdio.h>
#include <stdlib.h>

void attach_gdb(int signum)
{
    pid_t gdbpid;
    pid_t debuggee_pid = getpid();
    int gdb_exit_status;
    char pidbuf[100];
    char exebuf[100]; // should be safe unless PIDs reach ~90 digits ;P
    sprintf(pidbuf, "%d", debuggee_pid);
    sprintf(exebuf, "/proc/%d/exe", debuggee_pid);
    printf("Signal %d received. Attaching GDB to process. PID=%d\n", signum, debuggee_pid);

    if ((gdbpid = fork()) == 0)
    {
        execlp("gdb", "gdb", exebuf, pidbuf, NULL);
        perror("execlp");
        exit(1);
    }

    waitpid(gdbpid, &gdb_exit_status, 0); // hold on, we want to be debugged
    exit(1);
}

void __attribute__((constructor)) setup_handler()
{
    struct sigaction sa, old_sa;
    sa.sa_handler = attach_gdb;
    sigemptyset(&sa.sa_mask);
    sa.sa_flags=0;
    // Register the handler for all actions which dump core by default
    sigaction(SIGSEGV, &sa, &old_sa);
    sigaction(SIGFPE, &sa, &old_sa);
    sigaction(SIGABRT, &sa, &old_sa);
    sigaction(SIGILL, &sa, &old_sa);
    sigaction(SIGQUIT, &sa, &old_sa);
}

Si se compila como librería dinámica y se enlaza a cualquiera de nuestros programas (o se precarga con LD_PRELOAD) lanza un gdb asociado al proceso al recibir cualquiera de las señales que causarían un core dump y terminación del programa :D.

¿Alguna idea para mejorarlo y que sea práctico? ¿Existe ya algo asi en un paquete Debian que hace mil cosas molonas más? (seguro que sí XD).

Categories
Code wenboi

Jugando con Qt

El otro dí­a me encontré con edb (una especie de OllyDbg para linux) y al ver la buena pinta que tenía me acordé de lo bonito que sería tener una interfaz gráfica para depurar en mi emulador de GameBoy. Me he puesto a juguetear con Qt y me está gustando. Está muy bien documentada y es bastante agradable de usar, una vez se pasa el susto de ver esas cosas raras como “public slots:” en mitad de la declaración de una clase en C++.

De momento he conseguido integrar el emu en una ventana de Qt, el redibujado va bastante más rápido de lo que me esperaba, y tengo el emulador en un hilo y la parte gráfica en otro. Ahora me falta empezar de verdad con el debugger. Ahi va un shot :)

qtboi screenshot

Categories
Code wenboi

wenboi

Llevo algún tiempo escribiendo a ratos un emulador de Game Boy. Me picaba el tema de la emulación y shash me había comentado que la Game Boy era facililla de emular y me pasó algo de documentación. Pues bien, ha llegado el momento de que vea la luz. Con todos ustedes… wenboi!

wenboi screenshot

Todavía está en pañales pero ya se puede empezar una partida de Tetris y colocar piezas, y es éste el hito que me ha llevado a poner la etiqueta de “version 0.1” y hablar un poquito del emulador aquí ;)

Por si alguien quiere cotillear, he creado una pequeña homepage de wenboi con información sobre el acceso al repositorio de Git y tambien he dado de alta a wenboi en Ohloh para que me analicen el repositorio, me saquen graficos de actividad y me digan que pongo pocos comentarios en el código. También hay un pequeño devlog que no sé si actualizaré demasiado.

Happy hacking!

Categories
Code

ctypes

El otro día me encontré con un módulo interesante de python que no conocía: ctypes. Sirve para comunicarse con librerías en C: permite cargar librerías dinámicas y llamar a sus funciones, definir tipos equivalentes a los de C para pasarlos de un lado a otro e incluso especificar funciones python como callbacks de C. Vamos, que se pueden crear bindings a librerías externas escribiendo únicamente código python.

Ahi va un ejemplillo tonto usando la libavformat:

#!/usr/bin/python
import sys
from ctypes import *
import ctypes.util

av = CDLL(ctypes.util.find_library("avformat"))
filename = sys.argv[1]
# pFormatCtx deberia ser un puntero a AVFormatContext, 
# pero esto es solo un ejemplo simple :)
pFormatCtx = c_void_p() 

av.av_register_all()
av.av_open_input_file(byref(pFormatCtx), filename, None, 0, None)
av.dump_format(pFormatCtx, 0, filename, 0)

Por supuesto para hacer algo más serio habría que declarar en python las estructuras como AVFormatContext que se definen en las cabeceras correspondientes y cosas así, pero entonces el programa de ejemplo sería demasiado engorroso como para leerlo en un blog ;). El ejemplo muestra una salida como esta:

$ ./av.py test.avi 
Input #0, avi, from 'test.avi':
  Duration: N/A, bitrate: N/A
  Stream #0.0: Video: mpeg4, 512x420,   inf fps(c)
  Stream #0.1: Audio: vorbis, 22050 Hz, stereo, 24 kb/s

Referencias: