Depurar código con gdb


> gdb programa

# especificar los argumentos del programa
run argumentos

# se pueden especificar puntos de parada usando fichero y linea,
# el nombre de una funcion, o clase y método
break fichero.c:linea
break nombre_funcion
break clase::metodo

# listado de puntos de parada
info breakpoints

# eliminar punto de parada X
delete breakpoint X
# eliminar todos
delete breakpoints

watch
awatch 

# Inspeccionar variables
display variable
print variable

# mostrar codigo fuente "alrededor" de la línea en ejecución
list 

# Control de ejecución
# siguiente linea, sin entrar en la llamada (atajo: "n")
next
# siguiente, entrando dentro de la llamada (atajo: "s")
step
# proseguir (atajo: "c")
continue

# Imprimir la pila de llamadas (atajo: "bt")
backtrace

#Recorrer la pila de llamadas
up

# gdb también permite "tracear" el código, con los "tracepoint commands"

Depurar codigo Java JNI en Linux

Depurar una mezcla de código Java y C++ no es trivial, sobre todo porque aún no hay disponibles entornos (o plugins) estables que soporten esta posibilidad. Con lo cual hay que recurrir a la siguiente receta, que permite interactuar a la vez con los depuradores nativos de cada lenguaje (sean para consola como gdb, o gráficos como NetBeans)

Primero iniciar el programa en modo de depuración remota:

java -Xdebug -Xnoagent -Djava.compiler=none -Xrunjdwp:transport=dt_socket,server=y,suspend=y -Djava.library.path=$LD_LIBRARY_PATH -cp . -jar PROG.jar
Listening for transport dt_socket at address: 37112

Es importante definir java.library.path para que contenga el directorio donde se encuentra la biblioteca .so con el código nativo (en este caso, se le asigna el valor de la variable de entorno LD_LIBRARY_PATH).

Iniciar el depurador de Java y conectarse al puerto indicado por el comando anterior (en el ejemplo, 37112)

jdb -attach 37112

También se puede utilizar un depurador gráfico, por ejemplo el que viene con Eclipse. Para ello basta crear un perfil de depuración de tipo “Remote Java Application”. En Connection Properties usar localhost y como puerto el que nos devolvio el anterior comando java (siguiendo con el ejemplo, 37112)

Establecer el punto de parada en el código Java

stop at CLASE:NUM_LINEA
run

Una vez alcanzado el punto de parada en el código Java, iniciar el depurador de código nativo y vincularlo con el proceso java mediante su PID

gdb
attach PID
break JNI_FUNCTION

continue (retoma la ejecución del programa java)

Importante: para que el depurador C++ encuentre la función JNI, el programa Java debe tener ya cargada la biblioteca C++ (archivo .so). Si paramos la ejecución del programa Java demasiado pronto, cuando entremos en el gdb la biblioteca aún no se habrá cargado y por lo tanto al intentar el “break” se quejará de que no encuentra la función.

Estos tres comandos gdb también pueden ejecutarse dentro de ddd, lo cual nos permite depurar el código C++ con la comodidad de un entorno gráfico

Por último, de vuelta en jdb ejecutar run de nuevo (continua la ejecución en el depurador y se detiene en el breakpoint del código nativo definido en gdb)

Plugins WordPress interesantes

Para hacer copias de seguridad de la base de datos, WordPress Database Backup. Para limpiarla (“optimizarla”), WP-Optimize.

Para agilizar la carga de las páginas, WP Super Cache.

Para una integración en Facebook y Twitter: Facebook Open Graph, Google+ & Twitter Card Tags o WP Facebook Open Graph protocol.

SEO: All in One SEO Pack

Para mostrar código, SyntaxHighlighter Evolved.

Para incrustar fácilmente videos de Youtube (si no viene de serie), WP Youtube Lyte

Para “proteger” los cambios, Revision Control.

Para recibir alertas cuando se hacen cambios, Email Post Changes.

Para reducir el spam, WP-SpamShield.

Formularios: WP Forms Lite o Contact Form 7

Humildad y aprendizaje

En “Por qué soy el mejor programador del mundo” (ironicamente) Jeff Atwood resume las opiniones sobre la humildad que aparecen en “Code Complete 2.0”:

Los peores programadores son aquellos que se niegan a aceptar el hecho de que
sus cerebros no son iguales a la tarea.
Sus egos les impiden ser grandes programadores.
Cuanto más aprendas a compensar tu pequeño cerebro, mejor programador serás.
Cuanto más humilde seas, más rápido mejorarás.

Ya lo decía un Mestre:

Menino seja humilde
e louve ao seu camarada
quem diçer que tudo sabe
é porque não sabe nada

La humildad con sabor árabe:

Quien no sabe que no sabe, es un necio: aléjate de él.
Quien sabe que no sabe es humilde: enséñale.
Quien no sabe que sabe está dormido: despiértale.
Quien sabe que sabe se percata de cuánto le queda por saber, y continúa por la senda del aprendizaje.

Sabiduría china: “Quien le gusta aprender está cerca de saber”

Desde Dinamarca: “A quien teme preguntar le avegüenza aprender”

En la música popular: “Sólo de errores se aprende” (Alejandro Sanz). Variante italiana: “Por la ignorancia nos equivocamos y por las equivocaciones aprendemos”

Recuperar contactos iPhone

Al sincronizar con iTunes por defecto se hace una copia de seguridad automática de los datos del iPhone, incluyendo los contactos. Pero a veces ocurre que al restaurar esa copia de seguridad los contactos no se restablecen.

En esos casos no todo está perdido: se puede acceder a los contactos del backup siguiendo los siguientes pasos:

  • Abrir el fichero 31bb7ba8914766d4ba40d6dfb6113c8b614be442.mddata (que está dentro del backup que hace iTunes) con sqlite3
  • Configurar la salida de sqlite con los comandos “.header on”, “.mode csv” y “.output contactos.csv”
  • Ejecutar la siguiente consulta en sqlite: “select First, Last ,Organization, Department, Note, ABMultiValue.value from ABPerson, ABMultiValue where ABMultiValue.record_id = ABPerson.ROWID;”
  • Salir (“.quit”)

Con esto tendremos en el fichero contactos.csv un volcado de los contactos según se guardaron en el backup. A partir de aquí se puede procesar ese fichero para adaptarlo al formato de la herramienta que vayamos a usar para introducirlos de nuevo en el iPhone (Google Contacts, Address Book, Outlook…)

Como siempre, es mucho más sencillo hacer múltiples backups antes del desastre que intentar restaurar datos después del desastre. Por eso es conveniente habilitar la sincronización de los contactos con algún programa externo (nuevamente Outlook, Address Book, Google Contacts o similares) y hacer copias de seguridad tanto del iPhone como de los datos de esos programas extrernos (Google Contacts permite exportar los contactos en formato csv y vcal)

Configuración interfaces de red en Debian

# The loopback network interface
auto lo
iface lo inet loopback

# interfaz principal
auto eth0
iface eth0 inet dhcp

auto eth1
iface eth1 inet static
        address 192.168.33.34
        netmask 255.255.255.0
        network 192.168.33.0
        broadcast 192.168.33.255
        gateway 192.168.33.1
        # dns-* options are implemented by the resolvconf package, if installed
        dns-nameservers 192.168.33.1 8.8.8.8
        dns-search my.domain.com

El ataque de los clones (II)

Como decíamos el año pasado, la competencia del iPhone es dura: cada vez hay más terminales con pantalla táctil, aunque luego no le saquen partido (una vez más, Apple ha marcado la senda…). Qué tiempos cuando la duda era escoger entre PDA o smartphone…

El iPhone 3GS tiene un interfaz cómodo (gracias a la ágil respuesta de la pantalla táctil y el software que la gestiona), un diseño elegante, y miles de aplicaciones fácilmente instalables (gracias al AppStore). Integra todo lo que realmente se usa en un smartphone (iPod, GPS, internet por wifi o 3G)

Por otro lado,  la batería dura poco y la cámara se queda justita. Por supuesto se trata de un modelo de negocio propietario: Apple controla todo lo relativo a iPhone, y en España Movistar controla el acceso a los terminales.

La competencia se ha puesto las pilas y están lanzado móviles táctiles y sistemas operativos para móviles como locos. Esto estimula la innovación, pero también fragmenta las fuerzas (“together we stand, divided we fall”). Para derrotar al iPhone van a tener que hacer causa común y ofrecer algo con la misma calidad pero aportando alguna ventaja competitiva. Los usuarios no van a tragar con un interfaz de usuario cuyo tiempo de respuesta no sea tan bueno como el del iPhone.

Estos son los contendientes más interesantes del ubicuo iPhone (que por cierto amenaza con nueva versión para mediados del 2010):

  • Android (“Google-o-filo”)
    • Nexus One (el “teléfono de Google”). No es multitouch (?) pero tiene un pantallón (3’7″) de alta resolución
    • HTC
  • Palm
    • Pre (por segundo año consecutivo). Claro que con los rumores de compra de Palm, su futuro es incierto…
  • Symbian (S60)
    • Nokia X6
    • Nokia 5800 Navigation Edition
    • Nokia N900: basado en Maemo, el Linux para móviles de Nokia. ¿Cómo le afectará la fusión de Maemo con el Moblin de Intel? 2 cabezas, dos tiendas de aplicaciones… peligro, peligro…
    • Nokia N97 mini
  • Windows Mobile – finalmente Microsoft ha abierto los ojos y está apostando fuerte con la versión 7 (aunque por ahora se mantiene la 6.5)
    • Samsung
    • Toshiba TG1
  • Samsung Bada – otro sistema operativo para móviles basado en Linux. La cosa se pone caliente…
    • Samsung Wave

Mis Linux favoritos

Una pequeña selección de distribuciones Linux, en función de su utilidad

  • propósito general: Open SUSE o Ubuntu
  • servidores: Debian
  • arranque y rescate: Knoppix (Live CD)
  • eficiencia (si tienes paciencia :-p ): Gentoo
  • otras:
    • CoLinux (run Linux inside Windows with no virtualization)
    • dsl y puppy: distribuciones minimas que caben en cualquier sitio

Y algunos enlaces para ir abriendo boca con Linux

Restablecer arranque Windows 7

Las herramientas de recuperación integradas en el disco de instalación de Windows 7 ofrecen la opción de intentar reparar automáticamente el arranque de Windows.

A veces esa opción no consigue recuperar el arranque. En estos casos, aún quedan algunas opciones antes de reinstalar desde cero.

Si hemos tomado la precaución de crear una imagen del sistema, podemos recuperarla con estas mismas herramientas de recuperación. Hay que tener cuidado, ya que en este proceso se pueden perder datos (la imagen del sistema se “sobreescribe” en la partición destino). Además, todo volverá al estado en que se encontraba en la fecha en que se tomó la imagen (lo cual puede ser bueno o malo :-p )

Otra posibilidad es usar la línea de comandos, desde las herramientas de recuperación.

No están disponibles todos los comandos de shell de Windows 7, pero sí varios que resultan útiles en estas situaciones de rescate: bootrec.exe, chkdsk, diskpart, sfc, bcdedit…

Comandos útiles diskpart:

help
list disk
list partition
select disk 
select partition
active
delete partition

Con la siguiente secuencia de comandos se comprueba la partición de sistema (generalmente, C:, en nomenclatura Windows / DOS), se restablece el sector de arranque y se regenera el menú de arranque.

chkdsk c:
bootrec /FixMbr
bootrec /FixBoot
bootsect.exe /nt60 all /force
bootrec.exe /rebuildbcd

Si se han perdido / corrompido archivos de sistema, puedes recurrir a sfc:

sfc /scannow /offbootdir=c:\ /offwindir=c:\windows

Ampliación disco duro: clonar particiones Windows Linux

Al poner un disco duro más grande en el ordenador nos suele interesar conservar todo lo que teníamos en el anterior disco, tanto datos como sistema operativo y aplicaciones.

En el mercado hay infinidad de soluciones para “clonar” discos duros. Aunque a veces funcionan estupendamente, otras veces fallan o se eternizan. Sobre todo, en esquemas mixtos que mezclan particiones de Linux y de Windows, o incluso volúmenes LVM.

Por eso, el protocolo que suelo utilizar es algo más manual:

  1. Arrancar Linux con un Live CD (o DVD). Recrear la tabla de particiones (incluyendo volúmenes lógicos, si los hay) en el nuevo disco, usando fdisk o parted
  2. Particiones Linux: “formatearlas” en el nuevo disco, con el mismo sistema de ficheros. Después, basta con copiar todos los ficheros (por ejemplo, con el estupendo rsync)
  3. Particiones Windows: lo más fácil para clonar la partición de sistema Windows es usar una herramienta específica, como puede ser Clonezilla o EaseUs Diskcopy (ambas gratuitas). Diskcopy no permite crear particiones sobre la marcha. Si el disco origen sólo tiene un par de particiones Windows, no pasa nada: al seleccionar el espacio sin particionar como destino, Diskcopy crea automáticamente una nueva partición idéntica a la original. Si no nos conviene copiar todas las particiones originales secuencialmente, nos quedamos “desamparados”. De ahí que resulte más práctico particionar el nuevo disco antes de usarlo. Así, podemos elegir origen y destino cómodamente

Para aprovechar el espacio extra, podemos ampliar las particiones del nuevo disco. En el caso de Linux es trivial, ya que la copia la hacemos con herramientas básicas como rsync. Con lo cual, no hace falta que las particiones origen y destino tengan el mismo tamaño.

En el caso de particiones Windows, dependemos de la potencia de la herramienta. Clonezilla, por ejemplo, permite clonar a una partición más amplia. En cualquier caso, una forma de hacerlo es: al particionar el nuevo disco, crear la partición destino con el mismo tamaño que la origen, pero dejando espacio detrás. Una vez clonada, se puede cambiar el tamaño de la partición con herramientas como gparted. Aunque esté formateada como NTFS, amplia tanto el tamaño de la partición en sí como el del sistema de ficheros, con lo que al arrancar Windows reconoce perfectamente la unidad con el nueva tamaño.

Antes de dar el cambiazo definitivo, otro punto clave es replicar el gestor de arranque. Si utilizamos grub, basta con reinstalarlo a mano. Si queremos que se encargue Windows, podemos recurrir a las herramientas de recuperación del CD de instalación de Windows.

Awk

Límites numéricos de awk: mawk parece que tiene la impresión de enteros limitada a 32 bits con signo, mientras gawk no:

> mawk '{a=11111111111111111111+10; printf "%d", a}'
2147483647
> gawk '{a=11111111111111111111+10; printf "%d", a}'
11111111111111110656

En general, la aritmética de awk es en IEEE double (de ahí el error en la suma al pasar a enteros)

> mawk '{a=11111111111111111111+10; print a}'
1.11111e+19
> gawk '{a=11111111111111111111+10; print a}'
11111111111111110656

Observamos también que por defecto gawk evita el formato científico para imprimir enteros.