From 3a46bf9f378ac1c8319a76b19ad5b1fa5dd941d6 Mon Sep 17 00:00:00 2001 From: "Mr.Robb" Date: Mon, 6 Nov 2017 16:42:50 +0100 Subject: [PATCH] =?UTF-8?q?Pr=C3=A1cticas=204=20y=205?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- S4/material/Makefile.eventos | 24 ++++++ S4/material/README | 18 +++++ S4/material/ejemplo_alarm1.c | 21 ++++++ S4/material/ejemplo_alarm2.c | 49 +++++++++++++ S4/material/ejemplo_alarm3.c | 49 +++++++++++++ S4/material/ejemplo_alarm4.c | 53 ++++++++++++++ S4/material/ejemplo_waitpid.c | 78 ++++++++++++++++++++ S4/material/ejemplo_waitpid2.c | 82 +++++++++++++++++++++ S4/material/signalPerdido.c | 82 +++++++++++++++++++++ S4/practica/ejemplo_alarm2.c | 59 +++++++++++++++ S4/practica/ejemplo_alarm3.c | 55 ++++++++++++++ S4/practica/ejemplo_signal.c | 96 ++++++++++++++++++++++++ S4/practica/ejemplo_signal2.c | 117 ++++++++++++++++++++++++++++++ S4/practica/entrega.txt | 13 ++++ S4/practica/eventos.c | 63 ++++++++++++++++ S4/practica/makefile | 29 ++++++++ S4/practica/sesion04.tar.gz | Bin 0 -> 2306 bytes S4/previo/entrega.txt | 52 +++++++++++++ S5/material/Makefile | 20 +++++ S5/material/mem1.c | 50 +++++++++++++ S5/material/mem1_previo.c | 34 +++++++++ S5/material/mem2.c | 36 +++++++++ S5/material/mem2_previo.c | 64 ++++++++++++++++ S5/material/mem3_previo.c | 26 +++++++ S5/practica/Makefile | 20 +++++ S5/practica/entrega.txt | 117 ++++++++++++++++++++++++++++++ S5/practica/mem1_v2.c | 51 +++++++++++++ S5/practica/mem1_v3.c | 51 +++++++++++++ S5/previo/mem1_previo_v2.c | 36 +++++++++ S5/previo/mem2_previo_v2.c | 66 +++++++++++++++++ S5/previo/mem3_previo_v2.c | 38 ++++++++++ S5/previo/previo.txt | 129 +++++++++++++++++++++++++++++++++ 32 files changed, 1678 insertions(+) create mode 100644 S4/material/Makefile.eventos create mode 100644 S4/material/README create mode 100644 S4/material/ejemplo_alarm1.c create mode 100644 S4/material/ejemplo_alarm2.c create mode 100644 S4/material/ejemplo_alarm3.c create mode 100644 S4/material/ejemplo_alarm4.c create mode 100644 S4/material/ejemplo_waitpid.c create mode 100644 S4/material/ejemplo_waitpid2.c create mode 100644 S4/material/signalPerdido.c create mode 100644 S4/practica/ejemplo_alarm2.c create mode 100644 S4/practica/ejemplo_alarm3.c create mode 100644 S4/practica/ejemplo_signal.c create mode 100644 S4/practica/ejemplo_signal2.c create mode 100644 S4/practica/entrega.txt create mode 100644 S4/practica/eventos.c create mode 100644 S4/practica/makefile create mode 100755 S4/practica/sesion04.tar.gz create mode 100644 S4/previo/entrega.txt create mode 100644 S5/material/Makefile create mode 100644 S5/material/mem1.c create mode 100644 S5/material/mem1_previo.c create mode 100644 S5/material/mem2.c create mode 100644 S5/material/mem2_previo.c create mode 100644 S5/material/mem3_previo.c create mode 100644 S5/practica/Makefile create mode 100644 S5/practica/entrega.txt create mode 100644 S5/practica/mem1_v2.c create mode 100644 S5/practica/mem1_v3.c create mode 100644 S5/previo/mem1_previo_v2.c create mode 100644 S5/previo/mem2_previo_v2.c create mode 100644 S5/previo/mem3_previo_v2.c create mode 100644 S5/previo/previo.txt diff --git a/S4/material/Makefile.eventos b/S4/material/Makefile.eventos new file mode 100644 index 0000000..4c20574 --- /dev/null +++ b/S4/material/Makefile.eventos @@ -0,0 +1,24 @@ +all: ejemplo_waitpid ejemplo_waitpid2 alarms signalPerdido + +ejemplo_waitpid:ejemplo_waitpid.c + gcc -o ejemplo_waitpid ejemplo_waitpid.c + +ejemplo_waitpid2:ejemplo_waitpid2.c + gcc -o ejemplo_waitpid2 ejemplo_waitpid2.c + +alarms:alarm1 alarm2 alarm3 alarm4 + +alarm1:ejemplo_alarm1.c + gcc -o alarm1 ejemplo_alarm1.c +alarm2:ejemplo_alarm2.c + gcc -o alarm2 ejemplo_alarm2.c +alarm3:ejemplo_alarm3.c + gcc -o alarm3 ejemplo_alarm3.c +alarm4:ejemplo_alarm4.c + gcc -o alarm4 ejemplo_alarm4.c +signalPerdido:signalPerdido.c + gcc -o signalPerdido signalPerdido.c + +clean: + rm -rf alarm1 alarm2 alarm3 alarm4 ejemplo_waitpid ejemplo_waitpid2 signalPerdido + diff --git a/S4/material/README b/S4/material/README new file mode 100644 index 0000000..19d843d --- /dev/null +++ b/S4/material/README @@ -0,0 +1,18 @@ +COMO COMPILAR +------------- +make -f Makefile.eventos + +EJEMPLOS CON ALARMAS +-------------------- + +ejemplo_alarm1.c: alarm/sigsuspend. El programa se autoprograma un evento tipo alarma al cabo de 5 segundos. La accion por defecto de Linux es acabar el proceso. +ejemplo_alarm2.c:sigprocmask/sigaction/alarm/sigsuspend. Realizamos una accion cada X segundos. Solo es necesario reprogramar el SIGALRM una vez +ejemplo_alarm3.c:sigprocmask/sigaction/alarm/sigsuspend. Herencia de tabla de eventos +ejemplo_alarm4.c:sigprocmask/sigaction/alarm/sigsuspend. La tabla de eventos se hereda pero no los eventos pendientes + +EJEMPLO CON SIGCHLD +------------------- +ejemplo_waitpid.c: Programa que crea varios hijos y espera a que finalicen mediante un bucle de waitpid's. + +ejemplo_waitpid2.c: Programa que crea varios hijos, después ejecuta su propia tarea y después espera a que finalicen sus hijos mediante un bucle de waitpid's. + diff --git a/S4/material/ejemplo_alarm1.c b/S4/material/ejemplo_alarm1.c new file mode 100644 index 0000000..043360e --- /dev/null +++ b/S4/material/ejemplo_alarm1.c @@ -0,0 +1,21 @@ +#include +#include +#include +#include +/* ESTE PROCESO PROGRAMA UN TEMPORIZADOR PARA DENTRO DE 5 SEGUNDOS Y SE BLOQUEA A ESPERAR QUE LLEGUE */ +/* LA ACCION POR DEFECTO DEL SIGALRM ES ACABAR EL PROCESO */ +int main (int argc,char * argv[]) +{ + sigset_t mask; + + sigemptyset(&mask); + sigaddset(&mask, SIGALRM); + sigprocmask(SIG_BLOCK, &mask, NULL); + + alarm(10); + sigfillset(&mask); + sigdelset(&mask, SIGALRM); + sigdelset(&mask, SIGINT); + sigsuspend(&mask); + exit(1); +} diff --git a/S4/material/ejemplo_alarm2.c b/S4/material/ejemplo_alarm2.c new file mode 100644 index 0000000..af0ffce --- /dev/null +++ b/S4/material/ejemplo_alarm2.c @@ -0,0 +1,49 @@ +#include +#include +#include +#include +#include + +void error_y_exit(char *msg,int exit_status) +{ + perror(msg); + exit(exit_status); +} + +/* ESTA VARIABLE SE ACCEDE DESDE LA FUNCION DE ATENCION AL SIGNAL Y DESDE EL MAIN */ +int segundos=0; +/* FUNCION DE ATENCION AL SIGNAL SIGALRM */ +void funcion_alarma(int s) +{ + char buff[256]; + segundos=segundos+10; + sprintf(buff, "ALARMA pid=%d: %d segundos\n",getpid(),segundos); + write(1, buff, strlen(buff)); +} +int main (int argc,char * argv[]) +{ + struct sigaction sa; + sigset_t mask; + + sigemptyset(&mask); + sigaddset(&mask, SIGALRM); + sigprocmask(SIG_BLOCK,&mask, NULL); + + /* REPROGRAMAMOS EL SIGNAL SIGALRM */ + sa.sa_handler = &funcion_alarma; + sa.sa_flags = SA_RESTART; + sigfillset(&sa.sa_mask); + + if (sigaction(SIGALRM, &sa, NULL) < 0) error_y_exit("sigaction", 1); + + while (segundos<100) + { + alarm(10); /* Programamos la alarma para dentro de 10 segundos */ + /* Nos bloqueamos a esperar que nos llegue un evento */ + sigfillset(&mask); + sigdelset(&mask, SIGALRM); + sigdelset(&mask, SIGINT); + sigsuspend(&mask); + } + exit(1); +} diff --git a/S4/material/ejemplo_alarm3.c b/S4/material/ejemplo_alarm3.c new file mode 100644 index 0000000..8be910a --- /dev/null +++ b/S4/material/ejemplo_alarm3.c @@ -0,0 +1,49 @@ +#include +#include +#include +#include +#include + +void error_y_exit(char *msg,int exit_status) +{ + perror(msg); + exit(exit_status); +} + +int segundos=0; +void funcion_alarma(int signal) +{ + char buff[256]; + segundos=segundos+10; + sprintf(buff,"ALARMA pid=%d: %d segundos\n",getpid(),segundos); + write(1, buff, strlen(buff) ); +} + +int main (int argc,char * argv[]) +{ + struct sigaction sa; + sigset_t mask; + + /* EVITAMOS QUE NOS LLEGUE EL SIGALRM FUERA DEL SIGSUSPEND */ + sigemptyset(&mask); + sigaddset(&mask, SIGALRM); + sigprocmask(SIG_BLOCK,&mask, NULL); + + /* REPROGRAMAMOS EL SIGNAL SIGALRM */ + sa.sa_handler = &funcion_alarma; + sa.sa_flags = SA_RESTART; + sigfillset(&sa.sa_mask); + + if (sigaction(SIGALRM, &sa, NULL) < 0) error_y_exit("sigaction", 1); + + if (fork() < 0) error_y_exit("fork", 1); + while (segundos<100) + { + alarm(10); + sigfillset(&mask); + sigdelset(&mask, SIGALRM); + sigdelset(&mask, SIGINT); + sigsuspend(&mask); + } + exit(1); +} diff --git a/S4/material/ejemplo_alarm4.c b/S4/material/ejemplo_alarm4.c new file mode 100644 index 0000000..a08da42 --- /dev/null +++ b/S4/material/ejemplo_alarm4.c @@ -0,0 +1,53 @@ +#include +#include +#include +#include +#include +#include + +void error_y_exit(char *msg,int exit_status) +{ + perror(msg); + exit(exit_status); +} + +int segundos=0; +void funcion_alarma(int signal) +{ + char buff[256]; + segundos=segundos+10; + sprintf(buff,"ALARMA pid=%d: %d segundos\n",getpid(),segundos); + write(1, buff, strlen(buff) ); +} +int main (int argc,char * argv[]) +{ + struct sigaction sa; + sigset_t mask; + + /* EVITAMOS TRATAR EL SIGALRM FUERA DEL SIGSUSPEND */ + + sigemptyset(&mask); + sigaddset(&mask, SIGALRM); + sigprocmask(SIG_BLOCK,&mask, NULL); + + /* REPROGRAMAMOS EL SIGNAL SIGALRM */ + sa.sa_handler = &funcion_alarma; + sa.sa_flags = SA_RESTART; + sigfillset(&sa.sa_mask); + + if (sigaction(SIGALRM, &sa, NULL) < 0) error_y_exit("sigaction", 1); + + switch (fork()) { + case -1: error_y_exit("fork", 1); + case 0: alarm(10); + } + while (segundos<100) + { + sigfillset(&mask); + sigdelset(&mask, SIGALRM); + sigdelset(&mask, SIGINT); + sigsuspend(&mask); + alarm(10); + } + exit(1); +} diff --git a/S4/material/ejemplo_waitpid.c b/S4/material/ejemplo_waitpid.c new file mode 100644 index 0000000..947bf8f --- /dev/null +++ b/S4/material/ejemplo_waitpid.c @@ -0,0 +1,78 @@ +#include +#include +#include +#include +#include +#include + +void error_y_exit(char *msg,int exit_status) +{ + perror(msg); + exit(exit_status); +} + +void trata_alarma(int s) +{ + +} + +int main(int argc,char *argv[]) +{ + int pid,res; + char buff[256]; + int contador = 0; + int hijos=0; + struct sigaction sa; + sigset_t mask; + + /* Evitamos recibir el SIGALRM fuera del sigsuspend */ + + sigemptyset(&mask); + sigaddset(&mask,SIGALRM); + sigprocmask(SIG_BLOCK,&mask, NULL); + + for (hijos=0;hijos<10;hijos++) + { + sprintf(buff, "Creando el hijo numero %d\n", hijos); + write(1, buff, strlen(buff)); + + pid=fork(); + if (pid==0) /* Esta linea la ejecutan tanto el padre como el hijo */ + { + + sa.sa_handler = &trata_alarma; + sa.sa_flags = SA_RESTART; + sigfillset(&sa.sa_mask); + if (sigaction(SIGALRM, &sa, NULL) < 0) error_y_exit("sigaction", 1); + + /* Escribe aqui el codigo del proceso hijo */ + sprintf(buff,"Hola, soy %d\n",getpid()); + write(1, buff, strlen(buff)); + + alarm(1); + sigfillset(&mask); + sigdelset(&mask, SIGALRM); + sigdelset(&mask, SIGINT); + sigsuspend(&mask); + + /* Termina su ejecución */ + exit(0); + } else if (pid<0) + { + /* Se ha producido un error */ + error_y_exit("Error en el fork", 1); + } + } + /* Esperamos que acaben los hijos */ + while (hijos > 0) + { + pid=waitpid(-1,&res,0); + sprintf(buff,"Termina el proceso %d\n",pid); + write(1, buff, strlen(buff)); + hijos --; + contador++; + } + sprintf(buff,"Valor del contador %d\n", contador); + write(1, buff, strlen(buff)); + return 0; +} diff --git a/S4/material/ejemplo_waitpid2.c b/S4/material/ejemplo_waitpid2.c new file mode 100644 index 0000000..71106ca --- /dev/null +++ b/S4/material/ejemplo_waitpid2.c @@ -0,0 +1,82 @@ +#include +#include +#include +#include +#include +#include + +#define FIN_BUCLE 50000000ULL + +void error_y_exit(char *msg,int exit_status) +{ + perror(msg); + exit(exit_status); +} + +void hago_algo_util() +{ + unsigned long long i; + + for (i = 0; i < FIN_BUCLE; i++); +} + + +void trata_alarma(int s) +{ + +} + + +int main(int argc,char *argv[]) +{ + int pid,res; + char buff[256]; + int hijos=0; + struct sigaction sa; + sigset_t mask; + + for (hijos=0;hijos<10;hijos++) + { + sprintf(buff, "Creando el hijo numero %d\n", hijos); + write(1, buff, strlen(buff)); + + pid=fork(); + if (pid==0) /* Esta linea la ejecutan tanto el padre como el hijo */ + { + //signal (SIGALRM, trata_alarma); + + sa.sa_handler = &trata_alarma; + sa.sa_flags = SA_RESTART; + sigfillset(&sa.sa_mask); + if (sigaction(SIGALRM, &sa, NULL) < 0) error_y_exit("sigaction", 1); + + /* Escribe aqui el codigo del proceso hijo */ + sprintf(buff,"Hola, soy %d\n",getpid()); + write(1, buff, strlen(buff)); + + alarm(1); + //pause(); + sigfillset(&mask); + sigdelset(&mask, SIGALRM); + sigdelset(&mask, SIGINT); + sigsuspend(&mask); + + /* Termina su ejecución */ + exit(0); + } else if (pid<0) + { + /* Se ha producido un error */ + error_y_exit("Error en el fork", 1); + } + } + + hago_algo_util(); + + /* Esperamos que acaben el resto de hijos */ + while ((pid=waitpid(-1,&res,0)) > 0) + { + sprintf(buff,"Waitpid bloqueante. Termina %d\n",pid); + write(1, buff, strlen(buff)); + } + return 0; +} diff --git a/S4/material/signalPerdido.c b/S4/material/signalPerdido.c new file mode 100644 index 0000000..d6b56bc --- /dev/null +++ b/S4/material/signalPerdido.c @@ -0,0 +1,82 @@ +#include +#include +#include +#include +#include + +void error_y_exit(char *msg,int exit_status) +{ + perror(msg); + exit(exit_status); +} + +void trat_sigusr1(int s) { + char buf[80]; + + sprintf(buf, "Hijo: SIGUSR1 recibido \n"); + write(1, buf,strlen(buf)); +} + +void trat_sigalrm(int s) { + char buf[80]; + + sprintf(buf, "Padre: voy a mandar SIGUSR1 \n"); + write(1, buf,strlen(buf)); +} + +main(int argc, char *argv[]) { + int i,pid_h; + char buf [80]; + int delay; + struct sigaction sa, sa2; + sigset_t mask; + + if (argc !=2) { + sprintf(buf, "Usage: %s delayParent \n delayParent: 0|1\n",argv[0]); + write(2,buf,strlen(buf)); + exit(1); + } + + delay = atoi(argv[1]); + //signal (SIGUSR1, trat_sigusr1); + sa.sa_handler = &trat_sigusr1; + sa.sa_flags = SA_RESTART; + sigfillset(&sa.sa_mask); + if (sigaction(SIGUSR1, &sa, NULL) < 0) error_y_exit("sigaction", 1); + + //signal (SIGALRM, trat_sigalrm); + sa2.sa_handler = &trat_sigalrm; + sa2.sa_flags = SA_RESTART; + sigfillset(&sa2.sa_mask); + if (sigaction(SIGALRM, &sa2, NULL) < 0) error_y_exit("sigaction", 1); + + pid_h = fork (); + + if (pid_h == 0) { + sprintf(buf, "Hijo entrando al pause\n"); + write(1,buf,strlen(buf)); + //pause(); + sigfillset(&mask); + sigdelset(&mask, SIGUSR1); + sigdelset(&mask, SIGINT); + sigsuspend(&mask); + sprintf(buf, "Hijo sale del pause\n"); + write(1,buf,strlen(buf)); + } else { + if (delay) { + alarm(5); + //pause(); + sigfillset(&mask); + sigdelset(&mask, SIGALRM); + sigdelset(&mask, SIGINT); + sigsuspend(&mask); + } + sprintf(buf, "Padre manda signal SIGUSR1\n"); + write(1,buf,strlen(buf)); + if (kill (pid_h, SIGUSR1) < 0) error_y_exit("kill", 1); + waitpid(-1, NULL, 0); + sprintf(buf, "Padre sale del waitpid\n"); + write(1,buf,strlen(buf)); + } +} + diff --git a/S4/practica/ejemplo_alarm2.c b/S4/practica/ejemplo_alarm2.c new file mode 100644 index 0000000..e235f8e --- /dev/null +++ b/S4/practica/ejemplo_alarm2.c @@ -0,0 +1,59 @@ +#include +#include +#include +#include +#include + +void error_y_exit(char *msg,int exit_status) +{ + perror(msg); + exit(exit_status); +} + +/* ESTA VARIABLE SE ACCEDE DESDE LA FUNCION DE ATENCION AL SIGNAL Y DESDE EL MAIN */ +int segundos=0; +/* FUNCION DE ATENCION AL SIGNAL SIGALRM */ +void funcion_alarma(int s) +{ + char buff[256]; + if (s == SIGALRM) { + segundos=segundos+10; + sprintf(buff, "ALARMA pid=%d: %d segundos\n",getpid(),segundos); + write(1, buff, strlen(buff)); + } + else if (s == SIGUSR1) { + sprintf(buff, "SIGUSR1: reiniciando alarma -> 10 s\n"); + write(1, buff, strlen(buff)); + } + +} +int main (int argc,char * argv[]) +{ + struct sigaction sa; + sigset_t mask; + + sigemptyset(&mask); + sigaddset(&mask, SIGALRM); + sigaddset(&mask, SIGUSR1); + sigprocmask(SIG_BLOCK,&mask, NULL); + + /* REPROGRAMAMOS EL SIGNAL SIGALRM */ + sa.sa_handler = &funcion_alarma; + sa.sa_flags = SA_RESTART; + sigfillset(&sa.sa_mask); + + if (sigaction(SIGALRM, &sa, NULL) < 0) error_y_exit("sigaction", 1); + if (sigaction(SIGUSR1, &sa, NULL) < 0) error_y_exit("sigaction", 1); + + while (segundos<100) + { + alarm(10); /* Programamos la alarma para dentro de 10 segundos */ + /* Nos bloqueamos a esperar que nos llegue un evento */ + sigfillset(&mask); + sigdelset(&mask, SIGALRM); + sigdelset(&mask, SIGINT); + sigdelset(&mask, SIGUSR1); + sigsuspend(&mask); + } + exit(1); +} diff --git a/S4/practica/ejemplo_alarm3.c b/S4/practica/ejemplo_alarm3.c new file mode 100644 index 0000000..3d63473 --- /dev/null +++ b/S4/practica/ejemplo_alarm3.c @@ -0,0 +1,55 @@ +#include +#include +#include +#include +#include + +void error_y_exit(char *msg,int exit_status) +{ + perror(msg); + exit(exit_status); +} + +int segundos=0; +void funcion_alarma(int signal) +{ + char buff[256]; + segundos=segundos+10; + sprintf(buff,"ALARMA pid=%d: %d segundos\n",getpid(),segundos); + write(1, buff, strlen(buff) ); +} + +int main (int argc,char * argv[]) +{ + struct sigaction sa; + sigset_t mask; + int child_pid; + + /* EVITAMOS QUE NOS LLEGUE EL SIGALRM FUERA DEL SIGSUSPEND */ + sigemptyset(&mask); + sigaddset(&mask, SIGALRM); + sigprocmask(SIG_BLOCK,&mask, NULL); + + /* REPROGRAMAMOS EL SIGNAL SIGALRM */ + sa.sa_handler = &funcion_alarma; + sa.sa_flags = SA_RESTART; + sigfillset(&sa.sa_mask); + + child_pid = fork(); + switch (child_pid) { + case -1: error_y_exit("fork", 1); + case 0: + if (sigaction(SIGALRM, &sa, NULL) < 0) error_y_exit("sigaction", 1); + } + + while (segundos<100) + { + alarm(10); + if (child_pid == 0) execlp("sleep", "sleep", "15", (char*)0); + sigfillset(&mask); + sigdelset(&mask, SIGALRM); + sigdelset(&mask, SIGINT); + sigsuspend(&mask); + } + exit(1); +} diff --git a/S4/practica/ejemplo_signal.c b/S4/practica/ejemplo_signal.c new file mode 100644 index 0000000..21bb676 --- /dev/null +++ b/S4/practica/ejemplo_signal.c @@ -0,0 +1,96 @@ +#include +#include +#include +#include +#include +#include +#include + +void error_y_exit(char *msg,int exit_status) +{ + perror(msg); + exit(exit_status); +} + + int hijos = 0; + int contador = 0; + +void trata_alarma(int s) +{ + +} + +void trata_muerte_hijo(int s) { + if (s == SIGCHLD) { + int pid,res; + pid = waitpid(-1, &res, WNOHANG); + while(pid > 0){ + char buff[256]; + sprintf(buff,"Termina el proceso %d\n",pid); + write(1, buff, strlen(buff)); + hijos --; + contador++; + pid = waitpid(-1, &res, WNOHANG); + } + } +} + +int main(int argc,char *argv[]) +{ + int pid,res; + char buff[256]; + struct sigaction sa; + sigset_t mask; + + /* Evitamos recibir el SIGALRM fuera del sigsuspend */ + + sigemptyset(&mask); + sigaddset(&mask,SIGALRM); + sigaddset(&mask,SIGCHLD); + sigprocmask(SIG_BLOCK,&mask, NULL); + + for (hijos=0;hijos<10;hijos++) + { + sprintf(buff, "Creando el hijo numero %d\n", hijos); + write(1, buff, strlen(buff)); + + sa.sa_handler = &trata_muerte_hijo; + sa.sa_flags = SA_RESTART; + sigfillset(&sa.sa_mask); + if (sigaction(SIGCHLD, &sa, NULL) < 0) error_y_exit("sigaction", 1); + + pid=fork(); + if (pid==0) /* Esta linea la ejecutan tanto el padre como el hijo */ + { + + sa.sa_handler = &trata_alarma; + sa.sa_flags = SA_RESTART; + sigfillset(&sa.sa_mask); + if (sigaction(SIGALRM, &sa, NULL) < 0) error_y_exit("sigaction", 1); + + /* Escribe aqui el codigo del proceso hijo */ + sprintf(buff,"Hola, soy %d\n",getpid()); + write(1, buff, strlen(buff)); + + alarm(1); + sigfillset(&mask); + sigdelset(&mask, SIGALRM); + sigdelset(&mask, SIGINT); + sigsuspend(&mask); + + /* Termina su ejecución */ + exit(0); + } + else if (pid<0) error_y_exit("Error en el fork", 1); + else { + sigfillset(&sa.sa_mask); + sigdelset(&mask, SIGCHLD); + } + + } + /* Esperamos que acaben los hijos */ + while (hijos > 0) sigsuspend(&mask); + sprintf(buff,"Valor del contador %d\n", contador); + write(1, buff, strlen(buff)); + return 0; +} diff --git a/S4/practica/ejemplo_signal2.c b/S4/practica/ejemplo_signal2.c new file mode 100644 index 0000000..11c9509 --- /dev/null +++ b/S4/practica/ejemplo_signal2.c @@ -0,0 +1,117 @@ +#include +#include +#include +#include +#include +#include +#include + +int hijos = 0; +int contador = 0; +int pids[10]; + + +void error_y_exit(char *msg,int exit_status) +{ + perror(msg); + exit(exit_status); +} + +void trata_alarma(int s) +{ + +} + +void trata_muerte_hijo(int s) { + if (s == SIGCHLD) { + int pid,res; + pid = waitpid(-1, &res, WNOHANG); + while (pid > 0){ + char buff[256]; + if (WIFEXITED(res)) { + sprintf(buff,"Termina el proceso %d con exitcode %d\n",pid, WEXITSTATUS(res)); + write(1, buff, strlen(buff)); + } + else { + if (WTERMSIG(res) == SIGUSR1) { + sprintf(buff,"Termina el proceso %d por el signal USR1\n",pid); + } + else { + sprintf(buff,"Termina el proceso %d por el signal %d\n",pid, WTERMSIG(res)); + } + write(1, buff, strlen(buff)); + } + + hijos --; + contador++; + pid = waitpid(-1, &res, WNOHANG); + } + } +} + +int main(int argc,char *argv[]) +{ + int pid,res; + char buff[256]; + struct sigaction sa; + sigset_t mask; + + /* Evitamos recibir el SIGALRM fuera del sigsuspend */ + + sigemptyset(&mask); + sigaddset(&mask,SIGALRM); + sigaddset(&mask,SIGCHLD); + sigprocmask(SIG_BLOCK,&mask, NULL); + + for (hijos=0;hijos<10;hijos++) + { + sprintf(buff, "Creando el hijo numero %d\n", hijos); + write(1, buff, strlen(buff)); + + sa.sa_handler = &trata_muerte_hijo; + sa.sa_flags = SA_RESTART; + sigfillset(&sa.sa_mask); + if (sigaction(SIGCHLD, &sa, NULL) < 0) error_y_exit("sigaction", 1); + + pid=fork(); + if (pid==0) /* Esta linea la ejecutan tanto el padre como el hijo */ + { + + sa.sa_handler = &trata_alarma; + sa.sa_flags = SA_RESTART; + sigfillset(&sa.sa_mask); + if (sigaction(SIGALRM, &sa, NULL) < 0) error_y_exit("sigaction", 1); + + /* Escribe aqui el codigo del proceso hijo */ + sprintf(buff,"Hola, soy %d\n",getpid()); + write(1, buff, strlen(buff)); + + alarm(1); + sigfillset(&mask); + sigdelset(&mask, SIGALRM); + sigdelset(&mask, SIGUSR1); + sigdelset(&mask, SIGINT); + sigsuspend(&mask); + + /* Termina su ejecución */ + exit(0); + } + else if (pid<0) error_y_exit("Error en el fork", 1); + else { + pids[hijos] = pid; + sigfillset(&sa.sa_mask); + sigdelset(&mask, SIGCHLD); + } + } + /* Esperamos que acaben los hijos */ + for (int i = 0; i < 10; ++i) { + kill(pids[i], SIGUSR1); + ++contador; + } + while (hijos > 0) { + sigsuspend(&mask); + } + sprintf(buff,"Valor del contador %d\n", contador); + write(1, buff, strlen(buff)); + return 0; +} diff --git a/S4/practica/entrega.txt b/S4/practica/entrega.txt new file mode 100644 index 0000000..91600bd --- /dev/null +++ b/S4/practica/entrega.txt @@ -0,0 +1,13 @@ +PREGUNTA 28: +El padre termina el proceso porque la acción por defecto del SIGALRM es terminar. + +PREGUNTA 29: +Cuando hacemos un execlp se estable la tabla de tratamiento de signals por defecto. + +PREGUNTA 30: +Es concurrente ya que se crean todos los hijos y luego, se hacen todos los waitpid a la vez. + +PREGUNTA 31: +No, no puede, porque un proceso sólo puede enviar signals a procesos creados por el mismo usuario y grupo. +bash: kill: (7453) - Operation not permitted + diff --git a/S4/practica/eventos.c b/S4/practica/eventos.c new file mode 100644 index 0000000..e174ded --- /dev/null +++ b/S4/practica/eventos.c @@ -0,0 +1,63 @@ +#include +#include +#include +#include +#include + +void error_y_exit(char *msg,int exit_status) +{ + perror(msg); + exit(exit_status); +} + +/* ESTA VARIABLE SE ACCEDE DESDE LA FUNCION DE ATENCION AL SIGNAL Y DESDE EL MAIN */ +int segundos=0; +/* FUNCION DE ATENCION AL SIGNAL SIGALRM */ +void signals(int s) +{ + char buff[256]; + if (s == SIGALRM) { + segundos=segundos+1; + } + else if (s == SIGUSR1) { + segundos = 0; + sprintf(buff, "Reiniciar: 0 segundos\n"); + write(1, buff, strlen(buff)); + } + else if (s == SIGUSR2) { + sprintf(buff, "pid=%d: %d segundos\n",getpid(),segundos); + write(1, buff, strlen(buff)); + } +} + +int main (int argc,char * argv[]) +{ + struct sigaction sa; + sigset_t mask; + + sigemptyset(&mask); + sigaddset(&mask, SIGALRM); + sigaddset(&mask, SIGUSR1); + sigprocmask(SIG_BLOCK,&mask, NULL); + + /* REPROGRAMAMOS EL SIGNAL SIGALRM */ + sa.sa_handler = &signals; + sa.sa_flags = SA_RESTART; + sigfillset(&sa.sa_mask); + + if (sigaction(SIGALRM, &sa, NULL) < 0) error_y_exit("sigaction", 1); + if (sigaction(SIGUSR1, &sa, NULL) < 0) error_y_exit("sigaction", 1); + if (sigaction(SIGUSR2, &sa, NULL) < 0) error_y_exit("sigaction", 1); + + while (1) + { + alarm(1); /* Programamos la alarma para dentro de 10 segundos */ + /* Nos bloqueamos a esperar que nos llegue un evento */ + sigfillset(&mask); + sigdelset(&mask, SIGALRM); + sigdelset(&mask, SIGINT); + sigdelset(&mask, SIGUSR1); + sigsuspend(&mask); + } + exit(1); +} \ No newline at end of file diff --git a/S4/practica/makefile b/S4/practica/makefile new file mode 100644 index 0000000..2f2203c --- /dev/null +++ b/S4/practica/makefile @@ -0,0 +1,29 @@ +all: ejemplo_waitpid ejemplo_waitpid2 alarms signalPerdido ejemplo_signal ejemplo_signal2 eventos + +ejemplo_waitpid:ejemplo_waitpid.c + gcc -o ejemplo_waitpid ejemplo_waitpid.c + +ejemplo_waitpid2:ejemplo_waitpid2.c + gcc -o ejemplo_waitpid2 ejemplo_waitpid2.c + +alarms: alarm1 alarm2 alarm3 alarm4 + +alarm1:ejemplo_alarm1.c + gcc -o alarm1 ejemplo_alarm1.c +alarm2:ejemplo_alarm2.c + gcc -o alarm2 ejemplo_alarm2.c +alarm3:ejemplo_alarm3.c + gcc -o alarm3 ejemplo_alarm3.c +alarm4:ejemplo_alarm4.c + gcc -o alarm4 ejemplo_alarm4.c +signalPerdido:signalPerdido.c + gcc -o signalPerdido signalPerdido.c +ejemplo_signal: ejemplo_signal.c + gcc -o ejemplo_signal ejemplo_signal.c +ejemplo_signal2: ejemplo_signal2.c + gcc -o ejemplo_signal2 ejemplo_signal2.c +eventos: eventos.c + gcc -o eventos eventos.c + +clean: + rm -rf alarm1 alarm2 alarm3 alarm4 ejemplo_waitpid ejemplo_waitpid2 signalPerdido ejemplo_signal ejemplo_signal2 eventos diff --git a/S4/practica/sesion04.tar.gz b/S4/practica/sesion04.tar.gz new file mode 100755 index 0000000000000000000000000000000000000000..6704881b362ba069ea46f8d528d30ffd48e7b3d1 GIT binary patch literal 2306 zcmV+d3H|mTiwFSQf9F{M1MOH%Zyd)F)p>qJL5F}u77MNilnuxm5#F1tIw*EqsBK7PP|7Y{#MO#kvf?;YK{e`j%j@o;hc@c90N<2!hCyg0f; zN57jzlhMb{1fn~p?wi*B`n>=2{{M8G`Bkt)rZ%BjoKUc(-IQ+kb4wK-SMJ;f+jce* zb#CMFhaX3`ZcU9JS46hm?tb#=x!qzeCRH}#XKkqTZS=J%7IQj%VavWVdJ>jV-wqS7 zkzYj{wuWMlht0-^&NPmzi6Php}7Y(nj4jFazR zaA!l~c(T>Qu`h5+4oCQh6@Jy()&_pHaTT`3-{4CdJqJp_?p)iO6kqB)SHmdc`NLlH z($(@46A%~j$_D!Q=AR$m{DbZL_~u7S2PUur(}#wmcsq4$aOlJP)A~kO2|zK*E;e4^ ziVlx9Hkc?s>l#53_^`{Pr{6tWVwdl1=~h?>>~eSpiZWCJb^;1~_zK)PZE0&?3l^UY zD2F`AuGeDDDA?-myeRI^m44Yj;Yex1S_shi*abjPgFU)B*>8XllBs30HsFP+IUf>3 zn;s_9Bs_^g?BQbo|B8>p^agxI*rJPIkVHIQfE8@7U(0$6@v4Ny=j=10nR9pCn~ky8 zlTXdqy~D;Cuw`+2eGUA)FgQ!#Eghc&SKvfrVkrcb04f&Aij2ktO5F-B^Q$Qub9!bg z$0@_RW`9AQ*nWJdlqjI4>(NT_orju*oe_tk}o9sBeg#*!ci?A(@pP0}s)-#g)$)~|Yp^w;ErQJdaYHYaHkWzHui5!Nq8 zB}Wl%7Bn$lb(FQ1iF@9Iw7zA|U^PTCSg2zK?H%L4EWR{lq9`jzTAK-L z`%Ku0s&HJQ6%T`Di2i0|fo2pFA(lbZB&P6+W{+46udio_CJrjkwGtAC^o(|15EmaI zY6@)QA%3n*`G(~KJ|JyMSaXXOOZsC$#LD<3=*2b9UP{ULt&Jxd7>U`H{)nC5fGq?i zES|Xm5rmfx_Y1wP&6In$Cw-(rc30qmm^7z5CVaIcJENkwc@d1 z89s?U461^irIz5ry+Ep^Nz!0(d6G!6Od-djv<*0X1uU2JOz9|ngE)~J2leQ=m~JNh z1G~BEgqT@Hk*z0m2CY`R{q#|YPKnQP#P z+K`@zES~KCUHFQX~s>clUjor}u{d!-R*bayz;6V2yjnkxSoE8G)J@-S8(hhnhQr4xbEtm5V zU%B}L`rR*RWr5Y#$|8}jimQdJyRi!!q?l*RfK%?8r1hHI6h$S@-3yd4T#B_jskBQ? zZpb1nE!rOpd2`)|soqX6Ybj`Qfs61xsMQ)78ste-nrBE(bX+k12fVnjxy3-Bjcfq;AV^NtwbS0VkYU^<`~~6TYlYJ|Wy2%X^VK_Ch?J zI0_ub$Q83mKu_0b8=kPic852?Un0WFdC0ymN%dc&Vm0P}e3B;3COryYlbBOt9A zVyd6z`MU cu^;=fAN#Q%`>`MU@n0SP1|AGaTL35k0KtiVtN;K2 literal 0 HcmV?d00001 diff --git a/S4/previo/entrega.txt b/S4/previo/entrega.txt new file mode 100644 index 0000000..b82257f --- /dev/null +++ b/S4/previo/entrega.txt @@ -0,0 +1,52 @@ +ALARM 1 -> PREGUNTA 1: +A los 5 segundos no se imprime nada. En el código pone la línea: + + alarm(10); + +cosa que creo que no está bien ya que al principio del programa se comenta que es un temporizador de 5 segundos. Por lo tanto, debería ser "alarm(5);". Sin embargo, a los 10 segundos salta un mensaje en pantalla que pone: Alarm clock. + + +ALARM 1 -> PREGUNTA 2: +No. No termina de ejecutarse el programa. Ya que se finaliza. No se recibe el mensaje de la alarma de reloj. Se recibe el siguiente mensaje en terminal: "[1]+ Killed ./alarm1" + + +ALARM 1 -> PREGUNTA 3: +El proceso padre, es decir, el proceso que muta al ejecutable que se indique. Puesto que en el pseudo código de la shell en ningún momento aparece nada que imprima. + +La shell recoge el estado de finalización del proceso que ejecuta alarm1 con la función waitpid(pid_h, &status, 0), con la cual quedará escrito en la variable status. Esta recogerá el valor del "exit(valor)". + + +ALARM 1 -> PREGUNTA 4: +Sí, es necesario, para indicarle a la shell un error. Se ejecuta en caso de que se salga del sigsuspend por cualquier error (debido a que alarm termina el proceso directamente y nunca saldría de sigsuspend, solo en caso de error). + + +ALARM 2 -> PREGUNTA 1: +No, el proceso escribe el mensaje de los 10 segundos aunque no han pasado 10 segundos. No ha funcionado. + + +ALARM 2 -> PREGUNTA 2: +No, se pueden modificar todos los tratamientos para cualquier signal menos SIGKILL y SIGSTOP. + + +ALARM 2 -> PREGUNTA 3: +Cambiando la linea de codigo que pone: + + alarm(10); + +por: + + if (alarm(10) > 0) error_y_exit("alarm", 1); + + +ALARM 3 -> PREGUNTA 1: +Los dos reciben su propio signal. Lo he comprabado lanzando un signal (kill -ALRM pid) a cada uno de ellos y con ambos sigue funcionando. + + +ALARM 4 -> PREGUNTA 1: +Solamente el proceso padre programa un SIGALRM. Pero ambos se quedan esperando uno. Pero solo el padre (quien lo ha programado) lo recibe y por lo tanto es el único que imprime la salida. + +Lo he comprobado mandando un SIGALRM al proceso hijo y entonces empieza a funcionar el contador. En caso contrario el hijo no deja de esperar en el sigsuspend. + + +EJEMPLO_WAITPID -> PREGUNTA 1: +Hecho. \ No newline at end of file diff --git a/S5/material/Makefile b/S5/material/Makefile new file mode 100644 index 0000000..5c704a0 --- /dev/null +++ b/S5/material/Makefile @@ -0,0 +1,20 @@ +all: mem1_previo mem2_previo mem3_previo mem1 mem2 + +mem1_previo: mem1_previo.c + gcc -o mem1_previo mem1_previo.c + +mem2_previo: mem2_previo.c + gcc -o mem2_previo mem2_previo.c + +mem3_previo: mem3_previo.c + gcc -o mem3_previo mem3_previo.c + +mem1: mem1.c + gcc -o mem1 mem1.c + +mem2: mem2.c + gcc -o mem2 mem2.c + +clean: + rm -f *.o mem1_previo mem2_previo mem3_previo mem1 mem2 + diff --git a/S5/material/mem1.c b/S5/material/mem1.c new file mode 100644 index 0000000..5cedcd1 --- /dev/null +++ b/S5/material/mem1.c @@ -0,0 +1,50 @@ +#include +#include +#include + +#define DEFAULT_ITERATIONS 3 +#define REGION_SIZE 4096 + +char globalArray[REGION_SIZE]; + +int +main (int argc, char *argv[]) +{ + char buff[80]; + int niterations = DEFAULT_ITERATIONS; + int i; + char localArray[REGION_SIZE]; + char *p; + + if (argc > 2) + { + sprintf (buff, "Usage: mem1 [numMallocs]\n"); + write(2,buff,strlen(buff)); + exit (1); + } + + if (argc == 2) + { + niterations = atoi (argv[1]); + } + + sprintf (buff, "Addresses:\n"); + write(1,buff,strlen(buff)); + sprintf (buff, "\tglobalArray: %p\n", globalArray); + write(1,buff,strlen(buff)); + sprintf (buff, "\tlocalArray: %p\n", localArray); + write(1,buff,strlen(buff)); + sprintf (buff, "\tp: %p\n", &p); + write(1,buff,strlen(buff)); + + + for (i = 0; i < niterations; i++) + { + p = malloc (REGION_SIZE); + sprintf (buff, "\tp: %p, region %d: %p\n", &p, i, p); + write(1,buff,strlen(buff)); + } + + while (1); + +} diff --git a/S5/material/mem1_previo.c b/S5/material/mem1_previo.c new file mode 100644 index 0000000..fe8321f --- /dev/null +++ b/S5/material/mem1_previo.c @@ -0,0 +1,34 @@ +#include +#include +#include + +void +suma (int op1, int op2, int *res) +{ + *res = op1 + op2; +} + +int j; + +int +main (int argc, char *argv[]) +{ + int i; + int s; + char buff[80]; + + if (argc != 3) + { + sprintf (buff, "Usage: %s num1 num2\n", argv[0]); + write(2,buff,strlen(buff)); + exit (1); + } + + i = atoi (argv[1]); + j = atoi (argv[2]); + suma (i, j, &s); + sprintf (buff, "suma de %d y %d es %d\n", i, j, s); + write(1,buff,strlen(buff)); + + exit (0); +} diff --git a/S5/material/mem2.c b/S5/material/mem2.c new file mode 100644 index 0000000..b52407d --- /dev/null +++ b/S5/material/mem2.c @@ -0,0 +1,36 @@ +#include +#include +#include +#include + +#define REGION_SIZE 4096 + +int *p; + +int main(int argc, char *argv[]) +{ + int i = 0; + char buff[256]; + + sprintf( buff, "Addresses:\n"); + write(1, buff, strlen(buff)); + sprintf( buff, "\tp: %p\n", &p); + write(1, buff, strlen(buff)); + + p = malloc(sizeof(int)); + + if (p == NULL) { + sprintf(buff, "ERROR en el malloc\n"); + write(2,buff,strlen(buff)); + } + + while (1) { + *p = i; + sprintf( buff, "\tProgram code -- p address: %p, p value: %p, *p: %d\n", + &p, p, *p); + write(1, buff, strlen(buff)); + p++; + i++; + } + +} diff --git a/S5/material/mem2_previo.c b/S5/material/mem2_previo.c new file mode 100644 index 0000000..189fc5f --- /dev/null +++ b/S5/material/mem2_previo.c @@ -0,0 +1,64 @@ +#include +#include +#include +#include + + +/* readint - Devuelve un entero leido desde teclado */ +int readint(void) +{ + char buff[100]; + int x; + x = read (0, &buff, sizeof(buff)); + if (x < 0) { + perror (" ERROR leyendo numero "); + exit (0); + } + buff[x-1] = '\0'; //substituir \n por \0 + x = atoi (buff); + return x; +} + +void fillvector (int *vector, int num_elems) +{ + int i; + for (i=0; i +#include +#include +#include + +#define REGION_SIZE 4096 + +int *p; + +int main(int argc, char *argv[]) +{ + char buff[256]; + + sprintf( buff, "Addresses:\n"); + write(1, buff, strlen(buff)); + sprintf( buff, "\tp: %p\n", &p); + write(1, buff, strlen(buff)); + + *p = 5; + + sprintf( buff, "\tp Address: %p, p value: %p, *p: %d\n", &p, p, *p); + write(1, buff, strlen(buff)); + + exit(0); + +} diff --git a/S5/practica/Makefile b/S5/practica/Makefile new file mode 100644 index 0000000..5c704a0 --- /dev/null +++ b/S5/practica/Makefile @@ -0,0 +1,20 @@ +all: mem1_previo mem2_previo mem3_previo mem1 mem2 + +mem1_previo: mem1_previo.c + gcc -o mem1_previo mem1_previo.c + +mem2_previo: mem2_previo.c + gcc -o mem2_previo mem2_previo.c + +mem3_previo: mem3_previo.c + gcc -o mem3_previo mem3_previo.c + +mem1: mem1.c + gcc -o mem1 mem1.c + +mem2: mem2.c + gcc -o mem2 mem2.c + +clean: + rm -f *.o mem1_previo mem2_previo mem3_previo mem1 mem2 + diff --git a/S5/practica/entrega.txt b/S5/practica/entrega.txt new file mode 100644 index 0000000..3e8a569 --- /dev/null +++ b/S5/practica/entrega.txt @@ -0,0 +1,117 @@ +34. + +Aparecen las variables globales, es decir, el "globalArray". + +0000000000601080 B globalArray + +Está en la dirección de memoria 0000000000601080 y se encuentra dentro de la región de memoria de la BSS. + + +35. + +El número de variables que salen cuando compilamos con librerías estáticas, comparado con las que salen cuando compilamos con librerías dinámicas es mucho mayor. Puesto que también almacena dichas librerías. + +La cantidad de código en assembler también es mucho mayor, por la misma razón. + +El tamaño de los archivos es muy diferente: + mem1_dynamic -> 8896 bytes + mem1_static -> 912888 bytes + +Como he dicho antes: las salidas (nm y objdump) del ejecutable compilado con librerías estáticas es mucho mayor. Debido a que almacena el código de dichas librerías en su interior. + + +36. + +DINÁMICA +INICIAL - FINAL ETIQUETA +00400000-00401000 r-xp 00000000 08:05 450622 /home/alumne/Desktop/S5/practica/mem1_dynamic +00600000-00601000 r--p 00000000 08:05 450622 /home/alumne/Desktop/S5/practica/mem1_dynamic +00601000-00602000 rw-p 00001000 08:05 450622 /home/alumne/Desktop/S5/practica/mem1_dynamic +00602000-00603000 rw-p 00000000 00:00 0 +01c59000-01c7b000 rw-p 00000000 00:00 0 [heap] +7f50d9758000-7f50d9918000 r-xp 00000000 08:05 78815 /lib/x86_64-linux-gnu/libc-2.23.so +7f50d9918000-7f50d9b18000 ---p 001c0000 08:05 78815 /lib/x86_64-linux-gnu/libc-2.23.so +7f50d9b18000-7f50d9b1c000 r--p 001c0000 08:05 78815 /lib/x86_64-linux-gnu/libc-2.23.so +7f50d9b1c000-7f50d9b1e000 rw-p 001c4000 08:05 78815 /lib/x86_64-linux-gnu/libc-2.23.so +7f50d9b1e000-7f50d9b22000 rw-p 00000000 00:00 0 +7f50d9b22000-7f50d9b48000 r-xp 00000000 08:05 78793 /lib/x86_64-linux-gnu/ld-2.23.so +7f50d9d2a000-7f50d9d2d000 rw-p 00000000 00:00 0 +7f50d9d45000-7f50d9d47000 rw-p 00000000 00:00 0 +7f50d9d47000-7f50d9d48000 r--p 00025000 08:05 78793 /lib/x86_64-linux-gnu/ld-2.23.so +7f50d9d48000-7f50d9d49000 rw-p 00026000 08:05 78793 /lib/x86_64-linux-gnu/ld-2.23.so +7f50d9d49000-7f50d9d4a000 rw-p 00000000 00:00 0 +7ffd8f66f000-7ffd8f690000 rw-p 00000000 00:00 0 [stack] +7ffd8f6a8000-7ffd8f6aa000 r--p 00000000 00:00 0 [vvar] +7ffd8f6aa000-7ffd8f6ac000 r-xp 00000000 00:00 0 [vdso] +ffffffffff600000-ffffffffff601000 r-xp 00000000 00:00 0 [vsyscall] + +ESTÁTICA +INICIAL - FINAL ETIQUETA +00400000-004ca000 r-xp 00000000 08:05 450635 /home/alumne/Desktop/S5/practica/mem1_static +006c9000-006cc000 rw-p 000c9000 08:05 450635 /home/alumne/Desktop/S5/practica/mem1_static +006cc000-006cf000 rw-p 00000000 00:00 0 +00b6c000-00b8f000 rw-p 00000000 00:00 0 [heap] +7ffdf27fc000-7ffdf281d000 rw-p 00000000 00:00 0 [stack] +7ffdf2965000-7ffdf2967000 r--p 00000000 00:00 0 [vvar] +7ffdf2967000-7ffdf2969000 r-xp 00000000 00:00 0 [vdso] +ffffffffff600000-ffffffffff601000 r-xp 00000000 00:00 0 [vsyscall] + + +La diferencia entre ambos maps es que el maps del compilado con librerías estáticas no tiene las direcciones de memoria que referencian a las librerías dinámicas dado que las contiene en su interior. + + +37. + +El malloc guarda les dades en el heap, ja que fa una gestió avanzada del heap. +00b6c000-00b8f000 HEAP + +38. + + 3: + n_mallocs: 3 + inicial: 01f79000 + final: 01f9b000 + tamaño: 0x00022000 + + 5: + n_mallocs: 5 + inicial: 0244d000 + final: 0246f000 + tamaño: 0x00022000 + + 100: + n_mallocs: 100 + inicial: 018c7000 + final: 0194c000 + tamaño: 0x00085000 + +Cambia su tamaño de entrada entre 3 ó 5 y 100. Dado que como malloc reserva un valor predeterminado de memoria pues no hace ningún sbrk extra al incrementar de 3 a 5. Sin embargo 100 se sale de su previsión y se ve obligado a pedir más espacio de heap. + + +39. + +El tamaño del HEAP es de: +006b4000 - 00693000 = 0x00021000 +Es decir, tiene el mismo tamaño que el inicial dado que se cuando haces free, se marca el espacio de memoria del malloc como libre y se reutiliza en la siguiente iteracion del bucle. + +40. + + 3: + n_mallocs: 3 + inicial: 0142f000 + final: 01432000 + tamaño: 0x00003000 + + 5: + n_mallocs: 5 + inicial: 006dd000 + final: 006e2000 + tamaño: 0x00005000 + + 100: + n_mallocs: 100 + inicial: 00ac8000 + final: 00b2c000 + tamaño: 0x00064000 + +Cambia el tamaño dado que sbrk aumenta el heap siempre. \ No newline at end of file diff --git a/S5/practica/mem1_v2.c b/S5/practica/mem1_v2.c new file mode 100644 index 0000000..c89d05c --- /dev/null +++ b/S5/practica/mem1_v2.c @@ -0,0 +1,51 @@ +#include +#include +#include + +#define DEFAULT_ITERATIONS 3 +#define REGION_SIZE 4096 + +char globalArray[REGION_SIZE]; + +int +main (int argc, char *argv[]) +{ + char buff[80]; + int niterations = DEFAULT_ITERATIONS; + int i; + char localArray[REGION_SIZE]; + char *p; + + if (argc > 2) + { + sprintf (buff, "Usage: mem1 [numMallocs]\n"); + write(2,buff,strlen(buff)); + exit (1); + } + + if (argc == 2) + { + niterations = atoi (argv[1]); + } + + sprintf (buff, "Addresses:\n"); + write(1,buff,strlen(buff)); + sprintf (buff, "\tglobalArray: %p\n", globalArray); + write(1,buff,strlen(buff)); + sprintf (buff, "\tlocalArray: %p\n", localArray); + write(1,buff,strlen(buff)); + sprintf (buff, "\tp: %p\n", &p); + write(1,buff,strlen(buff)); + + + for (i = 0; i < niterations; i++) + { + p = malloc (REGION_SIZE); + sprintf (buff, "\tp: %p, region %d: %p\n", &p, i, p); + write(1,buff,strlen(buff)); + free(p); + } + + while (1); + +} diff --git a/S5/practica/mem1_v3.c b/S5/practica/mem1_v3.c new file mode 100644 index 0000000..46cd346 --- /dev/null +++ b/S5/practica/mem1_v3.c @@ -0,0 +1,51 @@ +#include +#include +#include + +#define DEFAULT_ITERATIONS 3 +#define REGION_SIZE 4096 + +char globalArray[REGION_SIZE]; + +int +main (int argc, char *argv[]) +{ + char buff[80]; + int niterations = DEFAULT_ITERATIONS; + int i; + char localArray[REGION_SIZE]; + char *p; + + if (argc > 2) + { + sprintf (buff, "Usage: mem1 [numMallocs]\n"); + write(2,buff,strlen(buff)); + exit (1); + } + + if (argc == 2) + { + niterations = atoi (argv[1]); + } + + sprintf (buff, "Addresses:\n"); + write(1,buff,strlen(buff)); + sprintf (buff, "\tglobalArray: %p\n", globalArray); + write(1,buff,strlen(buff)); + sprintf (buff, "\tlocalArray: %p\n", localArray); + write(1,buff,strlen(buff)); + sprintf (buff, "\tp: %p\n", &p); + write(1,buff,strlen(buff)); + + + for (i = 0; i < niterations; i++) + { + p = sbrk (REGION_SIZE); + sprintf (buff, "\tp: %p, region %d: %p\n", &p, i, p); + write(1,buff,strlen(buff)); + p = sbrk(-REGION_SIZE); + } + + while (1); + +} diff --git a/S5/previo/mem1_previo_v2.c b/S5/previo/mem1_previo_v2.c new file mode 100644 index 0000000..3484389 --- /dev/null +++ b/S5/previo/mem1_previo_v2.c @@ -0,0 +1,36 @@ +#include +#include +#include + +void +suma (int op1, int op2, int *res) +{ + *res = op1 + op2; +} + +int j; + +int +main (int argc, char *argv[]) +{ + int i; + int *s; + char buff[80]; + + if (argc != 3) + { + sprintf (buff, "Usage: %s num1 num2\n", argv[0]); + write(2,buff,strlen(buff)); + exit (1); + } + + i = atoi (argv[1]); + j = atoi (argv[2]); + + s = malloc(sizeof(int)); + suma (i, j, s); + sprintf (buff, "suma de %d y %d es %d\n", i, j, *s); + write(1,buff,strlen(buff)); + + exit (0); +} \ No newline at end of file diff --git a/S5/previo/mem2_previo_v2.c b/S5/previo/mem2_previo_v2.c new file mode 100644 index 0000000..4d1ff87 --- /dev/null +++ b/S5/previo/mem2_previo_v2.c @@ -0,0 +1,66 @@ +#include +#include +#include +#include + + +/* readint - Devuelve un entero leido desde teclado */ +int readint(void) +{ + char buff[100]; + int x; + x = read (0, &buff, sizeof(buff)); + if (x < 0) { + perror (" ERROR leyendo numero "); + exit (0); + } + buff[x-1] = '\0'; //substituir \n por \0 + x = atoi (buff); + return x; +} + +void fillvector (int *vector, int num_elems) +{ + int i; + for (i=0; i +#include +#include +#include + +#define REGION_SIZE 4096 + +int *p; + +void funcion_segmentation(int s) +{ + printf("ERROR DE MEMORIA\n"); + exit(1); +} + +int main(int argc, char *argv[]) +{ + char buff[256]; + + struct sigaction sa; + sa.sa_handler = &funcion_segmentation; + sa.sa_flags = SA_RESTART; + sigfillset(&sa.sa_mask); + sigaction(SIGSEGV, &sa, NULL); + + sprintf( buff, "Addresses:\n"); + write(1, buff, strlen(buff)); + sprintf( buff, "\tp: %p\n", &p); + write(1, buff, strlen(buff)); + + *p = 5; + + sprintf( buff, "\tp Address: %p, p value: %p, *p: %d\n", &p, p, *p); + write(1, buff, strlen(buff)); + + exit(0); + +} \ No newline at end of file diff --git a/S5/previo/previo.txt b/S5/previo/previo.txt new file mode 100644 index 0000000..504f26c --- /dev/null +++ b/S5/previo/previo.txt @@ -0,0 +1,129 @@ +Las direcciones asignadas son las que aparecen aquí a la izquierda, de todas las instrucciones del programa: + | + | + V + U atoi@@GLIBC_2.2.5 +0000000000601058 B __bss_start +0000000000601058 b completed.7585 +0000000000601048 D __data_start +0000000000601048 W data_start +0000000000400580 t deregister_tm_clones +0000000000400600 t __do_global_dtors_aux +0000000000600e18 t __do_global_dtors_aux_fini_array_entry +0000000000601050 D __dso_handle +0000000000600e28 d _DYNAMIC +0000000000601058 D _edata +0000000000601060 B _end + U exit@@GLIBC_2.2.5 +00000000004007e4 T _fini +0000000000400620 t frame_dummy +0000000000600e10 t __frame_dummy_init_array_entry +0000000000400970 r __FRAME_END__ +0000000000601000 d _GLOBAL_OFFSET_TABLE_ + w __gmon_start__ +0000000000400820 r __GNU_EH_FRAME_HDR +00000000004004a8 T _init +0000000000600e18 t __init_array_end +0000000000600e10 t __init_array_start +00000000004007f0 R _IO_stdin_used + w _ITM_deregisterTMCloneTable + w _ITM_registerTMCloneTable +000000000060105c B j +0000000000600e20 d __JCR_END__ +0000000000600e20 d __JCR_LIST__ + w _Jv_RegisterClasses +00000000004007e0 T __libc_csu_fini +0000000000400770 T __libc_csu_init + U __libc_start_main@@GLIBC_2.2.5 +0000000000400665 T main +00000000004005c0 t register_tm_clones + U sprintf@@GLIBC_2.2.5 +0000000000400550 T _start + U strlen@@GLIBC_2.2.5 +0000000000400646 T suma +0000000000601058 D __TMC_END__ + U write@@GLIBC_2.2.5 + +Los tipos de símbolos que nos muestra son: + +U -> The symbol is undefined. + +B / b -> The symbol is in the uninitialized data section (known as BSS). + +D / d -> The symbol is in the uninitialized data section (known as BSS). + +W / w -> The symbol is a weak symbol that has not been specifically tagged as a weak object symbol. When a weak defined symbol is linked with a normal defined symbol, the normal defined symbol is used with no error. When a weak undefined symbol is linked and the symbol is not defined, the value of the symbol is determined in a system-specific manner without error. On some systems, uppercase indicates that a default value has been specified. + +T / t -> The symbol is in the text (code) section. + +R / r -> The symbol is in a read only data section. + +Es posible saber la dirección de la variable j ya que es una variable global, sin embargo, no es posible saber la dirección de memoria de i ya que es una variable local y se asignará cuando se ejecute el programa. + +La j está en el BSS y la i en un espacio de memoria reservado para la memoria dinámica. + +La dirección asignada de la función suma está en la sección de código. + + +El comando usado es el siguiente: +gcc -o mem1_previo_v2 mem1_previo_v2.c -static + +mem2_previo: + 10: + + 00400000-004ca000 r-xp 00000000 08:05 468238 /home/alumne/Desktop/S5/previo/mem2_previo + 006c9000-006cc000 rw-p 000c9000 08:05 468238 /home/alumne/Desktop/S5/previo/mem2_previo + 006cc000-006f6000 rw-p 00000000 00:00 0 + 01149000-0116c000 rw-p 00000000 00:00 0 [heap] + 7ffdb4c16000-7ffdb4c37000 rw-p 00000000 00:00 0 [stack] + 7ffdb4ce4000-7ffdb4ce6000 r--p 00000000 00:00 0 [vvar] + 7ffdb4ce6000-7ffdb4ce8000 r-xp 00000000 00:00 0 [vdso] + ffffffffff600000-ffffffffff601000 r-xp 00000000 00:00 0 [vsyscall] + + HEAP -> 0116c000 - 01149000 = 0x00023000 + DATOS -> + + 40.000: + + 00400000-004ca000 r-xp 00000000 08:05 468238 /home/alumne/Desktop/S5/previo/mem2_previo + 006c9000-006cc000 rw-p 000c9000 08:05 468238 /home/alumne/Desktop/S5/previo/mem2_previo + 006cc000-006f6000 rw-p 00000000 00:00 0 + 01c25000-01c48000 rw-p 00000000 00:00 0 [heap] + 7fffe6160000-7fffe6181000 rw-p 00000000 00:00 0 [stack] + 7fffe618e000-7fffe6190000 r--p 00000000 00:00 0 [vvar] + 7fffe6190000-7fffe6192000 r-xp 00000000 00:00 0 [vdso] + ffffffffff600000-ffffffffff601000 r-xp 00000000 00:00 0 [vsyscall] + + HEAP -> 01c48000 - 01c25000 = 0x00023000 + DATOS -> + +mem2_previo_v2: + 10: + + 00400000-004ca000 r-xp 00000000 08:05 468253 /home/alumne/Desktop/S5/previo/mem2_previo_v2 + 006c9000-006cc000 rw-p 000c9000 08:05 468253 /home/alumne/Desktop/S5/previo/mem2_previo_v2 + 006cc000-006ce000 rw-p 00000000 00:00 0 + 01eb4000-01ed8000 rw-p 00000000 00:00 0 [heap] + 7ffc56ee9000-7ffc56f0a000 rw-p 00000000 00:00 0 [stack] + 7ffc56fbb000-7ffc56fbd000 r--p 00000000 00:00 0 [vvar] + 7ffc56fbd000-7ffc56fbf000 r-xp 00000000 00:00 0 [vdso] + ffffffffff600000-ffffffffff601000 r-xp 00000000 00:00 0 [vsyscall] + + HEAP -> 01ed8000 - 01eb4000 = 0x24000 + DATOS -> + + 40.000: + + 00400000-004ca000 r-xp 00000000 08:05 468253 /home/alumne/Desktop/S5/previo/mem2_previo_v2 + 006c9000-006cc000 rw-p 000c9000 08:05 468253 /home/alumne/Desktop/S5/previo/mem2_previo_v2 + 006cc000-006ce000 rw-p 00000000 00:00 0 + 00d45000-00d90000 rw-p 00000000 00:00 0 [heap] + 7ffe12da7000-7ffe12dc8000 rw-p 00000000 00:00 0 [stack] + 7ffe12ded000-7ffe12def000 r--p 00000000 00:00 0 [vvar] + 7ffe12def000-7ffe12df1000 r-xp 00000000 00:00 0 [vdso] + ffffffffff600000-ffffffffff601000 r-xp 00000000 00:00 0 [vsyscall] + + HEAP -> 00d90000 - 00d45000 = 0x4B000 + DATOS -> + +El programa con mem_previo_v2 como tiene reserva de memoria dinamica tiene unos valores diferentes en el heap mientras que el primero mantiene un valor constante debido a que la reserva de espacio es siempre la misma. \ No newline at end of file