Entender el espacio de direcciones virtual de los procesos.
El siguiente
programa,
imprime en hexadecimal la dirección virtual de diversas partes
de un programa. Ejecútelo e intente explicar los resultados.
Además mire el tamaño de los distintos segmentos del
programa con size
.
#include <stdlib.h>
#include <stdio.h>
char e1[1000], e2[1000];
char *m = "Hola amigo";
int main(void) {
char *p1 = malloc(10000);
char *p2 = malloc(10000);
printf("main %10x (%10u)\n", main, main);
printf("e1 %10x (%10u)\n", &e1, &e1);
printf("e2 %10x (%10u)\n", &e2, &e2);
printf("m %10x (%10u)\n", &m, &m);
printf("*m %10x (%10u)\n", m, m);
printf("p1 %10x (%10u)\n", &p1, &p1);
printf("p2 %10x (%10u)\n", &p2, &p2);
printf("*p1 %10x (%10u)\n", p1, p1);
printf("*p2 %10x (%10u)\n", p2, p2);
exit(0);
}
El siguiente programa, explora el espacio virtual de las direcciones que un proceso puede leer. Ejecútelo e interprete los resultados.
#include <unistd.h>
#include <stdio.h>
#include <signal.h>
#include <setjmp.h>
typedef enum {si, no, no_sabe, me_da_igual} accesibilidad;
char *dir, *dir0;
accesibilidad acc0;
int tpagina;
jmp_buf estado;
void imprime_rango(char *d1, char* d2, accesibilidad acc) {
printf("%8x-%8x (%10u-%10u) ", d1, d2, d1, d2);
if (acc == si) printf("accesible\n"); else printf("inaccesible\n");
}
void informa(accesibilidad acc) { /* Sólo imprime rangos */
if (acc0 == no_sabe) acc0 = acc;
else
if (acc != acc0) {
imprime_rango(dir0, dir-1, acc0);
dir0 = dir; acc0 = acc;
}
dir = dir + tpagina;
if (dir == NULL) {
imprime_rango(dir0, dir-1, acc);
exit(0);
}
}
void viola(int s) { /* Procesa violaciones de memoria */
informa(no);
signal(SIGSEGV, viola);
longjmp(estado, 1);
}
int main(void) {
char dato;
tpagina = getpagesize();
acc0 = no_sabe;
dir = NULL; dir0 = dir;
signal(SIGSEGV, viola); /* Etiqueta para volver de violación */
setjmp(estado);
for (;;) {
dato = *dir; /* Si es inaccesible, no se ejecuta */
informa(si);
}
}