Solucionar error symbol lookup error: suhosin.so: undefined symbol: php_mb_encoding_translation en PHP 5.4 con cPanel

5 09 2013
Suhosin logo

Suhosin logo de Hardened PHP Project

Si has actualizado a PHP 5.4 en cPanel es posible que durante la subida de archivos u otras partes de tu código PHP te encuentres el siguiente error en el error_log de Apache.

1
2
/usr/bin/php: symbol lookup error: /usr/local/lib/php/extensions/no-debug-non-zts-20100525/suhosin.so:
 undefined symbol: php_mb_encoding_translation

Este error sólo se produce si además tienes activo Suhosin. Oficialmente PHP 5.4 no tiene soporte para Suhosin, pero esta extensión es muy necesaria para el uso de servidores compartidos, debido a que ofrece bastantes características de seguridad adicionales a la instalación base de PHP.

El problema se debe a que varias funciones relacionadas con mb string no estan presentes en el código fuente de PHP (probablemente porque cPanel usa una versión propia y ligeramente modificada del código original de PHP), donde puede haber sido eliminada la función php_mb_encoding_translation

Podemos observar, que en el código fuente de la versión PHP 5.4.19 se encuentra definida la función php_mb_encoding_translation() en concreto en /ext/mbstring/mbstring.c:102. Teóricamente esta función existe en el código nativo de PHP y suhosin debería poder utilizarla, pero al ser la versión PHP personalizada de cPanel no esta presente y suhosin falla al ejecutar el código php y eso producirá un error 500 en Apache abortando la ejecución del script.

Afortunadamente, existe un parche en Github en forma de Pull Request cuyo autor es Jan Ingvoldstad, que no ha sido aún aceptada después de más de 8 meses (al momento de escribir este artículo).

Puedes aplicar directamente el parche en el código fuente de github y compilarlo. En mi caso, he creado un repositorio aparte haciendo cherry picking del parche y de otros parches adicionales que corrigen otros errores en PHP 5.4 con suhosin y aún no han sido fusionados en el proyecto original.

La forma rápida de solucionarlo sería:

1 – Clonar mi repositorio de Suhosin con los parches aplicados (cherry picking)

1
git clone -b master --single-branch http://github.com/shakaran/suhosin.git suhosin-shakaran

2 – Compilar e instalar suhosin desde mi rama. En una sola línea sería:

1
cd suhosin-shakaran; phpize; ./configure; make; make install

Pero si quieres hacer tu propio cherry picking te explico como podrías hacer lo mismo que yo:

1 – Dirígete a github, en el repositorio oficial de suhosin y haz un fork del proyecto original

2 – Añade como repositorio remoto la rama de Jan Ingvoldstad

1
git remote add jani-upstream git://github.com/jani/suhosin.git

3 – Baja los commits de dicha rama (solo las referencias)

1
git fetch jani-upstream

4 – Haz un cherry pick del commit (parche) que arregla el fallo:

1
git cherry-pick e8beb4f50fa997c0ea4b923677deb275cc7660e

5 – Compila con:

1
cd suhosin-shakaran; phpize; ./configure; make; make install

Y listo, tendrás tu propio branch con tu parche aplicado.

VN:F [1.9.22_1171]
Rating: 0.0/10 (0 votes cast)
VN:F [1.9.22_1171]
Rating: 0 (from 0 votes)


FreeStation: a little sneak peek

16 04 2012

Several months have passed since I wrote about Freestation. I would like show some advances and write about my dissertation project that I hope to finish for the 2th June as last day for deadline on this course.

An introduction reminder

FreeStation is a program built for help to distribute easy and reliable software and information on point of interest (POI).

Basically, a POI is huge device that you can find on universities, libraries, hospitals, police stations, train stations, etc.

For example, this are a couple of images of POIs:

DNI POI on police station

DNI POI on police station

This is POI on a police station for perform changes with a DNI (National Idenfication Document on Spain). It shows a keyboard, trackball and DNI card reader for easy operations with credential authentication using DNI.

It has normal power connection but it also has internet connection for load data. On the following image:

Front detail of DNI POI on a police station

Front detail of DNI POI on a police station

As you can apreciate, it shows with more details a screen showing input boxes for the user and a simple interface with buttons. The height POI is adjusted to people in wheelchairs (a laudable feature for accessibility).

Another example of POI:

Adif POI on a train station

Adif POI on a train station

This image corresponds to another POI on a Adif’s train station. It has a different design, totally vertical with a big screen rotated. Unfortunaly when I take the photo it was turned off, but I think that it is a tactil screen model with internet connection too.

It incorporates a audio system maybe useful for blind people and as possible confirmation for using audio notification. Sadly, it is enough high for wheelchairs people, so maybe the only functions could be a information panel with low interaction. I can’t ensure this, because I never can see running this POI when I travel.

Finally another radical example of POI (three different examples should be enough for ilustrate my point):

SESCAM POI on a hospital

SESCAM POI on a hospital

This is another interesting POI that has a intercommunication phone for direct assistance, keyboard, tracball mouse and sanitary card reader. It also has a tray as printer for deliver useful data to the user. Sadly, when I take the photo the POI also is turned off.

So, this is only a reduced set of examples of a huge variety of POIs. Usually you can find the same model for each same hospital, train station, police station, university, etc. Each model runs practically the same model of software and hardware features. But, when the time past, it is highly probably that some POIs have breakdows, energy loss, software bugs, unconsistence of versions, etc.

So, FreeStation try to repair and unify this problems for offer a kindly solution, because it is important deploy same versions between POIs, recieve notifications when a POI it is offline for a breakdown, auto-restart the POI if some hard bug happens, etc.

Architecture

The Freestation architecture is mainly based on client-server model. Each component is easy to tweak or customize and it doesn’t require technical knowledge for diary use.

Architecture - Server and clients infrastructure

Architecture - Server and clients infrastructure

Let me introduce you the architecture with real screenshots of the application and some diagrams.

Server architecture

FreeStation server runs over a software stack consisting of several technologies and components. It handles all the communication with every client.

It has a friendly webserver GUI panel administration based on PHP + Javascript.

FreeStation Server Webserver GUI

FreeStation Server Webserver GUI

As you can see, you can start/stop/restart the server, see real status and different useful output logs for analyce and diagnose whatever event.

It allows easily make the common tasks for deploy and configure a high amount of clients with POIs.

Under the webserver GUI, it runs a daemon process as backend based on python. Each action and task is handled internally and dispatched on fast way.

The backend can make asynchronous communication with clients. For that the backend uses ICE (Internet Comunication Engine of ZeroIce).

This allows a reliable and robust way to transfer huge information datasets between a big amount of clients and the server.

For example, you also can see a list of current clients handled by the server with stats:

FreeStation Server GUI - List of clients

FreeStation Server GUI - List of clients

The list shows each client hostname, IP address, last connection, requests, status and some actions for each client. You can add/remove/edit clients and all the data associated with a clients would be updated.

Client architecture

A client run only on a POI and periodically poll to the server for updates or information. Clients need a specification for deploy widgets and the data associated for each widget.

A widget on Freestation terminology is a abstract element that performs a atomic operation and provides communication for the data handled inside the widget.

For complex operations a widget could associate with more widgets for perform a sofisticated task or simply commnicate data with other widgets. The widgets only run on clients, but all them are configured only from a server.

This describe a orchestra model where the server acts like a manager and clients with widgets acts like a choir.

That means that a client only can communicate with the server and it is not allowed the communication between clients. But this can be easily a SPOF (Single Point Of Failure) for server. So, it is planned on a future allow several masters servers as failover and syncronize and replicate data between masters.

In other hand, an a server, you have a list of widgets available to configure on a client.

FreeStation Server GUI - List of total widgets

FreeStation Server GUI - List of total widgets

For example, you can choose deploy and configure a USB Storage widget and a Mount Device widget on a client. That widgets could associate operations for list several files of books about medicine. When the user pick a set and choose save to a usb key, the Mount Device detect the usb key and usb storage widget write the data. The result it is a happy user that obtain the needed information quickly and without problems.

FreeStation Server - Associate widget to client

FreeStation Server - Associate widget to client

 

You can associate the needed widgets for a client and configure/edit each widget with custom params (for example, only allow 5 items for save on Mount Device):

FreeStation Server - Configure Widget for a client

FreeStation Server - Configure Widget for a client

Another example, you can choose a Video widget and display a video on POI for idle mode. When the user touch or interact with the POI, you can load a Browser Widget with a concrete webpage. Additionally as some institution you can choose a simple logo widget for display your institution logo on screen.

When a client is totally configured, then can be deployed on POI (normal desktop computer customized). A simple example of client screen deployed:

 

FreeStation Client - Welcome wigdets configured

FreeStation Client - Welcome wigdets configured

There are not limit defining or using new widgets. So in theory, the widget model scale for each custom need for a institution.

Free & easy to scale to your needs

With FreeStation some basic widgets are offered, but on the future, it could has repository widgets associated, widget patners and offer a rich market for developers that they are interested on develop custom widgets for companies, institutions, hospitals.

Soon, I plan to release the code as AGPLv3 on Github. Still I need polish some widgets, finish a real demo case for my dissertation and literally write a boring book with approximattelly 200 pages (currently, I have around 80 bad structure pages written).

So, the project is nearly to finish and with lucky I can finish before to 2th june deadline (and 15 th june official presentation) and finally has a big engineer diploma on my wall, yay!

Meanwhile, there are nearly two months of hard work, But shhh … I found a secret weapon ;)

 

Secret hard work weapon

Secret hard work weapon

 

 

VN:F [1.9.22_1171]
Rating: 0.0/10 (0 votes cast)
VN:F [1.9.22_1171]
Rating: 0 (from 0 votes)


Depurar y perfilar funciones PHP gráficamente con XDebug, KCacheGrind y Webgrind en Ubuntu 11.10

18 01 2012
El arte de depurar y perfilar con PHP

El arte de depurar y perfilar con PHP

En desarrollo web y por lo general, en cualquier aplicación que requiera tener una demanda escalable, son muy importantes los algoritmos empleados, las llamadas a funciones nativas y las estructuras de datos utilizadas.

En aplicaciones PHP con miles de líneas de código se necesita un diseño eficiente para poder manejar una buena ejecución del código PHP.

Principalmente se busca reducir el consumo de memoria y CPU al máximo posible, sin que la aplicación pierda funcionalidad, ni características. Para lograr este objetivo y que la aplicación sea escalable, se busca utilizar buenas herramientas de depuración y profiling (perfilado de rendimiento). Con ello se consigue que el programador o ingeniero disponga de una buena perspectiva de lo que esta haciendo a bajo nivel su aplicación y decidir en consecuencia que técnica aplicar.

El perfilado o medición del rendimiento (performance profiling) permite ejecutar código en un entorno controlado y devolver un listado con estadísticas de tiempo gastado en cada funcion, longitud de consultas a la base de datos o la cantidad de memoria que ha sido usada. De esta forma, se puede desechar codígo lento o superfluo de una manera muy rápida o incluso realizar pequeños trucos en partes críticas para ganar más rendimiento.

Herramientas

En PHP existen varias herramientas de depuración(debugging) y localización de cuellos de botella(bottleneck) para perfilado de rendimiento.

Las herramientas más utilizadas son:

  • BenchMark es un proyecto PEAR de PHP, pero actualmente no esta mantenido.
  • DBG PHP Debugger es otra herramienta de depuración que dispone de una versión comercial y otra gratuita. La versión gratuita sólo permite depurar la rama de versión 5.2 y la comercial la versión 5.3. La aplicación es bastante cara y parece que no tiene mucha actividad y estar sólo integrada con el IDE NuSphere PhpED.
  • El Depurador Avanzado de PHP (APD, del inglés “Advanced PHP Debugger“) es un proyecto PEAR de PHP escrito en C por George Schlossnagle and Daniel Cowgill. Es cargado como una extensión en el motor Zend y funciona enlazando e interceptando las llamadas a funciones en el núcleo de Zend. Esto permite la medición del tiempo de ejecución de una función, la vuelta atrás de pilas, etc. La documentación es mínima y los informes de depurado junto con funcionalidades son algo reducidas, por lo que en la práctica no es la opción más utilizada.
  • Xdebug es el depurador y perfilador por excelencia de PHP escrito por Derick Rethans. Tiene una gran variedad de parámetros de configuración, depuración remota, integración con muchos IDEs (Eclipse, Netbeans, etc), reportes coloreados, niveles máximos de anidación para el depurado, accionadores (triggers) para el perfilador, un conjunto de funciones (para puntos de ruptura, analisis de tiempos, etiquetado de código, etc), reemplazo de var_dump por funciones de visualización, trazas de la pila de ejecución,  trazas de funciones, análisis de cobertura de código,   etc.

Instalación y configuración de Xdebug

Puesto que Xdebug ofrece las mejores características y facilidades, es la opción preferida, ademas la instalación y configuración en Ubuntu 11.10 es bastante sencilla.

Se pueden bajar los f uentes y compilarlos, pero resulta más cómodo bajar del repositorio PEAR la aplicación e instalarla.

Para instalar el paquete PEAR, debemos tener previamente PEAR instalado:

1
$ sudo apt-get install php-pear php5-dev

Despues, instalamos Xdebug a través de PECL

1
$ sudo pecl install xdebug

Una vez finalizada la instalación, podemos encontrar la biblioteca compartida compilada en /usr/lib/php5/20090626+lfs/xdebug.so

Pasamos a configurar el php.ini para que cargue Xdebug. Por defecto Ubuntu 11.10 tiene varios php.ini, como son /etc/php5/cli/php.ini/etc/php5/apache2/php.ini. Este último es que se utiliza para la configuración global.

Pasamos a modo root:

1
$ sudo su -

Añadimos Xdebug al php.ini cargándolo como extensión zend y con el path completo, en nuestro caso el path es /usr/lib/php5/20090626+lfs/xdebug.so

1
# echo 'zend_extension = "/usr/lib/php5/20090626+lfs/xdebug.so"' >> /etc/php5/apache2/php.ini

Después lo cargamos como extensión PHP:

1
# echo "extension=xdebug.so" >> /etc/php5/apache2/php.ini

Para comprobar que ha sido cargado, podemos mirar los módulos cargados de PHP:

1
2
# php -m | grep Xdebug
Xdebug

O bien en la información general:

1
2
# php -i | grep Xdebug
with Xdebug v2.1.2, Copyright (c) 2002-2011, by Derick Rethans

Si filtramos en minúsculas para la información general, podemos ver todas las opción de configuración:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
# php -i | grep xdebug
xdebug
xdebug support => enabled
xdebug.auto_trace => Off => Off
xdebug.collect_assignments => Off => Off
xdebug.collect_includes => On => On
xdebug.collect_params => 0 => 0
xdebug.collect_return => Off => Off
xdebug.collect_vars => Off => Off
xdebug.default_enable => On => On
xdebug.dump.COOKIE => no value => no value
xdebug.dump.ENV => no value => no value
xdebug.dump.FILES => no value => no value
xdebug.dump.GET => no value => no value
xdebug.dump.POST => no value => no value
xdebug.dump.REQUEST => no value => no value
xdebug.dump.SERVER => no value => no value
xdebug.dump.SESSION => no value => no value
xdebug.dump_globals => On => On
xdebug.dump_once => On => On
xdebug.dump_undefined => Off => Off
xdebug.extended_info => On => On
xdebug.file_link_format => no value => no value
xdebug.idekey => root => no value
xdebug.manual_url => http://www.php.net => http://www.php.net
xdebug.max_nesting_level => 100 => 100
xdebug.overload_var_dump => On => On
xdebug.profiler_aggregate => Off => Off
xdebug.profiler_append => Off => Off
xdebug.profiler_enable => On => On
xdebug.profiler_enable_trigger => On => On
xdebug.profiler_output_dir => /var/www/webgrind/tmp => /var/www/webgrind/tmp
xdebug.profiler_output_name => cachegrind.out.%t.%p => cachegrind.out.%t.%p
xdebug.remote_autostart => Off => Off
xdebug.remote_connect_back => Off => Off
xdebug.remote_cookie_expire_time => 3600 => 3600
xdebug.remote_enable => On => On
xdebug.remote_handler => dbgp => dbgp
xdebug.remote_host => 127.0.0.1 => 127.0.0.1
xdebug.remote_log => no value => no value
xdebug.remote_mode => req => req
xdebug.remote_port => 9000 => 9000
xdebug.scream => Off => Off
xdebug.show_exception_trace => Off => Off
xdebug.show_local_vars => Off => Off
xdebug.show_mem_delta => Off => Off
xdebug.trace_format => 0 => 0
xdebug.trace_options => 0 => 0
xdebug.trace_output_dir => /tmp => /tmp
xdebug.trace_output_name => trace.%c => trace.%c
xdebug.var_display_max_children => 128 => 128
xdebug.var_display_max_data => 512 => 512
xdebug.var_display_max_depth => 3 => 3

Activando configuraciones en Xdebug

Para generar información de depuración, debemos activar como mínimo las siguientes configuraciones de la familia xdebug.profiler_*:

  • Primero escribimos la cabecera de configuraciónpara xdebug:
    1
    
    # echo "[xdebug]" >> /etc/php5/cli/php.ini
  • xdebug.profiler_enable activa el perfilador de xdebug para que genere archivos de perfilado en un directorio de salida. Estos archivos puedes leerse por programas visualizadores gráficos de llamadas como KCacheGrind o Webgrindque será explicado más adelante. Esta configuración también puede habilitarse mediante la función ini_set() por lo que resulta interesante para activar selectivamente el perfilador en nuestras aplicaciones. Se activa con:
    1
    
    # echo "xdebug.profiler_enable = 1" >> /etc/php5/cli/php.ini
  • xdebug.profiler_enable_triggerpermite generar archivos de perfilador usando el parámetro XDEBUG_PROFILE por peticiones GET/POST o establecer una cookie. Lo activamos con:
    1
    
    # echo "xdebug.profiler_enable_trigger = 1" >> /etc/php5/cli/php.ini
  • xdebug.profiler_output_dir el valor por defecto donde el perfilador escribira su salida. Debe tener permisos de escritura para PHP y no puede ser establecida con ini_set(). Para propósitos posteriores, la estableceremos como:
    1
    
    # echo 'xdebug.profiler_output_dir = "/var/www/webgrind/tmp"' >> /etc/php5/cli/php.ini
  • xdebug.profiler_output_name determina el nombre del archivo usado para las trazas de depuración. La configuración especifica el formato del nombre con los especificares de formato que son muy similares a sprintf() y strtime(). Por defecto es cachegrind.out.%p. Existe un un listado completo de los especificadoresdocumentados. Lo configuramos con:
    1
    
    # echo "xdebug.profiler_output_name = cachegrind.out.%t.%p" >> /etc/php5/cli/php.ini

La configuración mínima recomendada que resultaría al final del php.ini quedaría como:

1
2
3
4
5
6
7
8
zend_extension = "/usr/lib/php5/20090626+lfs/xdebug.so
extension=xdebug.so
 
[xdebug]
xdebug.profiler_enable = 1
xdebug.profiler_enable_trigger = 1
xdebug.profiler_output_dir = "/var/www/webgrind/tmp"
xdebug.profiler_output_name = cachegrind.out.%t.%p

Si queremos activar ademas la depuración remota en un puerto y máquina (o bien en la misma), usaremos la familia de configuraciones xdebug.remote_*. Las mínimas recomendadas son:

  • xdebug.remote_enable si esta activado, Xdebug tratará de contactar con el cliente que este escuchando en el puerto y host configurad. Si la conexión no puede ser establecidad, el script continuará ejecutado como si estuviera desactivado. Lo activamos con:
    1
    
    # echo "xdebug.<a title="xdebug.remote_enable config option" href="http://xdebug.org/docs/all_settings#remote_enable" target="_blank">remote_enable</a> = 1" >> /etc/php5/cli/php.ini
  • xdebug.remote_host selecciona el host donde el cliente de depuración se ejecutará. Puede utilizar un nombre de host o una dirección IP. Lo configuramos con:
    1
    
    # echo "xdebug.remote_host=127.0.0.1" >> /etc/php5/cli/php.ini
  • xdebug.remote_port el puerto al que Xdebug tratara de conectar en el host remoto. Por defecto es el puerto 9000, para el cliente y cliente de debug integrado. Lo configuramos con:
    1
    
    # echo "xdebug.remote_port=9000" >> /etc/php5/cli/php.ini
  • xdebug.remote_handler puede ser ‘php3′ que selecciona el depurador antiguo para PHP3, tambiíen puede ser ’gdb’ que habilita el depurador GDB o bien el protocolo de depuración con ‘dbgp’. El protocolo de depuraciónesta por lo general más soportado por los clientes. Lo configuramos con:
    1
    
    # echo "xdebug.remote_handler=dbgp" >> /etc/php5/cli/php.ini

Puedes ver más información en la introducción al depurado remoto de Xdebug.

Por lo que el resultado final sería:

1
2
3
4
5
6
7
8
9
10
11
12
zend_extension = "/usr/lib/php5/20090626+lfs/xdebug.so
extension=xdebug.so
 
[xdebug]
xdebug.profiler_enable = 1
xdebug.profiler_enable_trigger = 1
xdebug.profiler_output_dir = "/var/www/webgrind/tmp"
xdebug.profiler_output_name = cachegrind.out.%t.%p
xdebug.remote_enable=true
xdebug.remote_host=127.0.0.1
xdebug.remote_port=9000
xdebug.remote_handler=dbgp

Instalando KCacheGrind

KCacheGrind es un programa de escritorio (en especial para diseñado para KDE, pero compatible para GNOME) escrito para visualizar los archivos de depuración generados por xdebug. Es un frontend de Callgrind, que a su vez usa en tiempo de ejecución al framework de Valgrind para simulación de caches y generación de las llamadas gráficas. Un aspecto a recalcar es que incluso las bibliotecas compartidas que son abiertas dinamicamente son perfiladas. Podemos abrir con el archivos de depuración con formato Callgrind generados con xdebug de forma bastante rápida.

Para instalarlo simplemente:

1
$ sudo apt-get install kcachegrind

Por ejemplo podemos crear un archivo con la información de PHP para ver un ejemplo sencillo de depuración y ejecutarlo para que se genere un archivo cachegrind.out, que podamos abrir con KCacheGrind:

1
# echo "&lt;?php phpinfo(); ?>" >> /var/www/phpinfo.php

Como resultado, obtendríamos un grafo y los tiempos de ejecución globales y relativos implicados:

KCacheGrind - Ejemplo sencillo con phpinfo()Ejemplo de depuración de phpinfo() con KCacheGrind

Es una aplicación bastante notable, pero en su lugar es más recomendable usar Webgrind como frontend web, que veremos a continuación.

Instalar webgrind

Webgrind 1.0 logo

Webgrind es un perfilador gráfico de PHP via web escrito en PHP por Joakim Nygård y Jacob Oettinger. Tiene como dependencia Xdebug ya que es en realidad un wrapper web no completo de las funciones de KCacheGrind como reemplazo de frontend web de xdebug (existe incluso una proposición de Google Summer of Code aceptada por Chung-Yang Lee).

Su apareciencia es simple y agradable para depurar aplicaciones PHP. Es multiplataforma (al ser vía web) y permite seguimiento de los tiempos empleados por cada llamada de función, por coste de ellas misma o coste inclusivo (el coste inclusivo es el tiempo dentro de la función mas llamadas internas de esa función a otras).

También permite ver tiempo de llamadas internas y llamadas de usuario diciendo la llamada por la que fue invocada previamente.

Descargamos la aplicación de github, ya que en el momento de escribir este artículo están haciendo una migración de google code a github (también puedes hacer un checkout del repo, aunque puede ser inestable):

1
$ wget https://github.com/downloads/jokkedk/webgrind/webgrind-release-1.0.zip

Descomprimos:

1
$ unzip webgrind-release-1.0.zip

En ubuntu el DocumentRoot de Apache esta establecido por defecto en /var/www según /etc/apache2/sites-available/default

Luego, copiaremos los fuentes de webgrind y crearemos los archivos temporales que configuramos como directorio de salida en el perfilador de Xdebug:

1
2
3
$ sudo mv webgrind /var/www
$ sudo mkdir /var/www/webgrind/tmp
$ sudo chmod 777 /var/www/webgrind/tmp

Editamos el archivo de configuración e introducimos la ruta de directorio de salida de xdebug:

1
$ sudo vi /var/www/webgrind/config.php

Busca las variables $storageDir y $profilerDir y escribe:

1
2
static $storageDir = '/var/www/webgrind/tmp';
static $profilerDir = '/var/www/webgrind/tmp';

Nos aseguramos de todos los archivos tienen los permisos de grupo correctos de Apache:

1
$ sudo chown -R www-data.www-data /var/www/webgrind/

Si además queremos que no se creen archivos de depuración para el propio webgrind, creamos un archivo .htaccess en el directorio de webgrind desactivandolo:

1
php_flag xdebug.profiler_enable 0

Para entrar a la interfaz web de Webgrind, simplemente escribe en tu navegador http://localhost/webgrind/ y aparecerá disponible un listado de archivos cachegrind* donde podemos ver la traza y tiempos de depuración del perfilador:

Traza de depuración de phpinfo() con WebgrindTraza de depuración de phpinfo() con Webgrind
VN:F [1.9.22_1171]
Rating: 0.0/10 (0 votes cast)
VN:F [1.9.22_1171]
Rating: 0 (from 0 votes)





Cargado con 273 consultas en 0,999 segundos