2009-04-13 30 views
6

Estoy ejecutando una especie de "caja de arena" en C en Ubuntu: toma un programa, y ​​lo ejecuta de forma segura bajo el usuario nobody (e intercepta señales, etc.). Además, asigna límites de memoria y tiempo, y mide el uso de tiempo y memoria.
(En caso de que usted es curioso, es por una especie de "juez de línea" para marcar los programas en los datos de prueba)¿Uso de memoria de un proceso hijo?

Actualmente me he adaptado el módulo safeexec de mooshak. Aunque la mayoría de las cosas funcionan correctamente, el uso de la memoria parece ser un problema. (Es muy impreciso)

Ahora he intentado el consejo here y analicé VM desde /proc/pid/stat, y ahora el problema de precisión está solucionado. Sin embargo, para los programas que terminan muy rápido que no funciona y simplemente devuelve 0.

El programa safeexecparece que funciona de esta manera:

  1. Se fork() s
  2. Usos execv() en el proceso hijo para ejecutar el programa deseado
  3. Supervisa el programa desde el proceso principal hasta que finaliza el proceso secundario (usando wait4, que devuelve el uso de la CPU, pero no la memoria?)
    Por lo tanto, un análisis sintáctico /proc/../stat del proceso hijo (que ha sido sustituido por el execv)

¿Por qué es VM en /proc/child_pid/stat veces igual a 0?
¿Es porque el execv() finaliza demasiado rápido, y /proc/child_pid/stat simplemente no está disponible?
Si es así, ¿hay algún otro modo de obtener el uso de memoria del niño?
(Dado que esto está destinado a juzgar los programas en un límite de tiempo, no puedo pagar algo con una penalización de rendimiento como valgrind)

Gracias de antemano.

Respuesta

3

¿Puede organizar el proceso hijo para usar su propia versión de malloc() y otros y hacer que se registre el uso de la memoria HWM (quizás utilizando un controlador registrado con atexit())? Tal vez usaría LD_PRELOAD para cargar su biblioteca de gestión de memoria. Esto no ayudará con grandes arreglos estáticos o grandes arreglos automáticos.


Hmm, suena interesante. ¿Alguna forma de rastrear las matrices estáticas/automáticas?

La memoria estática se puede analizar con el comando 'tamaño' - más o menos.

Las matrices automáticas son un problema, no estoy seguro de cómo manejarlas. El código de asignación de memoria podría ver cuánta pila está en uso cuando se la llama (consulte la dirección de una variable local). Pero no hay garantía de que la memoria se asigne cuando se usa la cantidad máxima de matriz local, por lo que ofrece, en el mejor de los casos, una medida aproximada.

Otro pensamiento: quizás podría utilizar la tecnología del depurador - la llamada al sistema ptrace() - para controlar el proceso hijo, y en particular, para mantenerlo el tiempo suficiente para poder recoger las estadísticas de uso de memoria de /proc/....

+0

Hmm, suena interesante. ¿Alguna forma de rastrear las matrices estáticas/automáticas? –

+0

Wow, ptrace es realmente limpio. ¡Gracias! (Dado que ptrace hace que el proceso hijo se detenga cuando es execv() s, puedo medir el uso de la memoria tal como comienza) –

2

Puede establecer el límite de recursos duros (setrlimit para el recurso RLIMIT_AS) antes de execve(). El programa no podrá asignar más que esa cantidad de memoria. Si intenta hacerlo, las llamadas de asignación de memoria (brk, mmap, mremap) fallarán. Si el programa no maneja la condición de falta de memoria, segmentará la falla, que se reflejará en el estado de salida devuelto por wait4.

+0

Ya lo estoy haciendo - Me gustaría saber cuánto está usando en realidad, sin embargo (para comparar soluciones) –

Cuestiones relacionadas