• Inicio
  • Novedades
  • Academia SAP
  • FAQ
  • Blog
  • Contacto
S4PCADEMY_Logo
  • Inicio
  • Novedades
  • Academia SAP
  • FAQ
  • Blog
  • Contacto
Twitter Linkedin Instagram

S4PCADEMY_Logo
  • Inicio
  • Novedades
  • Academia SAP
  • FAQ
  • Blog
  • Contacto
Twitter Linkedin Instagram
AsyncGetCallTrace  ·  openjdk  ·  Technical Articles

Validación de las API de creación de perfiles de Java | Blogs de SAP

By s4pcademy 


En mi última publicación, cubrí un error de corrección en la API fundamental de generación de perfiles de Java AsyncGetCallTrace que encontré por casualidad. Ahora la pregunta es: ¿podríamos encontrar esos errores automáticamente? Potencialmente, descubrir más errores o tener más confianza en ausencia de errores. Ya escribí código para probar la estabilidad de las API de creación de perfiles, probando la falta de errores fatales, en mi Probador de perfiles jdk proyecto. Dichas herramientas son invaluables cuando se modifica la implementación de la API o se agrega una nueva API. Esta publicación cubrirá una nueva herramienta prototípica llamada seguimiento_validación y sus conceptos fundamentales. Me concentro aquí en AsyncGetCallTrace y GetStackTrace API, pero debido a la similitud en el código, JFR debería tener propiedades de corrección similares.

La herramienta tardó mucho más en llegar a un estado utilizable; Es por eso que no escribí una publicación en el blog la semana pasada. Espero volver a estar en horario la próxima semana.

AsyncGetCallTrace y GetStackTrace

Un breve resumen de mi serie de blogs “Escribiendo un perfilador desde cero”: Ambas API devuelven el seguimiento de la pila para un subproceso determinado en un momento determinado (A llamó a B, que a su vez llamó a C, …):

AsyncGetCallTrace

La única diferencia es que AsyncGetCallTrace (ASGCT) devuelve el seguimiento de la pila en cualquier punto de la ejecución del programa y GetStackTrace (GST) solo en puntos seguros específicos, donde se define el estado de la JVM. GetStackTrace es la única API oficial para obtener seguimientos de pila, pero tiene problemas de precisión. Ambos no tienen más que unas pocas pruebas básicas en OpenJDK.

Exactitud

Pero, ¿cuándo se considera correcto el resultado de una API de creación de perfiles? Si coincide con la ejecución del programa.

Esto es difícil de comprobar si no modificamos la JVM. Pero es relativamente simple verificar casos de prueba pequeños donde la mayor parte del tiempo de ejecución se gasta en un solo método. Luego podemos verificar directamente en el código fuente si el seguimiento de la pila tiene sentido. Volveremos a esta respuesta pronto.

La idea básica para la automatización es comparar automáticamente las devoluciones de la API de creación de perfiles con las devoluciones de un oráculo. Sin embargo, lamentablemente aún no tenemos un oráculo para el AsyncGetCallTrace asíncrono, pero podemos crear uno al debilitar nuestra definición de corrección y desarrollar nuestro oráculo en varias etapas.

Debilitamiento de la definición de corrección

En la práctica, no necesitamos las API de creación de perfiles para devolver el resultado correcto en el 100 % de los casos y para todos los fotogramas del seguimiento. Los perfiladores típicos son perfiladores de muestreo y, por lo tanto, aproximan el resultado de todos modos. Esto hace que la definición de corrección sea más fácil de probar, ya que nos permite hacer el equilibrio entre factibilidad y precisión.

oráculo en capas

La idea ahora es construir nuestro oráculo en diferentes capas. Estamos comenzando con suposiciones básicas y escribiendo pruebas para verificar que la capa anterior probablemente también sea correcta. Esto nos lleva a nuestra prueba combinada de AsyncGetCallTrace asíncrono. Esto tiene la ventaja de que cada verificación es relativamente simple, lo cual es esencial porque todo el oráculo depende de cuánto confiemos en los supuestos básicos y las pruebas que verifican que una capa es correcta. Describo las capas y controles a continuación:

Diferentes capas de trace_validation

capa de tierra

Comenzamos con la suposición más básica como nuestra capa base: se puede obtener una aproximación de los seguimientos de la pila instrumentando el código de bytes en tiempo de ejecución. La idea es insertar en cada entrada de un método el método y su clase (el marco) en una pila y abrirlo en cada salida:

class A {
 void methodB() {
   // ...
 }
}

… se transforma en …

class A {
 void methodB() {
   trace.push("A", "methodB");
   // ...
   trace.pop();
 }
}

El agente de instrumentación modifica el código de bytes en tiempo de ejecución, por lo que se registra cada salida del método. Usé el gran Asistente de Java biblioteca para el trabajo pesado. Registramos toda esta información en pilas de subprocesos locales.

Esto no captura todos los métodos, porque no podemos modificar los métodos nativos implementados en C++, pero cubre la mayoría de los métodos. Esto es lo que quise decir antes con una aproximación. Un problema con esto es el costo de la instrumentación. Podemos hacer un compromiso entre precisión y utilidad instrumentando solo algunos de los métodos.

Podemos pedirle a la estructura de datos de la pila que se aproxime al seguimiento de la pila actual en medio de cada método. Estos rastros son correctos por construcción, especialmente cuando implementamos la estructura de datos de la pila en código nativo, solo exponiendo el Trace::push y Trace::pop métodos. Esto limita el reordenamiento del código por parte de la JVM.

Capa GetStackTrace

Como describí anteriormente, esta API es la API oficial para obtener los seguimientos de la pila y no se limita al recorrido básico de la pila, ya que camina solo cuando se define el estado de JVM. Por lo tanto, se podría suponer que devuelve los fotogramas correctos. Esto es lo que hice en mi publicación anterior del blog. Pero deberíamos probar esta suposición: podemos crear un nativo Trace::check que llama a GetStackTrace y verifica que todos los marcos de Trace están presentes y en el orden correcto. Las llamadas a este método se insertan después de la llamada a Trace::push al comienzo de los métodos.

Por lo general, hay más marcos presentes en el retorno de GetStackTrace, pero es seguro asumir que los atributos de corrección también se mantienen aproximadamente para todo el GetStackTrace. Por supuesto, se podría verificar la corrección de GetStackTrace en diferentes partes de los métodos. Esto probablemente sea innecesario, ya que los programas comunes de Java llaman a los métodos cada pocas instrucciones de código de bytes.

Esta capa ahora nos permite obtener los marcos que consisten en la identificación del método y la ubicación en puntos seguros.

Punto seguro Capa AsyncGetCallTrace

Ahora podemos usar la capa anterior y el hecho de que el resultado de ambas API tiene casi el mismo formato para comprobar que AsyncGetCallTrace devuelve el resultado correcto en puntos seguros. Ambas API deberían producir los mismos resultados allí. La verificación aquí es tan simple como llamar a ambas API en el método Trace::check y comparar sus resultados (omitiendo la información de ubicación ya que es menos estable). Esto tiene, por supuesto, las mismas advertencias que en la capa anterior, pero esto es aceptable, en mi opinión.

Si tiene curiosidad: la principal diferencia entre los marcos de ambas API es el número mágico que usan ASGCT y GST para indicar métodos nativos en el campo de ubicación.

Capa Async AsyncGetCallTrace

Nuestro objetivo es convencernos de que AsyncGetCallTrace es seguro en puntos no seguros, asumiendo que AsyncGetCallTrace es seguro en puntos seguros (aquí el comienzo de los métodos). La solución consta de dos partes: la pila de seguimiento, que contiene el seguimiento de la pila actual y el bucle de muestra, que llama a AsyncGetCallTrace de forma asíncrona y compara los resultados con la pila de seguimiento.

La estructura de datos de la pila de seguimiento permite empujar y sacar los seguimientos de la pila en la entrada y salida del método. Consiste en una matriz de fotogramas grandes que contiene los fotogramas actuales: el índice 0 tiene el fotograma inferior y el índice superior contiene el fotograma superior (el orden inverso en comparación con AsyncGetCallTrace). La matriz es lo suficientemente grande, aquí 1024 entradas, para almacenar seguimientos de pila de todos los tamaños relevantes. Se aumenta con un previous matriz que contiene el índice del marco superior del marco emisor transitivo más reciente del marco superior actual.

Estructura de datos de pila de seguimiento utilizada para almacenar la pila de seguimientos de pila

Suponemos aquí que el rastro de la persona que llama es un sub-rastreo del rastro actual, con solo el marco de la persona que llama que difiere en la ubicación (lineno aquí). Esto se debe a que la ubicación del marco de la persona que llama es el comienzo del método donde obtuvimos el seguimiento. Las llamadas a otros métodos tienen ubicaciones diferentes. Por lo tanto, marcamos la ubicación del cuadro superior con un número mágico para indicar que esta información cambia durante la ejecución del método.

Esto nos permite almacenar la pila de trazas de pila de forma compacta. Creamos una estructura de datos de este tipo por subproceso en el almacenamiento local de subprocesos. Esto nos permite obtener una subtraza posiblemente completa en cada punto de la ejecución, con solo la ubicación del marco superior de la subtraza diferente. Podemos usar esto para verificar la corrección de AsyncGetCallTrace en puntos arbitrarios en el tiempo:

Creamos un bucle en un subproceso separado que envía una señal a un subproceso Java en ejecución elegido al azar y usamos el controlador de señales para llamar a AsyncGetCallTrace para el subproceso Java y obtener una copia de la pila de seguimiento actual. Luego comprobamos que el resultado es el esperado. Tenga en cuenta la sincronización.

Con esto, podemos estar razonablemente seguros de que AsyncGetCallTrace es lo suficientemente correcto cuando todas las pruebas de capa se ejecutan correctamente en un punto de referencia representativo como Renacimiento. Una implementación prototípica de todo esto es mi proyecto trace_validation: se ejecuta con el encabezado actual de OpenJDK sin ningún problema, excepto por una tasa de error del 0,003 % en la última verificación (dependiendo de la configuración, pero también con dos advertencias: la última verificación todavía tiene el problema de colgarse a veces, pero espero solucionarlo en las próximas semanas, y solo lo probé en Linux x86.

Hay otra forma posible de implementar la última verificación, que no implementé (todavía) pero que aún es interesante explorar:

Una variante de la verificación Async AsyncGetCallTrace

También podemos basar esta capa en la parte superior de la capa GetStackTrace aprovechando el hecho de que GetStackTrace bloquea en puntos no seguros hasta que se alcanza un punto seguro y luego obtener el seguimiento de la pila (ver JBS). Al igual que con la otra variante de verificación, creamos un ciclo de muestra en un subproceso separado, elegimos un subproceso Java aleatorio, le enviamos una señal y luego llamamos a AsyncGetCallTrace en el controlador de señal. Pero inmediatamente después de enviar la señal, llamamos a GetStackTrace para obtener un seguimiento de la pila en el siguiente punto seguro. El seguimiento de la pila debe ser aproximadamente el mismo que el seguimiento de AsyncGetCallTrace, ya que el tiempo de demora entre sus llamadas es mínimo. Podemos comparar ambas trazas y así hacer una comprobación aproximada.

La ventaja es que no hacemos ninguna instrumentación con este enfoque y solo registramos los seguimientos de pila que realmente necesitamos. La principal desventaja es que es más aproximado, ya que la sincronización de AsyncGetCallTrace y GetStackTrace no es evidente y, de hecho, es específica de la implementación y la carga. Todavía no lo probé, pero podría hacerlo en el futuro porque la configuración debería ser lo suficientemente simple como para agregarlo a OpenJDK como un caso de prueba.

Conclusión

Le mostré en este artículo cómo podemos probar la corrección de AsyncGetCallTrace automáticamente usando un oráculo de varios niveles. La implementación difiere ligeramente y es más complicada de lo esperado debido a las peculiaridades de escribir un agente de instrumentación con un agente nativo y una biblioteca nativa.

Ahora estoy bastante seguro de que AsyncGetCallTrace es lo suficientemente correcto y espero que usted también. Por favor, pruebe el subyacente proyecto y presentar cualquier problema o sugerencia.

Esta entrada de blog es parte de mi trabajo en el máquina savia equipo en SAVIAhaciendo que la creación de perfiles sea más fácil para todos.



Source link


APIBlogsCreaciónJavalasperfilesSAPValidación

Artículos relacionados


Product Information
Wie kann ich meinen Code aus SAP Build Apps exportieren.
Personal Insights
Aumentar/disminuir los procesos de trabajo de fondo/diálogo sin reiniciar el sistema SAP
#fioriforios  ·  #mobile  ·  Product Information  ·  sap mobile services  ·  SAP Mobile Services on Cloud Foundry
SAP BTP SDK para iOS 9.1 ya está disponible

Deja tu comentario Cancelar la respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *

*

*

Estudie Sistemas de Información (Empresariales) en Alemania, Austria y Suiza (FH Aachen)
Previo
Las empresas de servicios públicos se trasladan a la nube con SAP Utilities Core Solution
Siguiente

Madrid

Calle Eloy Gonzalo, 27
Madrid, Madrid.
Código Postal 28010

México

Paseo de la Reforma 26
Colonia Juárez,  Cuauhtémoc
Ciudad de México 06600

Costa Rica

Real Cariari
Autopista General Cañas, 
San José, SJ 40104

Perú

Av. Jorge Basadre 349
San Isidro
Lima, LIM 15073

Twitter Linkedin Instagram
Copyright 2022 | All Right Reserved.
Cookies Para que este sitio funcione adecuadamente, a veces instalamos en los dispositivos de los usuarios pequeños ficheros de datos, conocidos como cookies. La mayoría de los grandes sitios web también lo hacen.
Aceptar
Cambiar ajustes
Configuración de Cookie Box
Configuración de Cookie Box

Ajustes de privacidad

Decida qué cookies quiere permitir. Puede cambiar estos ajustes en cualquier momento. Sin embargo, esto puede hacer que algunas funciones dejen de estar disponibles. Para obtener información sobre eliminar las cookies, por favor consulte la función de ayuda de su navegador. Aprenda más sobre las cookies que usamos.

Con el deslizador, puede habilitar o deshabilitar los diferentes tipos de cookies:

  • Bloquear todas
  • Essentials
  • Funcionalidad
  • Análisis
  • Publicidad

Este sitio web hará:

Este sitio web no:

  • Esencial: recuerde su configuración de permiso de cookie
  • Esencial: Permitir cookies de sesión
  • Esencial: Reúna la información que ingresa en un formulario de contacto, boletín informativo y otros formularios en todas las páginas
  • Esencial: haga un seguimiento de lo que ingresa en un carrito de compras
  • Esencial: autentica que has iniciado sesión en tu cuenta de usuario
  • Esencial: recuerda la versión de idioma que seleccionaste
  • Functionality: Remember social media settings
  • Functionality: Remember selected region and country
  • Analytics: Keep track of your visited pages and interaction taken
  • Analytics: Keep track about your location and region based on your IP number
  • Analytics: Keep track of the time spent on each page
  • Analytics: Increase the data quality of the statistics functions
  • Advertising: Tailor information and advertising to your interests based on e.g. the content you have visited before. (Currently we do not use targeting or targeting cookies.
  • Advertising: Gather personally identifiable information such as name and location
  • Recuerde sus detalles de inicio de sesión
  • Esencial: recuerde su configuración de permiso de cookie
  • Esencial: Permitir cookies de sesión
  • Esencial: Reúna la información que ingresa en un formulario de contacto, boletín informativo y otros formularios en todas las páginas
  • Esencial: haga un seguimiento de lo que ingresa en un carrito de compras
  • Esencial: autentica que has iniciado sesión en tu cuenta de usuario
  • Esencial: recuerda la versión de idioma que seleccionaste
  • Functionality: Remember social media settings
  • Functionality: Remember selected region and country
  • Analytics: Keep track of your visited pages and interaction taken
  • Analytics: Keep track about your location and region based on your IP number
  • Analytics: Keep track of the time spent on each page
  • Analytics: Increase the data quality of the statistics functions
  • Advertising: Tailor information and advertising to your interests based on e.g. the content you have visited before. (Currently we do not use targeting or targeting cookies.
  • Advertising: Gather personally identifiable information such as name and location
Guardar y cerrar