240 likes | 379 Views
Outline Lab 6: interposition test Error handling I/O practice problem Reminders Lab 6: Due Tuesday. Minglong Shao shaoml+213@cs.cmu.edu Office hours: Thursdays 5-6PM Wean Hall 1315. Recitation 11 (Nov. 22). Exam2 statistics. 118 exams Highest score 74/74 (2 students)
E N D
Outline Lab 6: interposition test Error handling I/O practice problem Reminders Lab 6: Due Tuesday Minglong Shao shaoml+213@cs.cmu.edu Office hours: Thursdays 5-6PM Wean Hall 1315 Recitation 11 (Nov. 22)
Exam2 statistics • 118 exams • Highest score 74/74 (2 students) • Lowest score 24 • Average score 49.94 • Median score 49
L6: Interposition test • Build shared libraries mm.so and memlib.so make mm.so memlib.so gcc –fpic –shared –o mm.so mm-student.c gcc –fpic –shared –o memlib.so memlib.c • Set LD_PRELOAD bash: export LD_PRELOAD=“/path/to/mm.so /path/to/memlib.so” Remember to restore LD_PRELOAD export LD_PRELOAD= • Make sure the heap is initialized
Error handling • Always check return code of system calls • There are subtle ways that things can go wrong • Use the status info kernel provides us • Appendix B
Different error handling styles • Unix-style • e.g. kill, signal, fork, etc. • Posix-style • e.g. pthread_create • DNS-style • e.g. gethostbyname
Unix-style error handling • Special return value when encounter error (always –1) • Global variable errno set to an error code • Use strerror function for text description of errno • Or use perror voidunix_error(char *msg) { fprintf(stderr, “%s: %s\n“, msg, strerror(errno)); exit(0); } if((pid = wait(NULL)) < 0) unix_error(“Error in wait”);
Unix-style error handling cont’d if ((pid = wait(NULL)) < 0) { perror(“Error in wait”); exit (0); }
Posix-style error handling • Return value indicates success (0) or failure (nonzero) • Useful results returned in function arguments voidposix_error(int code, char *msg) { fprintf(stderr, “%s: %s\n“, msg, strerror(code)); exit(0); } if((retcode = pthread_create(…)) != 0) posix_error(retcode, “Error in pthread”);
DNS-style error handling • Return a NULL pointer on failure • Set the global h_errno variable voiddns_error(char *msg) { fprintf(stderr, “%s: DNS error %d\n“, msg, h_errno); exit(0); } if((p = gethostbyname(name)) == NULL) dns_error(“Error in gethostbyname”);
Example: wrappers • Appendix B: csapp.h and csapp.c • Unix-Style, for kill function • Behaves exactly like the base function if no error • Prints informative message and terminates the process voidKill (pid_t pid, int signum) { intrc; if((rc = kill(pid, signum)) <0) unix_error(“Kill error”); }
Handle errors gracefully • The wrappers shown above calls exit() • In many situations, we want to handle errors more gracefully. • For example: web server, etc. void sigchld_handler(int signum) { pid_t pid; while((pid = waitpid(…)) > 0) printf(“Reaped %d\n”, (int)pid); if(errno != ECHILD) unix_error(“waitpid error”); }
I/O practice problems from Chapter 11 • 11.1 ~ 11.5
Problem 11.1 What is the output of the following program? #include "csapp.h" int main() { int fd1, fd2; fd1 = Open("foo.txt", O_RDONLY, 0); Close(fd1); fd2 = Open("baz.txt", O_RDONLY, 0); printf("fd2 = %d\n", fd2); exit(0); }
Answer to 11.1 • stdin (descriptor 0)stdout (descriptor 1)stderr (descriptor 2) • open always returns lowestunopened descriptor • First open returns 3. close frees it. • So second open also returns 3. • Program prints: "fd2 = 3"
File sharing • Descriptor table • Each process has its own • Child inherits from parents • File Table • set of all open files • Shared by all processes • Reference count of number of file descriptors pointing to each entry • File position • V-node table • Contains information in the stat structure • Shared by all processes
Problem 11.2 foobar.txt has 6 ASCII characters "foobar". What is the output of the following program? #include "csapp.h" int main() { int fd1, fd2; char c; fd1 = Open("foobar.txt", O_RDONLY, 0); fd2 = Open("foobar.txt", O_RDONLY, 0); Read(fd1, &c, 1); Read(fd2, &c, 1); printf("c = %c\n", c); exit(0); }
Answer to 11.2 fd1 and fd2 have different open file table entries have their own file positions for foobar.txt fd2 reads the first byte of foobar.txt The output isc = fand notc = o
Problem 11.3 foobar.txt has 6 ASCII characters "foobar". What is the output of the following program? #include "csapp.h" int main() { int fd; char c; fd = Open("foobar.txt", O_RDONLY, 0); if(Fork() == 0) {Read(fd, &c, 1); exit(0);} Wait(NULL); Read(fd, &c, 1); printf("c = %c\n", c); exit(0); }
Answer to 11.3 Child inherits the parent’s descriptor table Child & parent share an open file table entry (refcount = 2) They share file position. c = o
Problem 11.4 • How would you use dup2 to redirect standard input to descriptor 5? • int dup2(int oldfd, int newfd); • Copies descriptor table entry oldfd to descriptor table entry newfd
Answer to 11.4 dup2(5,0); or dup2(5,STDIN_FILENO);
Problem 11.5 foobar.txt has 6 ASCII characters "foobar". What is the output of the following program? #include "csapp.h" int main() { int fd1, fd2; char c; fd1 = Open("foobar.txt", O_RDONLY, 0); fd2 = Open("foobar.txt", O_RDONLY, 0); Read(fd2, &c, 1); Dup2(fd2, fd1); Read(fd1, &c, 1); printf("c = %c\n", c); exit(0); }
Answer to 11.5 Redirect fd1 to fd2 fd1 points to the same open file table entry as fd2 The second Read uses the file position offset of fd2. c = o