[php] Depurando / Profiling en php ( I )

Para poder diagnosticar qué sucede en la máquina cuando se ejecuta un script en php es necesario instalar un depurador o profiler. En este caso instalamos Advanced Php Debugger.

En máquinas Centos, como es usual no lo tenemos en el repositorio así lo instalaremos manualmente usando ‘pecl‘ que lo provee el paquete de php-pear .

pecl install apd

Será necesario tener instalado make, gcc  y autconf

Nos podemos encontrar con este error :

# pecl install apd
WARNING: channel "pear.php.net" has updated its protocols, use "channel-update pear.php.net" to update
downloading apd-1.0.1.tgz ...
Starting to download apd-1.0.1.tgz (36,643 bytes)
..........done: 36,643 bytes
15 source files, building
running: phpize
Configuring for:
PHP Api Version:         20041225
Zend Module Api No:      20060613
Zend Extension Api No:   220060519
building in /var/tmp/pear-build-root/apd-1.0.1
running: /tmp/pear/download/apd-1.0.1/configure
checking for egrep... grep -E
checking for a sed that does not truncate output... //bin/sed
checking for cc... cc
checking for C compiler default output file name... a.out
checking whether the C compiler works... configure: error: cannot run C compiled programs.
If you meant to cross compile, use `--host'.
See `config.log' for more details.
ERROR: `/tmp/pear/download/apd-1.0.1/configure' failed

Normalmente es debido a que tenemos /var y /var/tmp con la opcion de noexec. Para poder ejecutarlo correctamente pondremos temporalmente estos puntos de montaje con permisos de ejecución y luego lo restauramos:

mount -o,remount,rw,exec /var/tmp
mount -o,remount,rw,exec /tmp
pecl install apd
mount -o,remount,rw,noexec /var/tmp
mount -o,remount,rw,noexec /tmp

Nos insteresa quedarnos con este contenido para configurar el fichero .ini :

running: make INSTALL_ROOT="/var/tmp/pear-build-root/install-apd-1.0.1" install
Installing shared extensions:     /var/tmp/pear-build-root/install-apd-1.0.1/usr/lib64/php/modules/
running: find "/var/tmp/pear-build-root/install-apd-1.0.1" | xargs ls -dils
  12   1 drwxr-xr-x 3 root root   1024 Jul 23 18:33 /var/tmp/pear-build-root/install-apd-1.0.1
2057   1 drwxr-xr-x 3 root root   1024 Jul 23 18:33 /var/tmp/pear-build-root/install-apd-1.0.1/usr
4113   1 drwxr-xr-x 3 root root   1024 Jul 23 18:33 /var/tmp/pear-build-root/install-apd-1.0.1/usr/lib64
6169   1 drwxr-xr-x 3 root root   1024 Jul 23 18:33 /var/tmp/pear-build-root/install-apd-1.0.1/usr/lib64/php
8225   1 drwxr-xr-x 2 root root   1024 Jul 23 18:33 /var/tmp/pear-build-root/install-apd-1.0.1/usr/lib64/php/modules
8226 129 -rwxr-xr-x 1 root root 130196 Jul 23 18:33 /var/tmp/pear-build-root/install-apd-1.0.1/usr/lib64/php/modules/apd.so

Build process completed successfully
Installing '/usr/lib64/php/modules/apd.so'
install ok: channel://pear.php.net/apd-1.0.1

Tendremos que crear un fichero en /etc/php.d/apd.ini con este contenido

zend_extension = /usr/lib64/php/modules/apd.so
apd.dumpdir = /tmp
apd.statement_tracing = 0

y comprobamos que el modulo carga con php -m

#php -m

....

[Zend Modules]
Advanced PHP Debugger (APD)
Zend Optimizer

Ahora ya podemos lanzar el profiling en nuestras páginas, para ello podemos incrustar este fragmento de código y activarlo sólamente cuando accedamos nosotros y no los clientes:

 <?php
 $DEBUGIPS = array('93.174.6.8','192.168.1.1');
 if(array_search($_SERVER[REMOTE_IP], $DEBUGIPS)) {
   apd_set_pprof_trace();
 }
?> 

Y con esto acabamos la primera parte, atentos a la segunda 😀

[magento] PHP Fatal error: Exception thrown without a stack frame in Unknown on line 0

Estos últimas días hemos tenido que optimizar la carga de servidores con Magento. Una de las tareas es usar un sistema de caché que acelere los scripts php. Usamos apc por compatibilidad con Magento y por que ya viene paquetizado en los repositorios de Debian.

El problema, aparece en el pié de página: “PHP Fatal error:  Exception thrown without a stack frame in Unknown on line 0”.
Este error aparece cuando se ha lanzado una excepcion en un lugar donde se no se puede lanzar una excepción por no tener ‘stack frame‘.

Los manejadores de excepciones ‘ exception handlers‘ y los destructores no tienen ‘stack frame‘.
Por lo que combinar por ejemplo un ‘execption handler‘ con un ‘error preporting‘  o lanzar un execption en un destructor puede provocar que aparezcan. Os podeis documentar más en este interesante enlace Solving “Fatal error: Exception thrown without a stack frame in Unknown on line 0″

En nuestro caso, tan solo hizo falta acutalizar la version del apc con un simple aptapt-get install php-apc

En la máquina estaba previamente instalado el apc vía pecl

Agrengando lenguaje Vasco al webmail de Plesk: Horde

Un requisito relativamente fácil como puede ser agregar un idioma a Horde ( gestor de mail vía web y software libre ) puede complicarse al tener que realizarlo en un entorno paquetizado y cerrdado como es Plesk. El problema de modificar este componente ( u otros de Plesk ) es que futuras versiones o parches de Plesk puedes modificar o machacar nuestros cambios. Además de no conocer el impacto real de nuestras modificaciones.

Desde el soporte de Parallels nos han indicado que no existe problema en agregar un nuevo lenguaje a Plesk y nos indican la guia de instalacion de idiomas en Horde http://www.horde.org/horde/docs/?f=po_README.html

Primero verificamos que version tenemos de Horde instalada. Vamos a intentar siempre usar las mismas versiones para quitarnos de problemas

# rpm -qa | grep horde
psa-horde-3.1.7-cos5.build92090714.19

Creamos el directorio para preparar la compilacion de los idiomas ( hay que generar los .mo a partir de ficheros .po )

mkdir -p /usr/src/horde
cd /usr/src/horde

Nos bajamos nuestra versión de horde:

wget http://ftp.horde.org/pub/horde/horde-3.1.7.tar.gz
tar zxvf horde-3.1.7.tar.gz

Ahora nos bajamos por separado los ficheros .po del cvs y que no están en la distribucion 3.1.7.
Es muy importante no mezclar ficheros de distribuciones para evitar problemas. La estructura de directorios se almacenará en el directorio ‘horde’

export CVSROOT=:pserver:cvsread@anoncvs.horde.org:/repository
cvs login
# password: horde
# cvs co horde/po/ horde/locale horde/lib/core.php
cvs co horde/po/ horde/locale 

Como solo queremos los ficheros de cadenas, mezclar phps de distinas versiones nos dará errores de clases no encontradas

cp -r horde/po/*_* horde-3.1.7/po/
cp -r horde/locale/*_* horde-3.1.7/locale/

Tenemos algunos requistios que se pueden leer en el fichero REAME.

cd /usr/src/horde-po
wget http://download.pear.php.net/package/File_Find-1.3.0.tgz
wget http://download.pear.php.net/package/Console_Table-1.1.3.tgz

mkdir -p pear/Console
mkdir -p pear/File

tar zxvf File_Find-1.3.0.tgz -C pear/File/ *Find.php
mv pear/File/File_Find-1.3.0/Find.php pear/File/

tar zxvf Console_Table-1.1.3.tgz -C pear/Console/ *Table.php
mv pear/Console/Console_Table-1.1.3/* pear/Console/

También necesitamos la herramienta gettext al menos la version 0.12

yum install gettext

Dado que ejecutamos php con la configuracion de Plesk estamos limitados a la ejecución de comandos bajo safe_mode. En la cabecera de translator.php, agregamos las rutas necesarias ( include_path ) y con php -n hacemos que no cargue el /etc/php.ini para saltarnos el safe_mode

#!/usr/bin/php -qn
<?php
ini_set ("include_path", "/usr/src/horde/horde-3.1.7/lib:/usr/share/psa-pear/:/usr/src/horde/pear/:." );

Ahora generamos los ficheros:

./translator.php make 

Copiamos los ficheros de cadenas a nuestra ubicación de la instalación de Plesk. Cuidado, no copiar ningún php de la rama del cvs a nuestra rama estable.

cp /usr/src/horde/horde-3.1.7/locale/* /usr/share/psa-horde/locale/

Por último editar la configuracón de horde de plesk para que aparezca el nuevo idioma disponible:

/etc/psa/webmail/horde/horde/nls.php
$nls['languages']['eu_ES'] = 'Euskera';

Aún no he tenido la oportunidad de problarlo pero casi seguro que con alguna alguna actualización, machaca este fichero y hay que volver a editarlo para agregar el idioma.

Linux mola

Ayer día 15 de Marzo de 2009 se cerró el plazo para participar en el concurso “We’re Linux” de la Fundacion Linux. El ganador tendrá viaje y hospedaje para el “Linux Foundation Japan Symposium” en Octubre de 2009.

La mayoría de los videos no valen nada, parece que l@s chic@s linux están más centrados en tareas más tecnicas que en artes creativas jejejeje

No obstante no hay que dejar pasar este video:

Más videos aquí

Instalando una impresora Brother MFC-7820N en debian

He estado tratando de instalar la impresora de red Brother MFC-7820N y la verdad que me ha costado un poco. Diversos mensajes tanto en el gnome-cups-manager, como en el interface web de cups, y en los logs de cups como estos:
[shell]CUPS-Add-Modify-Printer client-error-not-possible: device-uri
cups client-error-not-possible
UPS-Add-Modify-Printer client-error-not-possible: device-uri “socket://192.168.1.13” incorrecto.
[/shell]

Al final recordé que existen opciones para reconfigurar el paquete cups asi que a reconfigurar..

[shell]
# marcar nivel bajo
dpkg-reconfigure debconf

# reconfigurar cups
dpkg-reconfigure cups[/shell]
Nos presenta algunas opciones a elegir:

En IPP todos los trabajos de impresión tienen un tipo MIME. Puesto que no todas las fuentes de trabajos de impresión asignan correctamente algún tipo MIME, muchos llegan con el tipo «application/octet-stream» y podrían rechazarse si CUPS no puede adivinar el formato del trabajo. Es posible hacer que CUPS trate todos estos trabajos como trabajos «en crudo», con lo que se mandan directamente a la impresora sin procesar. Se recomienda que escoga esta opción si el servidor va a aceptar trabajos de impresión de ordenadores con Windows o servidores Samba. ¿Quiere que CUPS imprima en bruto los trabajos desconocidos?

Marcamos

CUPS utiliza diversos motores para comunicarse con el puerto o dispositivo de la impresora. Desafortunadamente, ciertos motores pueden causar problemas. Por ejemplo, con el motor del puerto paralelo se producen algunas caídas del núcleo en la arquitectura PPC. Por favor, elija el motor que utilizará CUPS. La opción predeterminada debería ser apta para los entornos más comunes. Motores de comunicación con la impresora:

Seleccionamos : ipp , socket, usb, snmp, dnssd

Con estas opciones deberemos poder configurar e imprimir correctamente

Instalando BCM4310 en Linux

Uno de los puntos negros de linux, es el soporte para hardware nuevo o hardware que tarda en ser soportado de forma estable.

Esta semana me he encontrado con la necesidad de usar una wifi en un portatil HP Pavillion dv6000 con tarjeta wifi BCM 4310. La instalación de sistema operativo, ubuntu.

Tras verificar en linuxwireless que no hay soporte para esta tarjeta y que la unica forma es via ndiswrapper.

BCM 4310 – This device has an LP PHY. We think that means low power. In any case, previous code does not work. The reverse engineers have translated a great deal of the code and are currently generating specs for the code writers.

Seguimos estos pasos:

[shell]
cd /tmp
wget ftp://ftp.us.dell.com/network/R151517.EXE
unzip R151517.EXE
cd DRIVER
ndiswrapper -i bcmwl5.inf
ndiswrapper -ma

# quitamos estos modulos que pueden dar conflicto
echo blacklist ssb >> /etc/modprobe.d/ndiswrapper
echo blacklist b43 >> /etc/modprobe.d/ndiswrapper

# cargamos el modulo de ndiswrapper
modprobe ndiswrapper
[/shell]

PHP Warning: [eAccelerator] Can not create shared memory area in Unknown on line 0

eAccelertor es una solución de cache para php. Con este software conseguimos guardar una copia de scripts ya interpretados, de esta forma cada vez que el servidor web tenga que lanzar este script ahorrará una parte de tiempo y carga de cpu.

Con este software puede ocurrir que nos econtremos con el siguiente error:

PHP Warning:  [eAccelerator] Can not create shared memory area in Unknown on line 0
PHP Fatal error:  Unable to start eAccelerator module in Unknown on line 0

    
Por defecto el tamaño de memoria compartida ( shared memory ) en un kernel 2.6 es de 32mb. Este parámetro se encuentra en el fichero /proc/sys/kernel/shmmax de forma que puedes comprobar si está en el límite. Para modificarlo existen dos formas :

* Cambio on-fly, con esto duplicaremos el tamaño actual

echo $(( `cat /proc/sys/kernel/shmmax` * 2 ))  > /proc/sys/kernel/shmmax

* Cambio permamente, modificando /etc/sysctl.conf

kernel.shmmax=VALOR_DESEADO

# aplicar los cambios reiniciando o con este comando:
sysctl -p

En el caso de los vps habŕa que comprobar si la memoria asignada es suficiente ( share memory and socket buffers ). Para ello podemos verificar el fichero /proc/user_beancounter donde muestra todos los parámetros que tenemos y la última columna referente a failcnt, es la cantidad de veces que se han superado estos límites. Seguramente aparecerá la fila  PRIVVMPAGES con el contador distinto de 0. Habrá que ampliar este valor en ese caso.