Sistemi di Calcolo

Corso di Laurea in Ingegneria Informatica e Automatica - A.A. 2017-2018

HomePage | Avvisi | Diario lezioni | Programma | Materiale didattico | Esami | Forum | Login

Revision [3317]

Last edited on 2017-11-17 17:03:32 by EmilioCoppa
Additions:
Per tracciare le system call invocate da un eseguibile in Linux possiamo utilizzare il tool ##strace##:
Deletions:
Per tracciare le system call invocate da un eseguibile possiamo utilizzare il tool ##strace##:


Revision [3316]

Edited on 2017-11-17 17:02:45 by EmilioCoppa
Additions:
printf("hello\n"); // printf utilizza internamente gli stream, che a loro volta sono implementati utilizzando i file descriptor
Deletions:
printf("hello\n"); // printf utilizza internamente gli stream che sono implementati utilizzando i file descriptor


Revision [3315]

Edited on 2017-11-17 17:01:47 by EmilioCoppa
Additions:
perror("Errore in write"); // perror permette di stampare una stringa che descrive l'errore
// prende come argomento un ulteriore stringa che viene concatenata alla descrizione dell'errore
Deletions:
perror("Errore in write"); // perror permette di stampare una stringa che spiega l'errore
// prende como un argomento un ulteriore stringa ricevuta come argomento


Revision [3314]

Edited on 2017-11-17 16:57:20 by EmilioCoppa
Additions:
Effettivamente ##printf## invoca la system call ##write##:
{{image url="https://notes.shichao.io/lkd/figure_5.1_600.png" title="write_system_call" alt="write_system_call"}}
Image credits to: [[https://notes.shichao.io/lkd/ch5/ shichao.io]]
Deletions:
Effettivamente ##printf## invoca la system call ##write##.


Revision [3313]

Edited on 2017-11-17 15:10:36 by EmilioCoppa
Additions:
Diverse funzioni definite da POSIX sono semplicemente composte da codice che innesca l'invocazione di una system call. Il meccanismo di invocazione di una system call è specifico per l'architettura e per il kernel in uso. Il meccanismo di invocazione non è stabilito dallo standard POSIX. Per scrivere codice portabile POSIX dobbiamo sempre utilizzare le API POSIX: sarranno quest'ultime a gestire l'invocazione della system call in base alla piattaforma utilizzata.
Deletions:
Diverse funzioni definite da POSIX sono semplicemente composte da codice che innesca l'invocazione di una system call. Il meccanismo di invocazione di una system call è specifico per l'architettura e per il kernel in uso. Il meccanismo di invocazione non è stabilito dallo standard POSIX. Per scrivere codice portabile POSIX dobbiamo sempre utilizzare le API POSIX che internamente innescano l'invocazione della system call.


Revision [3312]

Edited on 2017-11-17 15:07:57 by EmilioCoppa
Additions:
// prende como un argomento un ulteriore stringa ricevuta come argomento
// in questo caso emettera sullo stderr: "Errore in write: Bad file descriptor"
// dove ": Bad file descriptor" è stato aggiunto da perror in coda
// alla stringa fornita come argomento
Deletions:
// prende como un argomento un ulteriore stringa ricevuta come argomento
// in questo caso emettera sullo stderr: "Errore in write: Bad file descriptor"
// dove ": Bad file descriptor" è stato aggiunto da perror in coda
// alla stringa fornita come argomento


Revision [3311]

Edited on 2017-11-17 15:07:43 by EmilioCoppa
Additions:
perror("Errore in write"); // perror permette di stampare una stringa che spiega l'errore
// prende como un argomento un ulteriore stringa ricevuta come argomento
// in questo caso emettera sullo stderr: "Errore in write: Bad file descriptor"
// dove ": Bad file descriptor" è stato aggiunto da perror in coda
// alla stringa fornita come argomento
Deletions:
perror("Errore in write"); // perror permette di stampare una stringa che spiega l'errore
// prendo come un argomento un ulteriore stringa ricevuta come argomento
// in questo caso emettera sullo stderr: "Errore in write: Bad file descriptor"
// dove ": Bad file descriptor" è stato aggiunto da perror in coda
// alla stringa fornita come argomento


Revision [3309]

Edited on 2017-11-17 15:00:55 by EmilioCoppa
Additions:
Il meccanismo di invocazione di una system call in Linux è specificato in ##man syscall##, sezione ##Architecture calling conventions##.
Le system call implementate da Linux sono elencate in un header del kernel:
Deletions:
Il meccanismo di invocazione di una system call in Linux è specificato in ##man syscall##, sezione ##Architecture calling conventions##. L'id numerico delle system call offerte da Linux possono essere visualizzate con:


Revision [3308]

Edited on 2017-11-17 14:59:29 by EmilioCoppa
Additions:
== Stream ==
== File Descriptors ==
Deletions:
==== Stream ====
==== File Descriptors ====


Revision [3307]

Edited on 2017-11-17 14:58:58 by EmilioCoppa
Additions:
== Invocazione di una system call in x86 Linux ==
Deletions:
==== Invocazione di una system call in x86 Linux ====


Revision [3306]

Edited on 2017-11-17 14:58:02 by EmilioCoppa
Additions:
// nostra funzione che invoca la system call linux che implementa il task della write
Deletions:
// nostra funzione che invoca la system call linux che l'effetto della write


Revision [3305]

Edited on 2017-11-17 14:57:27 by EmilioCoppa
Additions:
# In Linux, il gestore per 0x80 e' il componente del kernel che gestisce le system call

# il valore di ritorno della syscall si trovera' in eax
Deletions:
# In Linux, il gestore e' il kernel ed e' il
# meccanismo con cui e' possibile lanciare una syscall
# valore di ritorno della syscall in eax


Revision [3304]

Edited on 2017-11-17 14:55:54 by EmilioCoppa
Additions:
=== Invocazione di una system call ===
Diverse funzioni definite da POSIX sono semplicemente composte da codice che innesca l'invocazione di una system call. Il meccanismo di invocazione di una system call è specifico per l'architettura e per il kernel in uso. Il meccanismo di invocazione non è stabilito dallo standard POSIX. Per scrivere codice portabile POSIX dobbiamo sempre utilizzare le API POSIX che internamente innescano l'invocazione della system call.
==== Invocazione di una system call in x86 Linux ====
Il meccanismo di invocazione di una system call in Linux è specificato in ##man syscall##, sezione ##Architecture calling conventions##. L'id numerico delle system call offerte da Linux possono essere visualizzate con:
> cat /usr/src/linux-headers-$(uname -r)/arch/x86/include/generated/uapi/asm/unistd_32.h
[...]
#define __NR_write 4
[...]
La system call Linux relativa alla ##write## ha l'id numerico ##4##. Gli argomenti presi dalla system call write sono gli stessi presi dalla funzione POSIX ##write##, vedere ##man 2 write##.
%%(c;main.c)
// Non usiamo la funzione POSIX write ma implementiamo noi una
// nostra funzione che invoca la system call linux che l'effetto della write
int mywrite(int fd, const void *buf, int count);
mywrite(1, "Hello\n", 6);
%%
%%(c;mywrite.s)
# syscall numbers:
# cat /usr/src/linux-headers-$(uname -r)/arch/x86/include/generated/uapi/asm/unistd_32.h
# ssize_t write(int fd, const void *buf, size_t count)
# eax ebx ecx edx
.globl mywrite
mywrite:
pushl %ebx
movl $4, %eax # syscall write ha id numerico 4
# #define __NR_write 4 in /usr/src/linux-headers-$(uname -r)/
# arch/x86/include/generated/uapi/asm/unistd_32.h
movl 8(%esp), %ebx # primo argomento
movl 12(%esp), %ecx # secondo argomento
movl 16(%esp), %edx # terzo argomento
int $0x80 # genera un software interrupt
# il controllo viene passato a chi e' preposto a gestire
# l'interrupt number 0x80 (128)
# In Linux, il gestore e' il kernel ed e' il
# meccanismo con cui e' possibile lanciare una syscall
# valore di ritorno della syscall in eax
popl %ebx
ret
> gcc -m32 main.c mywrite.s -o main
> ./main
Hello


Revision [3303]

Edited on 2017-11-17 14:44:43 by EmilioCoppa
Additions:
=== Tracciamento invocazione system call ===
Deletions:
==== Tracciamento invocazione system call ===


Revision [3302]

Edited on 2017-11-17 14:44:10 by EmilioCoppa
Additions:
Contenuto di ##dump_syscall.txt##:
Deletions:
%%(dump_syscall.txt)


Revision [3301]

Edited on 2017-11-17 14:43:31 by EmilioCoppa
Additions:
==== Stream ====
==== File Descriptors ====
==== Tracciamento invocazione system call ===
%%(c; hello.c)
#include
printf("hello\n"); // printf utilizza internamente gli stream che sono implementati utilizzando i file descriptor
Per tracciare le system call invocate da un eseguibile possiamo utilizzare il tool ##strace##:
> strace ./hello 2> dump_syscall.txt
hello
L'output di ##strace## è emesso sullo standard error.
%%(dump_syscall.txt)
execve("./hello", ["./hello"], [/* 85 vars */]) = 0
brk(NULL) = 0x21d1000
access("/etc/ld.so.nohwcap", F_OK) = -1 ENOENT (No such file or directory)
mmap(NULL, 8192, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7fddc6825000
access("/etc/ld.so.preload", R_OK) = -1 ENOENT (No such file or directory)
open("/etc/ld.so.cache", O_RDONLY|O_CLOEXEC) = 3
fstat(3, {st_mode=S_IFREG|0644, st_size=211509, ...}) = 0
mmap(NULL, 211509, PROT_READ, MAP_PRIVATE, 3, 0) = 0x7fddc67f1000
close(3) = 0
access("/etc/ld.so.nohwcap", F_OK) = -1 ENOENT (No such file or directory)
open("/lib/x86_64-linux-gnu/libc.so.6", O_RDONLY|O_CLOEXEC) = 3
read(3, "\177ELF\2\1\1\3\0\0\0\0\0\0\0\0\3\0>\0\1\0\0\0P\t\2\0\0\0\0\0"..., 832) = 832
fstat(3, {st_mode=S_IFREG|0755, st_size=1868984, ...}) = 0
mmap(NULL, 3971488, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_DENYWRITE, 3, 0) = 0x7fddc6238000
mprotect(0x7fddc63f8000, 2097152, PROT_NONE) = 0
mmap(0x7fddc65f8000, 24576, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x1c0000) = 0x7fddc65f8000
mmap(0x7fddc65fe000, 14752, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS, -1, 0) = 0x7fddc65fe000
close(3) = 0
mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7fddc67f0000
mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7fddc67ef000
mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7fddc67ee000
arch_prctl(ARCH_SET_FS, 0x7fddc67ef700) = 0
mprotect(0x7fddc65f8000, 16384, PROT_READ) = 0
mprotect(0x600000, 4096, PROT_READ) = 0
mprotect(0x7fddc6827000, 4096, PROT_READ) = 0
munmap(0x7fddc67f1000, 211509) = 0
fstat(1, {st_mode=S_IFCHR|0620, st_rdev=makedev(136, 5), ...}) = 0
brk(NULL) = 0x21d1000
brk(0x21f2000) = 0x21f2000
write(1, "hello\n", 6) = 6
exit_group(0) = ?
+++ exited with 0 +++
Effettivamente ##printf## invoca la system call ##write##.
Deletions:
==== Stream ===
==== File Descriptors ===


Revision [3300]

Edited on 2017-11-17 14:37:18 by EmilioCoppa
Additions:
%%(c;example-file-descriptors-errno.c)
scritti = write(176677, testo, strlen(testo));
// valutiamo la causa dell'errore e
// reagiamo diversamente in base all'errore
switch (errno) {
case EBADF: // uno dei possibile errori di write. Vedere: man 2 write, sezioni RETURN VALUE e ERRORS
fprintf(stderr, "Descrittore errato\n"); // stampiamo semplicemente una stringa sullo stderr ma potremmo fare qualcosa di piu' utile
break;
default:
perror("Errore in write");
}


Revision [3299]

Edited on 2017-11-17 14:34:23 by EmilioCoppa
Additions:
scritti = write(176677, testo, strlen(testo)); // file descriptor volutamente non valido per indurre un errore nella write
perror("Errore in write"); // perror permette di stampare una stringa che spiega l'errore
// prendo come un argomento un ulteriore stringa ricevuta come argomento
// in questo caso emettera sullo stderr: "Errore in write: Bad file descriptor"
// dove ": Bad file descriptor" è stato aggiunto da perror in coda
// alla stringa fornita come argomento
Deletions:
scritti = write(176677, testo, strlen(testo));
perror("Errore in write");


Revision [3298]

Edited on 2017-11-17 14:31:14 by EmilioCoppa
Additions:
%%(c;example-file-descriptors-perror.c)
scritti = write(176677, testo, strlen(testo));
if (scritti == -1) {
perror("Errore in write");


Revision [3297]

The oldest known version of this page was created on 2017-11-17 14:29:59 by EmilioCoppa
Valid XHTML 1.0 Transitional :: Valid CSS :: Powered by WikkaWiki
Page was generated in 0.0675 seconds