Cómo depurar una aplicación para Android* x86 y qué herramientas usar

1. Introduction

Como ya sabemos, los desarrolladores para Android* cumplen varias funciones: son diseñadores, programadores de código y, inevitablemente, solucionadores de problemas. Es inevitable que aparezcan errores en el código y por eso es importante conocer las herramientas de depuración y saber cómo detectarlos de manera rápida y eficaz para corregirlos, ya sea que esos errores los hayamos creado nosotros o no. Por lo tanto, es esencial que los desarrolladores para Android de la actualidad dominen técnicas de depuración eficaces. En este artículo hacemos un repaso de las herramientas de depuración para aplicaciones con la idea de ayudar a los desarrolladores que recién comienzan a trabajar con el Android SDK y demás herramientas afines a entrar en ritmo más rápido y resolver defectos más eficazmente en la plataforma x86 para Android.

2. Herramientas de depuración de aplicaciones del SDK

El SDK ofrece la mayoría de las herramientas necesarias para depurar aplicaciones. Si uno quiere hacer cosas tales como seguir código paso a paso, ver valores de variables y pausar la ejecución de aplicaciones, necesita un depurador compatible con el protocolo JDWP. En caso de usar Eclipse, como ya incluye un depurador compatible con el protocolo JDWP, no es necesario instalarlo. Si se usa otro entorno de desarrollo integrado (IDE), se puede usar el depurador que venga con el IDE y vincularlo con un puerto especial para que se pueda comunicar con las máquinas virtuales de la aplicación en los dispositivos.

Si uno está desarrollando en Eclipse con el complemento ADT (herramientas de desarrollo de Android), puede usar el depurador Java* integrado, junto con el DDMS (servicio de control de depuración Dalvik), para depurar las aplicaciones. Para acceder al depurador y al DDMS, Eclipse muestra las funcionalidades de estos como perspectivas, que son vistas personalizadas de Eclipse que muestran ciertas pestañas y ventanas según la perspectiva en que se encuentra uno. Eclipse también se encarga de iniciar el daemon del host del ADB (puente de depuración de Android), por lo que no es necesario ejecutarlo manualmente. Todo aquel que depure con otro IDE puede aprovechar todas las herramientas de depuración que proporciona el SDK de Android, como ADB, DDMS, depurador Java, etc.

Figura 1. Servicio de control de depuración Dalvik

Con el DDMS, los desarrolladores pueden ver el uso de montón (heap) de un proceso, hacer un seguimiento de la asignación de memoria de objetos, trabajar con un emulador del sistema de archivos del dispositivo, examinar información de subprocesos, captar perfilados de métodos, usar la herramienta Network Traffic (en Android 4.0), usar LogCat para rastrear mensajes de código y emular operaciones y localización de teléfonos. Se puede encontrar más información en http://developer.android.com/guide/developing/debugging/ddms.html. El SDK de Android también proporciona el visor gráfico Hierarchy Viewer y la herramienta layoutopt para ayudar a los desarrolladores a depurar problemas de diseño.

La aplicación Hierarchy Viewer posibilita depurar y optimizar interfaces de usuario. Proporciona una representación visual de la jerarquía de objetos View del diseño (la ventana View Hierarchy) y una vista aumentada de la pantalla (la ventana Pixel Perfect).

Figura 2. Hierarchy Viewer

La ventana View Hierarchy muestra los objetos View que conforman la interfaz de usuario de la actividad que se está ejecutando en el dispositivo o el emulador. Se emplea para mirar objetos View individuales dentro del contexto del árbol View entero. Por cada objeto de este tipo, la ventana View Hierarchy muestra también datos de rendimiento de representación. Cuando se selecciona un nodo, aparece más información del objeto View en una ventana pequeña arriba del nodo. Al hacer clic en uno de los nodos, se ve información de la imagen, recuentos de vistas y tiempos de representación.

Figura 3. Ventana de información de objetos View

Pixel Perfect es una herramienta para examinar propiedades de píxeles y diseñar interfaces de usuario a partir de un dibujo. La ventana Pixel Perfect muestra una imagen aumentada de la pantalla actualmente visible en el emulador o el dispositivo. En ella, se pueden examinar propiedades de píxeles individuales de la imagen en pantalla. También se puede usar esta ventana para diseñar la interfaz de usuario de una aplicación a partir de un mapa de bits.

Figura 4. Ventana Pixel Perfect

La herramienta layoutopt permite analizar archivos XML que definen la interfaz de usuario de la aplicación, con el objeto de hallar ineficiencias en la jerarquía de vistas. Para ejecutar la herramienta, hay que abrir una terminal e iniciar layoutopt desde el directorio tools/ del SDK. El argumento es una lista, delimitada por espacios, de recursos que se desean analizar, ya sea archivos XML de recursos no compilados o directorios de este tipo de archivos. La herramienta carga los archivos XML especificados y analiza sus definiciones y jerarquías de acuerdo con un conjunto de reglas predefinidas. El siguiente es un ejemplo de la información de salida de la herramienta:

$ layoutopt samples/ samples/compound.xml 7:23 The root-level <FrameLayout/> can be replaced with <merge/> 11:21 This LinearLayout layout or its FrameLayout parent is useless samples/simple.xml 7:7 The root-level <FrameLayout/> can be replaced with <merge/> samples/too_deep.xml -1:-1 This layout has too many nested layouts: 13 levels, it should have <= 10! 20:81 This LinearLayout layout or its LinearLayout parent is useless 24:79 This LinearLayout layout or its LinearLayout parent is useless 28:77 This LinearLayout layout or its LinearLayout parent is useless 32:75 This LinearLayout layout or its LinearLayout parent is useless 36:73 This LinearLayout layout or its LinearLayout parent is useless 40:71 This LinearLayout layout or its LinearLayout parent is useless 44:69 This LinearLayout layout or its LinearLayout parent is useless 48:67 This LinearLayout layout or its LinearLayout parent is useless 52:65 This LinearLayout layout or its LinearLayout parent is useless 56:63 This LinearLayout layout or its LinearLayout parent is useless samples/too_many.xml 7:413 The root-level <FrameLayout/> can be replaced with <merge/> -1:-1 This layout has too many views: 81 views, it should have <= 80! samples/useless.xml 7:19 The root-level <FrameLayout/> can be replaced with <merge/> 11:17 This LinearLayout layout or its FrameLayout parent is useless

Traceview es un visor gráfico para registros de ejecución que se crea mediante el uso de la clase Debug con el fin de registrar información de rastreo en el código propio. Este visor ayuda a depurar aplicaciones y generar un perfil de su rendimiento. Traceview carga los archivos de registro y exhibe sus datos en una ventana de dos paneles en la cual se muestra la aplicación, como se puede observar en las Figuras 5 y 6.

 

Figura 5. El panel Timeline describe cuándo se ha iniciado y detenido cada método y subproceso.

Figura 6. El panel Profile incluye un resumen de todo el tiempo que se dedicó a un método.

La herramienta dmtracedump ofrece una manera distinta de generar diagramas gráficos de pila de llamadas desde los archivos de registro de rastreo. Para crear los gráficos de salida, emplea la utilidad Graphviz Dot, así que es necesario instalar Graphviz antes de ejecutar dmtracedump. Genera los datos de pila de llamadas como diagrama de árbol, en el cual cada llamada está representada como un nodo. Muestra el flujo de llamadas (desde el nodo primario a los nodos secundarios) mediante flechas. En la Figura 7 se muestra un ejemplo de diagrama generado por dmtracedump.

Figura 7. dmtracedump

3. Herramientas de depuración de aplicaciones del NDK

Como el NDK de Android está basado en la colección de herramientas del GCC, incluye el GDB, el depurador de GNU, que posibilita iniciar, poner en pausa, examinar y modificar programas. En dispositivos Android, y más generalmente en dispositivos integrados, el GDB está configurado en modo cliente/servidor. El programa se ejecuta en el dispositivo como servidor y cliente remoto. La estación de trabajo del desarrollador se conecta a él y envía comandos de depuración de manera similar a una aplicación local. El GDB mismo es una utilidad de línea de comandos y puede ser algo engorrosa de usar manualmente. Tenemos la suerte de que la mayoría de los IDE manejan el GDB, en especial CDT. Por lo tanto, se puede usar Eclipse de manera directa para agregar puntos de interrupción e inspeccionar programas, ¡pero solo si se lo ha configurado correctamente!

Por cierto, Eclipse puede insertar puntos de interrupción con facilidad en Java y archivos fuente de C/C++; solo hay que hacer clic en el margen izquierdo del editor de texto. Los puntos de interrupción de Java funcionan de forma predeterminada gracias al complemento ADT, que administra la depuración mediante el ADB. Esto no es así para CDT, que, por supuesto, no está preparado para funcionar con Android. Por lo tanto, insertar un punto de interrupción no tendrá efecto a menos que configuremos CDT para usar el GDB del NDK, el cual a su vez necesita estar enlazado a la aplicación nativa de Android para depurarla. La compatibilidad con depuradores ha ido mejorando en las últimas versiones del NDK (por ejemplo, antes no se podían depurar hilos de código nativo puro). Si bien el NDK tiene cada vez más posibilidades de uso, el NDK R5 (e incluso el R7) dista de ser perfecto. ¡Pero igualmente puede ayudar! Ahora veamos cómo depurar una aplicación nativa.

Primero, se debe habilitar el modo de depuración en su aplicación. Deben seguirse estos pasos:
1) Algo muy importante que se debe hacer, y muy fácil de olvidar, es activar el indicador de depuración en el proyecto para Android. Esto hay que hacerlo en el manifiesto de la aplicación AndroidManifest.xml. Siempre hay que usar la versión del SDK apropiada para el código nativo:

<?xml version="1.0" encoding="utf-8"?> <manifest ...> <uses-sdk android:minSdkVersion="10"/> <application ... android:debuggable="true"> ...

 

2) Al habilitarse el indicador de depuración en el manifiesto, se activa automáticamente el modo de depuración en el código nativo. Sin embargo, el indicador APP_OPTIM también controla el modo de depuración. Si lo ha establecido de forma manual en Android.mk, entonces compruebe que su valor sea debug (y no release) o simplemente elimínelo:

APP_OPTIM := debug

3) Ahora configuremos el cliente del GDB que se conectará con el dispositivo. Vuelva a compilar el proyecto y enchufe el dispositivo o inicie el emulador. Ejecute su aplicación y salga de ella. Asegúrese de que se encuentre cargada y su PID esté disponible. Para comprobarlo, puede usar el siguiente comando que mostrará la lista de procesos (en Windows, use Cygwin):

$ adb shell ps |grep gl2jni

Debe devolver una línea:

app_75 13178 1378 201108 68672 ffffffff 80118883 S com.android.gl2jni

4) Abra una ventana de terminal y vaya al directorio de su proyecto. Ejecute el comando ndk-gdb (situado en la carpeta del NDK de Android, por ejemplo android-ndk-r8\):

$ ndk-gdb

Este comando no debe devolver un mensaje, sino crear tres archivos en el directorio obj\local\x86 (obj\local\armeabi para dispositivos ARM):

  • gdb.setup: este es un archivo de configuración generado por el cliente del GDB.
  • app_process: este archivo se toma directamente de su dispositivo. Es un archivo ejecutable de sistema, que se inicia cuando arranca el sistema y se desdobla para iniciar una nueva aplicación. El GBD necesita este archivo de referencia para encontrar sus marcas. En cierto modo, es el punto de entrada binario a su aplicación.
  • libc.so: este archivo también se toma directamente de su dispositivo. Es la biblioteca C estándar de Android (conocida como biónica) que usa el GDB para realizar el seguimiento de todos los hilos nativos creados durante el tiempo de ejecución.

5) En el directorio de su proyecto, copie obj\local\x86\gdb.setup y cámbiele el nombre a gdb2.setup. Ábralo y elimine la línea siguiente que solicita al cliente del GDB que se conecte con el servidor del GDB que se ejecuta en el dispositivo (esto lo hará el propio Eclipse): target remote :5039
target remote :5039

6) En el menú principal de Eclipse, vaya a Run | Debug Configurations… y cree una nueva configuración de depuración en el elemento de la aplicación C/C++ llamado GL2JNIActivityDefault. Esta configuración iniciará el cliente del GDB en su computadora y se conectará con el servidor del GDB que se ejecuta en el dispositivo.

7) En la pestaña Main, escriba en Project el directorio de su propio proyecto y use el botón Browse para que C/C++ Application apunte a obj\local\ x86\app_process (puede usar una ruta absoluta o relativa).

Figura 8. Configuración de depuración para aplicaciones C/C++

8) Cambie el tipo de iniciador a Standard Create Process Launcher (Figura 20); para ello use el vínculo Select other… que encontrará en la parte inferior derecha de la ventana.

Figura 9. Selección del iniciador preferido

9) Vaya al archivo de depuración, establezca el tipo de depurador como gdbserver y el depurador GDB como android-ndk-r8\toolchains\x86-4.4.3\prebuilt\windows\bin\i686-android-linux-gdb.exe o android-ndk-r8\toolchains\arm-linux-androideabi-4.4.3\prebuilt\linux-x86\bin\arm-linux-androideabi-gdb para ARM. Es necesario que el archivo de comandos del GDB apunte al archivo gdb2.setup situado en \obj\local\x86 o obj\local\armeabi\ para ARM (puede usar una ruta absoluta o relativa).

Figura 10. Panel de configuración del depurador

10) Vaya a la pestaña Connection (Figura 22) y elija TCP en Type. Conserve los valores predeterminados para Host name or IP address y Port number (localhost, 5039).

Figura 11. Configuración de la conexión en el panel de configuración del depurador

11)Ahora configuremos Eclipse para ejecutar el servidor del GDB en el dispositivo. Haga una copia de android-ndk-r8\ndk-gdb y ábrala con un editor de texto. Busque la línea siguiente:
$GDBCLIENT -x `native_path $GDBSETUP`

Conviértala en comentario porque el cliente del GDB va a ser ejecutado por Eclipse mismo:

#$GDBCLIENT -x `native_path $GDBSETUP`

12) En el menú de Eclipse, vaya a Run | External Tools | External Tools
Configurations...
y cree una nueva configuración GL2JNIActivity_GDB.
Esta configuración iniciará el servidor del GDB en el dispositivo.

13) En la pestaña Main, haga que Location apunte a su ndk-gdb modificado en android-ndk-r8. Establezca como directorio de trabajo el directorio en el que se encuentra la aplicación.
Si no, configure el cuadro de texto Arguments:

  • verbose: para ver en detalle qué sucede en la consola de Eclipse.
  • force: para anular automáticamente toda sesión anterior.
  • start:para dejar que el servidor del GDB inicie la aplicación en lugar de asociarse a la aplicación después de que se la ha iniciado. Esta opción es interesante si depura solamente código nativo y no Java.

Figura 12. Configuración de herramientas externas

14) Ahora, inicie su aplicación de la manera habitual.

15) Una vez que se inicie la aplicación, puede iniciar ndk-gdb directamente por la consola o iniciar la configuración de herramienta externa GL2JNIActivity_GDB, que va a poner en marcha al servidor del GDB en el dispositivo. El servidor del GDB recibe comandos de depuración que envía el cliente del GDB remoto y depura su aplicación localmente.

16) Abra jni\gl_code.cpp y establezca un punto de interrupción en setupGraphics; para hacerlo, haga doble clic en el margen izquierdo del editor de texto (o haga clic con el botón derecho y seleccione Toggle breakpoint [alternar punto de interrupción]).

Figura 13. Establecimiento de puntos de interrupción

17) Por último, inicie la configuración de aplicación C/C++ predeterminada GL2JNIActivity para iniciar el cliente del GDB. Retransmite comandos de depuración de Eclipse CDT al servidor del GDB por una conexión de socket. Desde el punto de vista del desarrollador, esto es casi como depurar una aplicación local.

Existen también herramientas específicas para depurar el rendimiento de gráficos. El Intel® GPA System Analyzer es uno de los Analizadores de Rendimiento de Gráficos Intel® (Intel® GPA) con nueva compatibilidad para dispositivos Android basados en Intel y su finalidad es que los ingenieros de aplicaciones y controladores optimicen sus cargas de trabajo de OpenGL* ES.

En esta sección se brindan instrucciones para configurar y usar Intel GPA con su dispositivo Android mediante una conexión USB. Cuando el Analizador de Sistemas GPA de Intel está conectado a un dispositivo Android, proporciona métricas de rendimiento de OpenGL ES API, CPU y GPU, y también proporciona múltiples reemplazos de estado de pipelines de gráficos para ayudarlo a analizar el rendimiento de la aplicación OpenGL ES.

Para comenzar a recopilar métricas, necesita instalar el Analizador de Sistemas GPA de Intel en el sistema cliente y conectarlo al dispositivo de destino:

To start collecting metrics you need to install the Intel GPA System Analyzer on the client system and connect it to the target device:

1) Instale Intel GPA 2012 R3 en la máquina cliente Windows*/Linux*.

2) Inicie el Analizador de Sistemas GPA de Intel.

3) Asegúrese de que los dispositivos Android estén conectados al sistema cliente por cable USB.

4) Espere hasta 10 segundos mientras su sistema cliente detecta los dispositivos de destino. Los dispositivos encontrados aparecen en la ventana de diálogo. La lista de dispositivos de destino se actualiza cada 5 o 6 segundos.

5) Busque el dispositivo que quiera conectar y haga clic en Connect. El Analizador de Sistemas GPA de Intel copiará los componentes necesarios al dispositivo de destino y generará una lista de aplicaciones instaladas. Si desea interrumpir el proceso de conexión, haga clic en Stop.

Figura 14. Selección del dispositivo conectado

6) Seleccione la aplicación deseada de la lista de aplicaciones disponibles. La pantalla Application List (Lista de aplicaciones, Figura 26) muestra todas las aplicaciones de usuario y de sistema instaladas en el dispositivo Android.

Figura 15. Lista de aplicaciones

7) La aplicación se iniciará y usted verá sus datos en la ventana del Analizador de Sistemas GPA de Intel.

8) Para cambiar a otra aplicación, haga clic en Back. Tenga en cuenta que se forzará el cierre de la aplicación que se está ejecutando.

9) Para cambiar a otro dispositivo de destino, haga clic en Back.
La arquitectura de gráficos PowerVR consiste en los siguientes módulos principales que convierten los datos enviados de aplicaciones 3D en una imagen representada: Tile Accelerator (TA), Image Synthesis Processor (ISP) y Texture & Shading Processor (TSP). Las métricas de Intel GPA que están en el grupo “GPU” corresponden a uno de estos módulos, y el orden de las métricas en la lista de métricas (Metrics List) depende del orden de los módulos en el pipeline de gráficos (Figura 27).

Figura 16. Ventana del Analizador de Sistemas GPA de Intel

Perfes una herramienta muy útil en Linux desde la versión 2.6.30 y se la puede utilizar para análisis de rendimiento tanto de hardware como de software. Si bien Android está basado en Linux e incluye muchos componentes y bibliotecas, no incluye perf. Hay que incorporarle una perf compilada estáticamente. Si ya se cuenta con una, solo hay que ponerla en /system/bin/ y puede funcionar bien. Los interesados en una breve descripción de perf, su uso básico y una guía instructiva pueden consultar https://perf.wiki.kernel.org/index.php/Main_Page.
Con traceview, los desarrolladores pueden captar información de rendimiento de código Java; con perf, pueden obtener información de rendimiento sobre código nativo y de nivel se sistema, como se muestra en la Figura 17.

Figura 17. Estadísticas de rendimiento

Figura 18. Pila de llamadas de funciones

UxTunees una herramienta de ingeniería que permite analizar y optimizar la interacción del usuario de Android. Es una herramienta pyTimeChart mejorada.
Las características de diseño de UxTune son :

  • Correlación vertical: mapeo de eventos de sistema a través de capas a actividades de nivel de usuario (p. ej., eventos, gestos, marcos, etc.).
  • Correlación horizontal: correlación de actividades de tiempo de ejecución entre diferentes entidades de sistema (p. ej., un subproceso activa una recolección de elementos no utilizados).
  • Visualización basada en pyTimeChart.

Si el desarrollador quiere usar UxTune para analizar la capacidad de respuesta, necesita estar familiarizado con algunos procesos importantes (que se muestran como filas en pyTimeChart) del sistema Android, a saber:

  1. Fila InputReader: esta fila muestra todos los eventos táctiles con coordenadas táctiles. Y los eventos se envían a InputDispatcher.
  2. Fila InputDispatcher: InputDispatcher empaqueta eventos táctiles en serie y envía el paquete al uiThread de la aplicación.
  3. Fila uiThread: esta fila exhibe el evento táctil de encabezado del paquete recibido de InputDispatcher. uiThread dibuja (representa) su superficie de acuerdo con acciones específicas. “D” hace referencia al proceso de dibujo.
  4. Fila Surface: uiThread bloquea su Surface el comienzo el dibujo y la desbloquea cuando el dibujo ya está terminado. “S” y “E” hacen referencia al principio y el final de la representación de la aplicación.
  5. Fila SurfaceFlinger: una vez terminada la representación de la aplicación, esta informa a SurfaceFlinger que componga y actualice la pantalla. “S” hace referencia a que SurfaceFlinger comienza a controlar la solicitud de la aplicación, y “E”, que la composición está hecha (intercambio de memoria de imagen finalizado).

Figura 19. Ventana de análisis de UxTune

Meter-FPSes una herramienta para medir el valor de cuadros por segundo (fps) del sistema; intercepta las rutas de procesamiento de gráficos para obtener los registros de cada cuadro, incluidas otras métricas tales como tiempo máximo de cuadro, varianza de tiempo de cuadro, cantidad de cuadros de tiempo prolongado y tasa de presentación de cuadros. Hay dos modelos de monitorización de fps. El modelo Real Tme muestra los fps en tiempo real de todas las aplicaciones en ejecución. El modelo Measure mide los fps y otros parámetros durante períodos cuyos inicio y duración define el usuario. Cuando se utiliza esta herramienta, hay que "rootear" el dispositivo.
Establecimiento del entorno:
setprop debug.graphic_log 1
stop zygote
start zygote

La Figura 20 muestra la interfaz de configuración en la cual los desarrolladores pueden configurar la herramienta para su objetivo de depuración.

20. Configuración de Meter-FPS

En el modelo Real Time, haga clic en el botón del monitor. La herramienta fps monitorizará todas las aplicaciones que se estén ejecutando y actualizará los fps en la ventana flotante de la pantalla.

Figura 21. Modelo Real Time de Meter-FPS

En el modelo Measure, haga clic en el botón del monitor. Se mostrará una ventana flotante con "Click to start…" ("Haga clic para comenzar"); haga clic en la ventana para iniciar la monitorización.

Figura 22. Modelo Real Measure-1 de Meter-FPS

Ahora se está ejecutando el modelo Measure:

Figura 23. Modelo Real Measure-1 de Meter-FPS

Haga clic en la ventana flotante para detener la monitorización; mostrará el resultado:

Figura 24. Lista de resultados del análisis de Meter-FPS

Haga clic en cada elemento de la lista de arriba para obtener registros detallados:

Registros de detalles del análisis de Meter-FPS

Enlaces de consulta:

http://developer.android.com/guide/developing/debugging/index.html
http://www.eclipse.org/sequoyah/documentation/native_debug.php
http://mhandroid.wordpress.com/2011/01/23/using-eclipse-for-android-cc-development/
http://mhandroid.wordpress.com/2011/01/23/using-eclipse-for-android-cc-debugging/
http://packages.python.org/pytimechart/userguide.html
https://perf.wiki.kernel.org/index.php/Main_Page

Acerca del autor

Xiaodong Wang es ingeniero de aplicaciones del Grupo de Software y Servicios de Intel. Actualmente ayuda a desarrolladores independientes para plataformas basadas en Intel con sistema operativo Android. Xiaodong colaboró en el proyecto PRC Plus (asistencia a desarrolladores independientes para tabletas Android); y facilitó, como interfaz técnica, el desarrollo de aplicaciones que se encuentran entre las 50 más importantes del NDK. Más recientemente, Xiaodong ha participado en varios proyectos de innovación en Intel y desempeña un papel importante en el proceso de desarrollo. Uno de esos proyectos ha sido seleccionado como demo de las notas clave del Foro para Desarrolladores de Intel; Xiaodong cumplió una buena labor en su función de brindar apoyo técnico. Antes de sumarse a Intel, Xiaodong trabajó en MediaTek en el desarrollo de marcos de trabajo y aplicaciones. Obtuvo una maestría en la Universidad de Pekín y ha publicado un artículo técnico sobre transacciones IEEE en computadoras cuando investigaba en la Universidad Nanyang de Singapur como invitado. Los temas que más le interesan son las tecnologías de internet móvil (LBS, NFC, AR, etc.) y el diseño de innovación.

 

Notices

 

INFORMATION IN THIS DOCUMENT IS PROVIDED IN CONNECTION WITH INTEL PRODUCTS. NO LICENSE, EXPRESS OR IMPLIED, BY ESTOPPEL OR OTHERWISE, TO ANY INTELLECTUAL PROPERTY RIGHTS IS GRANTED BY THIS DOCUMENT. EXCEPT AS PROVIDED IN INTEL'S TERMS AND CONDITIONS OF SALE FOR SUCH PRODUCTS, INTEL ASSUMES NO LIABILITY WHATSOEVER AND INTEL DISCLAIMS ANY EXPRESS OR IMPLIED WARRANTY, RELATING TO SALE AND/OR USE OF INTEL PRODUCTS INCLUDING LIABILITY OR WARRANTIES RELATING TO FITNESS FOR A PARTICULAR PURPOSE, MERCHANTABILITY, OR INFRINGEMENT OF ANY PATENT, COPYRIGHT OR OTHER INTELLECTUAL PROPERTY RIGHT.

UNLESS OTHERWISE AGREED IN WRITING BY INTEL, THE INTEL PRODUCTS ARE NOT DESIGNED NOR INTENDED FOR ANY APPLICATION IN WHICH THE FAILURE OF THE INTEL PRODUCT COULD CREATE A SITUATION WHERE PERSONAL INJURY OR DEATH MAY OCCUR.

Intel may make changes to specifications and product descriptions at any time, without notice. Designers must not rely on the absence or characteristics of any features or instructions marked "reserved" or "undefined." Intel reserves these for future definition and shall have no responsibility whatsoever for conflicts or incompatibilities arising from future changes to them. The information here is subject to change without notice. Do not finalize a design with this information.

The products described in this document may contain design defects or errors known as errata which may cause the product to deviate from published specifications. Current characterized errata are available on request.

Contact your local Intel sales office or your distributor to obtain the latest specifications and before placing your product order.

Copies of documents which have an order number and are referenced in this document, or other Intel literature, may be obtained by calling 1-800-548-4725, or go to: http://www.intel.com/design/literature.htm
Software and workloads used in performance tests may have been optimized for performance only on Intel microprocessors. Performance tests, such as SYSmark and MobileMark, are measured using specific computer systems, components, software, operations, and functions. Any change to any of those factors may cause the results to vary. You should consult other information and performance tests to assist you in fully evaluating your contemplated purchases, including the performance of that product when combined with other products.
Any software source code reprinted in this document is furnished under a software license and may only be used or copied in accordance with the terms of that license. Intel and the Intel logo are trademarks of Intel Corporation in the US and/or other countries.
Copyright © 2012 Intel Corporation. All rights reserved.
*Other names and brands may be claimed as the property of others.