2013-08-20 4 views
5

Ho modificato 1.c come di seguito.come accedere alla memoria allocata a processi diversi?

#include<stdio.h> 
int x=100; 
int main(void) 
{ 
    printf("%p",&x); 
    while(1); 
    return 0; 
} 

Poi ho aperto il prompt dei comandi ed eseguire questo programma e ha ottenuto uscita 00.402.000, mentre il programma ancora in esecuzione. Ora scappo 2.c

#include<stdio.h> 
int main(void) 
{ 
    int *p=(int *)0x00402000; 
    printf("%d",*p); 
    return 0; 
} 

in un'altra istanza di prompt dei comandi e ottenuto uscita -1, mi aspetto 100 che si trova in posizione 00402000. spiegare perché è questo comportamento?

+3

Nessun moderno sistema operativo multitasking consente di accedere alla memoria da altri processi. Si potrebbe voler leggere su [memoria condivisa] (http://en.wikipedia.org/wiki/Shared_memory) però. Un motivo per cui non è possibile utilizzare un'altra memoria di processo è semplicemente perché entrambi i processi hanno una propria mappa di memoria, ed è tutto [memoria virtuale] (http://en.wikipedia.org/wiki/Virtual_memory) comunque. Se hai aggiunto una variabile globale al secondo programma e hai stampato il suo indirizzo, potrebbe anche essere lo stesso indirizzo del primo processo. –

+0

Non è vero. I moduli del kernel hanno i privilegi del kernel – Magn3s1um

+1

@Joachim: dirlo all'API ReadProcessMemory. Certo che lo fa, in che altro modo dovresti eseguire il debug? È solo un'operazione privilegiata. –

risposta

11

Prima di tutto, lasciatemi dire che nei moderni sistemi operativi, i valori di indirizzo che il tuo programma vede (come 0x00402000) sono gli indirizzi fisici. Sono indirizzi virtuali, sono privati ​​del processo proprietario (cioè non hanno senso o significano qualcos'altro in altri processi) e sono mappati a indirizzi fisici tramite un meccanismo basato sulla CPU ("l'unità di paging") che solo il SO ha controllo sopra.

Se si desidera condividere una variabile tra diversi processi, esiste un meccanismo denominato memoria condivisa. Leggi su di esso. Le API pertinenti sono CreateFileMapping con il primo parametro INVALID_HANDLE_VALUE, MapViewOfFile, OpenFileMapping. Esistono anche altri modi di comunicazione tra interpreti.

Se si desidera leggere la cooperazione esplicita del processo 'memoria senza quel processo', è necessario leggere l'API di debug. Questo è un lavoro molto più complicato rispetto all'utilizzo della memoria condivisa.

Quello che hai codificato, tra l'altro, è un comportamento classico non definito.

+0

così ogni processo in memoria avrà la propria mappa di memoria virtuale? –

+1

@MSharathHegde SÌ Ogni volta che un'applicazione viene eseguita su un sistema operativo (SO), il sistema operativo crea un nuovo processo e un nuovo VAS per questo processo. –

+1

@MSharathHegde Sì. Almeno, la parte "utente" della stessa (su Windows, la metà del "kernel" della mappa della memoria virtuale è condivisa da tutti i processi) – Medinoc

1

Sembra un comportamento non definito. Dal momento che il processo di un utente è autorizzato ad accedere alla memoria che gli è stata assegnata. Così come si tenta di accedere alla memoria circa l'indirizzo, l'assegnazione di un indirizzo non valido, e si sta imbattendo in comportamento indefinito.

1

di demo il concetto spazio di indirizzamento, modificare il tuo secondo esempio a:

#include<stdio.h> 
int y = 101; 
int main(void) 
{ 
    int *p=(int *)0x00402000; // hope this works?? 
    printf("%d",*p); 

    printf("%p", p); // print value of p to ensure correct assignment 
    return 0; 
} 

Probabilmente/potrebbe stampare "101" !! Questo perché il sistema operativo considera ogni spazio indirizzo lo stesso. Quindi, la variabile globale per un int indipendentemente dal suo nome probabilmente viene allocata alla posizione 0x004002000.

+0

stampa 101 come hai detto .. –

+0

@MSharathHegde, fantastico! I computer sono davvero prevedibili !! – JackCColeman