mirror of
https://github.com/php/doc-es.git
synced 2026-03-23 23:12:09 +01:00
563 lines
20 KiB
XML
563 lines
20 KiB
XML
<?xml version="1.0" encoding="utf-8"?>
|
|
<!-- EN-Revision: d35d7d811ccf7662eefe4f23ff1cabc727a917ca Maintainer: PhilDaiguille Status: ready -->
|
|
<!-- Reviewed: yes Maintainer: Marqitos -->
|
|
<chapter xml:id="features.dtrace" xmlns="http://docbook.org/ns/docbook" xmlns:xlink="http://www.w3.org/1999/xlink">
|
|
<title>Rastreo dinámico de DTrace</title>
|
|
|
|
<sect1 xml:id="features.dtrace.introduction">
|
|
<title>Introducción a PHP y DTrace</title>
|
|
|
|
<para>
|
|
DTrace es un framework de rastreo siempre disponible, a bajo costo,
|
|
disponible en varias plataformas, incluyendo Solaris, macOS,
|
|
Oracle Linux y BSD. DTrace puede rastrear el comportamiento del sistema operativo
|
|
y la ejecución de programas de usuario. Puede mostrar los valores de los argumentos y ser
|
|
utilizado para deducir estadísticas de rendimiento. Las sondas son controladas por scripts
|
|
creados por el usuario y escritos en el lenguaje de script DTrace D. Esto
|
|
permite un análisis eficiente de los puntos de datos.
|
|
</para>
|
|
|
|
<para>
|
|
Las sondas PHP que no son activamente monitoreadas por el script DTrace
|
|
D del usuario no contienen código instrumentado, por lo que
|
|
no hay degradación del rendimiento durante la ejecución normal de la aplicación.
|
|
Las sondas que son monitoreadas tienen un costo de funcionamiento bastante bajo para
|
|
generalmente permitir la supervisión de DTrace en sistemas de producción.
|
|
</para>
|
|
|
|
<para>
|
|
PHP incorpora sondas de "Rastreo Estático Definido por el Usuario" (USDT)
|
|
que se disparan en el momento de la ejecución. Por ejemplo, cuando un script D
|
|
monitorea la sonda <literal>function-entry</literal> de PHP, entonces,
|
|
cada vez que se llama a una función del script PHP, esta sonda se dispara y
|
|
el código de acción del script D asociado se ejecuta. Este código de acción
|
|
podría, por ejemplo, imprimir los argumentos de la sonda como la ubicación del fichero
|
|
fuente de la función PHP. La acción también puede agrupar datos
|
|
como el número de veces que se llama a cada función.
|
|
</para>
|
|
|
|
<para>
|
|
Solo se describen aquí las sondas PHP USDT. Consulte la documentación externa
|
|
general y específica del sistema operativo para ver cómo
|
|
DTrace puede ser utilizado para trazar funciones arbitrarias, y cómo puede ser utilizado
|
|
para trazar el comportamiento del sistema operativo. Tenga en cuenta que no todas las funcionalidades
|
|
de DTrace están disponibles en todas las implementaciones de DTrace.
|
|
</para>
|
|
|
|
<para>
|
|
Las sondas DTrace estáticas en PHP pueden alternativamente ser utilizadas con la función
|
|
SystemTap en ciertas distribuciones Linux.
|
|
</para>
|
|
</sect1>
|
|
|
|
<sect1 xml:id="features.dtrace.dtrace">
|
|
<title>Usar PHP y DTrace</title>
|
|
<para>
|
|
PHP puede ser configurado con las sondas estáticas DTrace en las plataformas
|
|
que soportan el rastreo dinámico DTrace.
|
|
</para>
|
|
|
|
<sect2 xml:id="features.dtrace.install">
|
|
<title>Configurar PHP para las sondas estáticas de DTrace</title>
|
|
|
|
<para>
|
|
Consulte la documentación específica de la plataforma externa para habilitar
|
|
el soporte de DTrace del sistema operativo. Por ejemplo, en Oracle Linux
|
|
inicie un núcleo UEK3 y haga:
|
|
|
|
<informalexample>
|
|
<programlisting role="php">
|
|
<![CDATA[
|
|
# modprobe fasttrap
|
|
# chmod 666 /dev/dtrace/helper
|
|
]]>
|
|
</programlisting>
|
|
</informalexample>
|
|
</para>
|
|
<para>
|
|
En lugar de usar <literal>chmod</literal>, puede usar una regla de paquetado
|
|
ACL para limitar el acceso al dispositivo a un usuario específico.
|
|
</para>
|
|
|
|
<para>
|
|
Construir PHP con el parámetro de configuración <literal>--enable-dtrace</literal>:
|
|
<informalexample>
|
|
<programlisting role="php">
|
|
<![CDATA[
|
|
# ./configure --enable-dtrace ...
|
|
# make
|
|
# make install
|
|
]]>
|
|
</programlisting>
|
|
</informalexample>
|
|
</para>
|
|
<para>
|
|
Esto hace que las sondas estáticas estén disponibles en el núcleo de PHP. Todas las extensiones PHP
|
|
que proporcionen sus propias sondas deben ser construidas por separado como extensiones
|
|
compartidas.
|
|
</para>
|
|
<para>
|
|
Para habilitar las sondas, definir la variable de entorno <option>USE_ZEND_DTRACE=1</option> a los procesos PHP objetivo.
|
|
</para>
|
|
</sect2>
|
|
|
|
<sect2 xml:id="features.dtrace.static-probes">
|
|
<title>Sondas estáticas DTrace en el núcleo de PHP</title>
|
|
<table>
|
|
<title>Las siguientes sondas estáticas están disponibles en PHP</title>
|
|
<tgroup cols="2">
|
|
<thead>
|
|
<row>
|
|
<entry>Nombre de la sonda</entry>
|
|
<entry>Descripción de la sonda</entry>
|
|
<entry>Argumentos de la sonda</entry>
|
|
</row>
|
|
</thead>
|
|
<tbody>
|
|
<row>
|
|
<entry><literal>request-startup</literal></entry>
|
|
<entry>Se dispara cuando una petición comienza.</entry>
|
|
<entry>char *<varname>file</varname>, char *<varname>request_uri</varname>, char *<varname>request_method</varname></entry>
|
|
</row>
|
|
<row>
|
|
<entry><literal>request-shutdown</literal></entry>
|
|
<entry>Se dispara cuando una petición se detiene.</entry>
|
|
<entry>char *<varname>file</varname>, char *<varname>request_uri</varname>, char *<varname>request_method</varname></entry>
|
|
</row>
|
|
<row>
|
|
<entry><literal>compile-file-entry</literal></entry>
|
|
<entry>Se dispara cuando comienza la compilación de un script.</entry>
|
|
<entry>char *<varname>compile_file</varname>, char *<varname>compile_file_translated</varname></entry>
|
|
</row>
|
|
<row>
|
|
<entry><literal>compile-file-return</literal></entry>
|
|
<entry>Se dispara cuando termina la compilación de un script.</entry>
|
|
<entry>char *<varname>compile_file</varname>, char *<varname>compile_file_translated</varname></entry>
|
|
</row>
|
|
<row>
|
|
<entry><literal>execute-entry</literal></entry>
|
|
<entry>Se dispara cuando un array de opcodes debe ser ejecutado.
|
|
Por ejemplo, se dispara en llamadas de función, inclusiones y reanudaciones de
|
|
generador.</entry>
|
|
<entry>char *<varname>request_file</varname>, int <varname>lineno</varname></entry>
|
|
</row>
|
|
<row>
|
|
<entry><literal>execute-return</literal></entry>
|
|
<entry>Se dispara después de la ejecución de un array de opcodes.</entry>
|
|
<entry>char *<varname>request_file</varname>, int <varname>lineno</varname></entry>
|
|
</row>
|
|
<row>
|
|
<entry><literal>function-entry</literal></entry>
|
|
<entry>Se dispara cuando el motor de PHP entra en una función PHP o una llamada de método.</entry>
|
|
<entry>char *<varname>function_name</varname>, char *<varname>request_file</varname>, int <varname>lineno</varname>, char *<varname>classname</varname>, char *<varname>scope</varname></entry>
|
|
</row>
|
|
<row>
|
|
<entry><literal>function-return</literal></entry>
|
|
<entry>Se dispara cuando el motor PHP regresa de una función PHP o una llamada de método.</entry>
|
|
<entry>char *<varname>function_name</varname>, char *<varname>request_file</varname>, int <varname>lineno</varname>, char *<varname>classname</varname>, char *<varname>scope</varname></entry>
|
|
</row>
|
|
<row>
|
|
<entry><literal>exception-thrown</literal></entry>
|
|
<entry>Se dispara cuando se lanza una excepción.</entry>
|
|
<entry>char *<varname>classname</varname></entry>
|
|
</row>
|
|
<row>
|
|
<entry><literal>exception-caught</literal></entry>
|
|
<entry>Se dispara cuando se captura una excepción.</entry>
|
|
<entry>char *<varname>classname</varname></entry>
|
|
</row>
|
|
<row>
|
|
<entry><literal>error</literal></entry>
|
|
<entry>Se dispara cuando ocurre un error, independientemente del nivel de <link linkend="ini.error-reporting">error_reporting</link>.</entry>
|
|
<entry>char *<varname>errormsg</varname>, char *<varname>request_file</varname>, int <varname>lineno</varname></entry>
|
|
</row>
|
|
</tbody>
|
|
</tgroup>
|
|
</table>
|
|
<para>
|
|
Las extensiones PHP también pueden disponer de sondas estáticas adicionales.
|
|
</para>
|
|
</sect2>
|
|
|
|
<sect2 xml:id="features.dtrace.list-probes">
|
|
<title>Lista de sondas estáticas DTrace de PHP</title>
|
|
<para>
|
|
Para listar las sondas disponibles, inicie un proceso PHP y luego ejecute:
|
|
<informalexample>
|
|
<programlisting>
|
|
<![CDATA[
|
|
# dtrace -l
|
|
]]>
|
|
</programlisting>
|
|
</informalexample>
|
|
</para>
|
|
|
|
<para>
|
|
El resultado será similar al siguiente:
|
|
<informalexample>
|
|
<programlisting>
|
|
<![CDATA[
|
|
ID PROVIDER MODULE FUNCTION NAME
|
|
[ . . . ]
|
|
4 php15271 php dtrace_compile_file compile-file-entry
|
|
5 php15271 php dtrace_compile_file compile-file-return
|
|
6 php15271 php zend_error error
|
|
7 php15271 php ZEND_CATCH_SPEC_CONST_CV_HANDLER exception-caught
|
|
8 php15271 php zend_throw_exception_internal exception-thrown
|
|
9 php15271 php dtrace_execute_ex execute-entry
|
|
10 php15271 php dtrace_execute_internal execute-entry
|
|
11 php15271 php dtrace_execute_ex execute-return
|
|
12 php15271 php dtrace_execute_internal execute-return
|
|
13 php15271 php dtrace_execute_ex function-entry
|
|
14 php15271 php dtrace_execute_ex function-return
|
|
15 php15271 php php_request_shutdown request-shutdown
|
|
16 php15271 php php_request_startup request-startup
|
|
]]>
|
|
</programlisting>
|
|
</informalexample>
|
|
</para>
|
|
|
|
<para>
|
|
Los valores de la columna Provider son <literal>php</literal> y
|
|
el identificador del proceso PHP en ejecución.
|
|
</para>
|
|
|
|
<para>
|
|
Si el servidor web Apache está en ejecución, el nombre del módulo podría ser,
|
|
por ejemplo, <filename>libphp5.so</filename>, y habría
|
|
varios bloques de listas, uno por cada proceso Apache en ejecución.
|
|
</para>
|
|
|
|
<para>
|
|
La columna Función hace referencia a la implementación interna en C
|
|
de PHP, donde se encuentra cada proveedor.
|
|
</para>
|
|
|
|
<para>
|
|
Si no hay un proceso PHP en ejecución, no se mostrará ninguna sonda PHP.
|
|
</para>
|
|
</sect2>
|
|
|
|
<sect2 xml:id="features.dtrace.examples">
|
|
<title>DTrace con un ejemplo PHP</title>
|
|
<para>
|
|
Este ejemplo muestra los fundamentos del lenguaje de script DTrace D.
|
|
<example>
|
|
<title><filename>all_probes.d</filename> para trazar todas las sondas estáticas PHP con DTrace</title>
|
|
<programlisting>
|
|
<![CDATA[
|
|
#!/usr/sbin/dtrace -Zs
|
|
|
|
#pragma D option quiet
|
|
|
|
php*:::compile-file-entry
|
|
{
|
|
printf("PHP compile-file-entry\n");
|
|
printf(" compile_file %s\n", copyinstr(arg0));
|
|
printf(" compile_file_translated %s\n", copyinstr(arg1));
|
|
}
|
|
|
|
php*:::compile-file-return
|
|
{
|
|
printf("PHP compile-file-return\n");
|
|
printf(" compile_file %s\n", copyinstr(arg0));
|
|
printf(" compile_file_translated %s\n", copyinstr(arg1));
|
|
}
|
|
|
|
php*:::error
|
|
{
|
|
printf("PHP error\n");
|
|
printf(" errormsg %s\n", copyinstr(arg0));
|
|
printf(" request_file %s\n", copyinstr(arg1));
|
|
printf(" lineno %d\n", (int)arg2);
|
|
}
|
|
|
|
php*:::exception-caught
|
|
{
|
|
printf("PHP exception-caught\n");
|
|
printf(" classname %s\n", copyinstr(arg0));
|
|
}
|
|
|
|
php*:::exception-thrown
|
|
{
|
|
printf("PHP exception-thrown\n");
|
|
printf(" classname %s\n", copyinstr(arg0));
|
|
}
|
|
|
|
php*:::execute-entry
|
|
{
|
|
printf("PHP execute-entry\n");
|
|
printf(" request_file %s\n", copyinstr(arg0));
|
|
printf(" lineno %d\n", (int)arg1);
|
|
}
|
|
|
|
php*:::execute-return
|
|
{
|
|
printf("PHP execute-return\n");
|
|
printf(" request_file %s\n", copyinstr(arg0));
|
|
printf(" lineno %d\n", (int)arg1);
|
|
}
|
|
|
|
php*:::function-entry
|
|
{
|
|
printf("PHP function-entry\n");
|
|
printf(" function_name %s\n", copyinstr(arg0));
|
|
printf(" request_file %s\n", copyinstr(arg1));
|
|
printf(" lineno %d\n", (int)arg2);
|
|
printf(" classname %s\n", copyinstr(arg3));
|
|
printf(" scope %s\n", copyinstr(arg4));
|
|
}
|
|
|
|
php*:::function-return
|
|
{
|
|
printf("PHP function-return\n");
|
|
printf(" function_name %s\n", copyinstr(arg0));
|
|
printf(" request_file %s\n", copyinstr(arg1));
|
|
printf(" lineno %d\n", (int)arg2);
|
|
printf(" classname %s\n", copyinstr(arg3));
|
|
printf(" scope %s\n", copyinstr(arg4));
|
|
}
|
|
|
|
php*:::request-shutdown
|
|
{
|
|
printf("PHP request-shutdown\n");
|
|
printf(" file %s\n", copyinstr(arg0));
|
|
printf(" request_uri %s\n", copyinstr(arg1));
|
|
printf(" request_method %s\n", copyinstr(arg2));
|
|
}
|
|
|
|
php*:::request-startup
|
|
{
|
|
printf("PHP request-startup\n");
|
|
printf(" file %s\n", copyinstr(arg0));
|
|
printf(" request_uri %s\n", copyinstr(arg1));
|
|
printf(" request_method %s\n", copyinstr(arg2));
|
|
}
|
|
]]>
|
|
</programlisting>
|
|
</example>
|
|
</para>
|
|
|
|
<para>
|
|
Este script utiliza la opción <literal>-Z</literal> de
|
|
<filename>dtrace</filename>, lo que le permite ejecutarse cuando no hay
|
|
ningún proceso PHP en ejecución. Si se omitiera esta opción, el script
|
|
terminaría inmediatamente porque sabe que ninguna de las sondas a
|
|
monitorear existe.
|
|
</para>
|
|
|
|
<para>
|
|
El script traza todos los puntos de sondeo estáticos de PHP durante la
|
|
duración de un script PHP en ejecución. Ejecute el script D:
|
|
<informalexample>
|
|
<programlisting>
|
|
<![CDATA[
|
|
# ./all_probes.d
|
|
]]>
|
|
</programlisting>
|
|
</informalexample>
|
|
</para>
|
|
|
|
<para>
|
|
Ejecute un script o una aplicación PHP. El script D de monitoreo
|
|
mostrará los argumentos de cada sonda a medida que se dispare.
|
|
</para>
|
|
|
|
<para>
|
|
Cuando el monitoreo haya terminado, el script D puede ser interrumpido con un
|
|
<keycombo action='simul'><keycap>CTRL</keycap><keycap>C</keycap></keycombo>
|
|
</para>
|
|
|
|
<para>
|
|
En máquinas multi-CPU, el orden de las sondas puede no ser secuencial.
|
|
Esto depende del CPU que ha procesado las sondas,
|
|
y de cómo los hilos migran de un CPU a otro. La visualización de los timestamps de las sondas
|
|
permite reducir la confusión, por ejemplo :
|
|
<informalexample>
|
|
<programlisting>
|
|
<![CDATA[
|
|
php*:::function-entry
|
|
{
|
|
printf("%lld: PHP function-entry ", walltimestamp);
|
|
[ . . .]
|
|
}
|
|
]]>
|
|
</programlisting>
|
|
</informalexample>
|
|
</para>
|
|
</sect2>
|
|
|
|
<sect2 xml:id="features.dtrace.references">
|
|
&reftitle.seealso;
|
|
<simplelist>
|
|
<member><link linkend="oci8.dtrace">OCI8 y el rastreo dinámico DTrace</link></member>
|
|
</simplelist>
|
|
</sect2>
|
|
</sect1>
|
|
|
|
<sect1 xml:id="features.dtrace.systemtap">
|
|
<title>Usar SystemTap con las sondas estáticas DTrace de PHP</title>
|
|
<para>
|
|
En ciertas distribuciones Linux, la utilidad de rastreo SystemTap puede
|
|
ser utilizada para trazar las sondas estáticas DTrace de PHP. Esto está disponible con
|
|
PHP 5.4.20 y PHP 5.5.
|
|
</para>
|
|
|
|
<sect2 xml:id="features.dtrace.systemtap-install">
|
|
<title>Instalar PHP con SystemTap</title>
|
|
|
|
<para>
|
|
Instale el paquete de desarrollo SDT de SystemTap:
|
|
<informalexample>
|
|
<programlisting role="shell">
|
|
<![CDATA[
|
|
# yum install systemtap-sdt-devel
|
|
]]>
|
|
</programlisting>
|
|
</informalexample>
|
|
</para>
|
|
|
|
<para>
|
|
Instalar PHP con las sondas DTrace habilitadas:
|
|
<informalexample>
|
|
<programlisting role="shell">
|
|
<![CDATA[
|
|
# ./configure --enable-dtrace ...
|
|
# make
|
|
]]>
|
|
</programlisting>
|
|
</informalexample>
|
|
</para>
|
|
</sect2>
|
|
|
|
<sect2 xml:id="features.dtrace.systemtap-list-probes">
|
|
<title>Lista de sondas estáticas con SystemTap</title>
|
|
|
|
<para>
|
|
Las sondas estáticas en PHP pueden ser listadas utilizando <filename>stap</filename>:
|
|
<informalexample>
|
|
<programlisting>
|
|
<![CDATA[
|
|
# stap -l 'process.provider("php").mark("*")' -c 'sapi/cli/php -i'
|
|
]]>
|
|
</programlisting>
|
|
</informalexample>
|
|
</para>
|
|
|
|
<para>
|
|
Esto produce:
|
|
<informalexample>
|
|
<programlisting>
|
|
<![CDATA[
|
|
process("sapi/cli/php").provider("php").mark("compile__file__entry")
|
|
process("sapi/cli/php").provider("php").mark("compile__file__return")
|
|
process("sapi/cli/php").provider("php").mark("error")
|
|
process("sapi/cli/php").provider("php").mark("exception__caught")
|
|
process("sapi/cli/php").provider("php").mark("exception__thrown")
|
|
process("sapi/cli/php").provider("php").mark("execute__entry")
|
|
process("sapi/cli/php").provider("php").mark("execute__return")
|
|
process("sapi/cli/php").provider("php").mark("function__entry")
|
|
process("sapi/cli/php").provider("php").mark("function__return")
|
|
process("sapi/cli/php").provider("php").mark("request__shutdown")
|
|
process("sapi/cli/php").provider("php").mark("request__startup")
|
|
]]>
|
|
</programlisting>
|
|
</informalexample>
|
|
</para>
|
|
</sect2>
|
|
|
|
<sect2 xml:id="features.dtrace.systemtap-examples">
|
|
<title>SystemTap con un Ejemplo PHP</title>
|
|
|
|
<para>
|
|
<example>
|
|
<title><filename>all_probes.stp</filename> para trazar todas las sondas estáticas PHP con SystemTap</title>
|
|
<programlisting role="shell">
|
|
<![CDATA[
|
|
probe process("sapi/cli/php").provider("php").mark("compile__file__entry") {
|
|
printf("Probe compile__file__entry\n");
|
|
printf(" compile_file %s\n", user_string($arg1));
|
|
printf(" compile_file_translated %s\n", user_string($arg2));
|
|
}
|
|
probe process("sapi/cli/php").provider("php").mark("compile__file__return") {
|
|
printf("Probe compile__file__return\n");
|
|
printf(" compile_file %s\n", user_string($arg1));
|
|
printf(" compile_file_translated %s\n", user_string($arg2));
|
|
}
|
|
probe process("sapi/cli/php").provider("php").mark("error") {
|
|
printf("Probe error\n");
|
|
printf(" errormsg %s\n", user_string($arg1));
|
|
printf(" request_file %s\n", user_string($arg2));
|
|
printf(" lineno %d\n", $arg3);
|
|
}
|
|
probe process("sapi/cli/php").provider("php").mark("exception__caught") {
|
|
printf("Probe exception__caught\n");
|
|
printf(" classname %s\n", user_string($arg1));
|
|
}
|
|
probe process("sapi/cli/php").provider("php").mark("exception__thrown") {
|
|
printf("Probe exception__thrown\n");
|
|
printf(" classname %s\n", user_string($arg1));
|
|
}
|
|
probe process("sapi/cli/php").provider("php").mark("execute__entry") {
|
|
printf("Probe execute__entry\n");
|
|
printf(" request_file %s\n", user_string($arg1));
|
|
printf(" lineno %d\n", $arg2);
|
|
}
|
|
probe process("sapi/cli/php").provider("php").mark("execute__return") {
|
|
printf("Probe execute__return\n");
|
|
printf(" request_file %s\n", user_string($arg1));
|
|
printf(" lineno %d\n", $arg2);
|
|
}
|
|
probe process("sapi/cli/php").provider("php").mark("function__entry") {
|
|
printf("Probe function__entry\n");
|
|
printf(" function_name %s\n", user_string($arg1));
|
|
printf(" request_file %s\n", user_string($arg2));
|
|
printf(" lineno %d\n", $arg3);
|
|
printf(" classname %s\n", user_string($arg4));
|
|
printf(" scope %s\n", user_string($arg5));
|
|
}
|
|
probe process("sapi/cli/php").provider("php").mark("function__return") {
|
|
printf("Probe function__return: %s\n", user_string($arg1));
|
|
printf(" function_name %s\n", user_string($arg1));
|
|
printf(" request_file %s\n", user_string($arg2));
|
|
printf(" lineno %d\n", $arg3);
|
|
printf(" classname %s\n", user_string($arg4));
|
|
printf(" scope %s\n", user_string($arg5));
|
|
}
|
|
probe process("sapi/cli/php").provider("php").mark("request__shutdown") {
|
|
printf("Probe request__shutdown\n");
|
|
printf(" file %s\n", user_string($arg1));
|
|
printf(" request_uri %s\n", user_string($arg2));
|
|
printf(" request_method %s\n", user_string($arg3));
|
|
}
|
|
probe process("sapi/cli/php").provider("php").mark("request__startup") {
|
|
printf("Probe request__startup\n");
|
|
printf(" file %s\n", user_string($arg1));
|
|
printf(" request_uri %s\n", user_string($arg2));
|
|
printf(" request_method %s\n", user_string($arg3));
|
|
}
|
|
]]>
|
|
</programlisting>
|
|
</example>
|
|
</para>
|
|
<para>
|
|
El script anterior trazará todos los puntos de sondeo estáticos de PHP
|
|
durante toda la duración de la ejecución de un script PHP:
|
|
<informalexample>
|
|
<programlisting>
|
|
<![CDATA[
|
|
# stap -c 'sapi/cli/php test.php' all_probes.stp
|
|
]]>
|
|
</programlisting>
|
|
</informalexample>
|
|
</para>
|
|
</sect2>
|
|
</sect1>
|
|
</chapter>
|
|
|
|
<!-- Keep this comment at the end of the file
|
|
vim600: syn=xml fen fdm=syntax fdl=2 si
|
|
vim: et tw=78 syn=sgml
|
|
vi: ts=1 sw=1
|
|
-->
|