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!
Author: slack
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.
$ 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.
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.
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 :)
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)
:)
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).
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 :)
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!
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!
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: