Il caricatore dinamico fa solo regolare vecchi open(2)
e mmap(2)
chiamate e una mappa di memoria urti refcounts inode stesso modo un fd aperta fa. Quindi se fai il solito trucco di sostituzione del file atomico per la libreria, scrivi le tue modifiche in una nuova copia del file e poi rename(2)
sopra il vecchio nome, tutto ciò che è iniziato dopo quel punto preleverà il nuovo inode e il nuovi contenuti, ma i programmi in esecuzione continueranno a utilizzare il vecchio inode e il vecchio contenuto.
Se si modifica la libreria in posizione, naturalmente tutti i programmi avviati dopo la chiamata write
rileveranno le modifiche. La domanda più interessante è che cosa succede ai processi che l'hanno già mappato. La risposta è probabilmente "il sistema non ti permetterà di farlo" o "non specificato, dipende dai dettagli dell'implementazione della cache di pagina". Poking casualmente sull'implementazione Linux (che è quello che ho a disposizione): Il caricatore dinamico glibc usa MAP_DENYWRITE
per tutte le sue mappe di libreria condivise, che non sono documentate ma suoni come se significasse "rendere questo file non modificabile mentre esiste la mappatura" . Tuttavia, non riesco a trovare nulla nei sorgenti del kernel che rende MAP_DENYWRITE
do nulla; potrebbe essere una traccia storica o qualcosa di simile.
Utilizza anche MAP_PRIVATE
. http://pubs.opengroup.org/onlinepubs/7908799/xsh/mmap.html afferma che "Non è specificato se le modifiche all'oggetto sottostante eseguite dopo che il mapping MAP_PRIVATE è stato stabilito sono visibili tramite il mapping MAP_PRIVATE." Quindi potresti o potresti non essere in grado di modificare un'immagine di una libreria condivisa sotto un processo in esecuzione, a seconda dei dettagli dell'implementazione della cache di pagina.
questo in realtà non risponde alla domanda – zwol