¿Por qué ejecutar mapas de funciones en áreas privadas?

Sep 24 2020

Estaba leyendo un libro de texto que describe la execvefunción e como:

Supongamos que el programa que se ejecuta en el proceso actual realiza la siguiente llamada:

execve("a.out", NULL, NULL);

la función execve carga y ejecuta el programa contenido en el archivo de objeto ejecutable a.out dentro del proceso actual, reemplazando efectivamente el programa actual con el programa a.out. La carga y ejecución de a.out requiere los siguientes pasos

  1. Eliminar áreas de usuario existentes
  2. Mapa de áreas privadas. Cree nuevas estructuras de área para las áreas de código, datos, bss y pila del nuevo programa. Todas estas áreas nuevas son copia en escritura privada como:

  1. Mapa de áreas compartidas
  2. Configurar el contador del programa

Estoy un poco confundido sobre el paso 2, así que digamos que fork()bifurca un proceso hijo y deja que el proceso hijo se ejecute execvepara un nuevo programa, entonces, ¿por qué execvemapear las nuevas áreas del proceso hijo como copia en escritura privada? el proceso padre no compartirá memoria con el proceso hijo porque los procesos padre e hijo se asignan a un objeto diferente, ¿por qué el proceso hijo teme que otros procesos puedan escribir algo que lo afecte?

Respuestas

1 R..GitHubSTOPHELPINGICE Sep 25 2020 at 00:06

En este contexto, el mapeo privado se opone al mapeo compartido. Una asignación compartida de escritura del archivo requeriría acceso de escritura al archivo, y cualquier cambio que se realice se reflejaría en el disco y en todas las demás asignaciones compartidas del archivo, incluidas otras instancias del mismo programa o biblioteca. Obviamente, esto no se desea.

Eso es para las asignaciones de archivos / bibliotecas ejecutables. Para cosas como bss que no tienen respaldo de archivos (mapas "anónimos"), es posible que se pregunte por qué no se puede usar un mapeo compartido. De hecho, lo haría hasta que el proceso se bifurque, pero si se bifurca, el mapeo anónimo compartido se compartiría entre el padre y el hijo. A veces, desea hacer eso intencionalmente para los mapas con los que crea usted mismo mmap, pero no proporciona la semántica correcta para los objetos de datos globales después de la bifurcación, por lo que no se puede usar aquí.

4 ShadowRanger Sep 24 2020 at 21:30

Si observa el diagrama, la mayoría de esas páginas de "copia en escritura privada" son páginas de "demanda cero". Así es como Linux maneja las solicitudes de asignación; copia sobre escritura asigna la página cero. Entonces, si acaba de leer la página, verá que está llena de ceros, pero no ocupa memoria real en ese momento. Tan pronto como necesite escribir en él, sin problemas crea una nueva página "real" llena de ceros y le aplica su escritura.

Para el resto de ellos, como la .datasección, está mapeando los datos originales del ejecutable, pero no querrá modificar el archivo en el disco porque reasignó una variable global, así que nuevamente, se usa la copia en escritura.

Básicamente, no se trata de "copiar" una página real del programa original , es solo una estrategia para servir páginas constantemente puestas a cero al programa desde el sistema operativo y para proporcionar acceso económico a los datos del ejecutable original de una manera que permita modificaciones si es necesario.