El runtime es un "backend" que implementa unas cuantas interposiciones especiales que cooperarán con pDI-Tools para llevar a cabo con éxito la instrumentación del "software". Estas interposiciones instrumentan determinadas llamadas a GNU C Library que pueden alterar el estado de las estructuras del "Runtime Linker" y ELF, como por ejemplo la carga de un objeto compartido, o del flujo natural de la ejecución del programa, como una llamada a exit(3).
El runtime también es responsable de incorporar una rutina que asigne un identificador numérico a cada "thread", en caso de que la plataforma a la que está orientado soporte el mecanismo de interposición mediante "callback".
Seguidamente enumeramos unos cuantos casos de funciones que un runtime debería cubrir mediante definiciones o reenlaces y posteriormente explicamos como el runtime resuelve el problema antes comentado.
pDI-Tools es una herramienta que debido a su naturaleza puede verse afectada de forma indeseada por algunos componentes del sistema y/o la aplicación. Se intenta controlar los fenómenos que pueden dejar las estructuras de pDI-Tools desincronizadas respecto a la información del "Runtime Linker" aunque hay cosas que caen fuera del control de pDI-Tools como llamadas al sistema como fork(2), exit(3), exec(2), abort(3), etc. pDI-Tools no dispone de ningún mecanismo para instrumentar directamente llamadas al sistema y como mucho puede interceptar las llamadas a las librerías de C que llamarán a estas llamadas al sistema.
Por ello de la gestión de estas llamadas se encargará un módulo que llamamos runtime. Este módulo es un "backend" normal a excepción de que es el primero que se instala, que interpone el código necesario para gestionar las llamadas antes descritas. No obstante este módulo actualmente no forma parte de pDI-Tools y es obligación del programador implementarlo para sus herramientas de instrumentación.
Las funciones que debe instrumentar el runtime varían en cada sistema operativo. Aquí sólo describimos algunas de las más importantes, pero que permiten ver la naturaleza de las funciones que se deben interceptar.
fork(2) y __clone(3). Estas llamadas interesa capturarlas ya que su ejecución puede implicar cambios que alteren el funcionamiento de pDI-Tools o de los "backends". Además puede interesar partir los "log" en otros ficheros o mantener estructuras de memoria propias.
Existen algunas llamadas de algunas librerías como MPI que pueden implicar acciones como la creación o destrucción de otro proceso. Se debería cubrir también estos casos.
dlopen(3) y dlclose(3).
La ejecución de estas llamadas altera la lista de objetos
cargados en memoria. El runtime debería hacer una
llamada a _pdi_arch_refreshObjectList()
para poner al día la
réplica de pDI-Tools.
exec(2) y execve(2). Estas llamadas en el fondo son como llamar a exit(3): va implicar el cese de la aplicación y pDI-Tools y en algunos casos puede hacer falta tenerla instrumentada para forzar la finalización de pDI-Tools o simplemente para realizar algunas operaciones antes de transferir el control a otro programa.
Llamadas especiales al "Runtime Linker". El "Runtime Linker" en algunas plataformas exporta un API especial que permite modificar sus estructuras. Es deber del programador detectarlas e implementar los reenlaces adecuados para mantener pDI-Tools actualizado respecto a ellas.