Download presentation
Presentation is loading. Please wait.
Published byLewis Melton Modified over 8 years ago
1
Background Survey Answers Operating Systems CS 550 Spring 2016 Kenneth Chiu
2
Q5: Let’s say you have process A writing a number to a shared memory region. Process B reads the number from the shared memory region. Both processes are started at the same time. How do you make sure that Process B doesn’t read the number until Process A has finished writing the number? A: This is a traditional producer-consumer problem with a queue size of 1.
3
Q6: Write a C or C++ program to create a file named “data” containing exactly 1024 bytes with each byte having the value 0xff. A: Many people had trouble with this. Mainly just looking for the fact that you know there’s a key difference between ASCII and binary output, and just some ideas about how to do it. (In the real world, if you just have some slight idea, then you can quickly Google it. If you have no idea, then you don’t even know what to Google for in some cases.) – #include #include int main() { int rv; FILE *f = fopen(“data”, “w”); assert(f != 0); char b = 0xff; for (int i = 0; i < 1024; i++) { rv = fwrite(&b, 1, 1, f); assert(rv == 1); } rv = fclose(f); assert(rv == 0); return 0; }
4
Q7: Finish this function fragment to allocate two arrays using a single malloc() call: – void func(int n1, int n2) { // Allocate enough memory for both arrays. char *tmp = malloc(...); // Should point to beginning of n1 ints. int *int_array =...; // Should point to beginning of n2 doubles. double *double_array =...; for (int i = 0; i < n1; i++) int_array[i] = i; // Initialize the array of ints. for (int i = 0; i < n2; i++) double_array[i] = i; // Initialize the array of doubles.
5
A: – void func(int n1, int n2) { char *tmp = malloc(n1*sizeof(int) + n2*sizeof(double)); int *int_array = (int *) tmp; double *double_array = (double *) (tmp + n1*sizeof(int)); for (int i = 0; i < n1; i++) int_array[i] = i; for (int i = 0; i < n2; i++) double_array[i] = i;
6
Q8: Write code to test at run-time whether the machine is little-endian or big-endian? If you were required to determine the same information at compile-time, how would you do it? – int i = 1; if (*(char *) &i == 1) { printf(“little-endian\n”); } else { printf(“big-endian\n”); } – At compile time, use an #ifdef of some type.
7
Q9: Let’s say that you have 1000 JPEG files in a folder and its subfolders. Each file begins with the letters PIC. You wish to rename them all so that they begin with IMG instead. How would you do this? A: Correct answers: (1) “I would write a script in XYZ.” (2) “I would use the rename command.” (3) “I would create a sequence of commands in ABC.” Some people talked about the algorithm, or write a program in C, etc.
8
Q10. How do you debug a memory leak? A: What’s hard about it? – Use valgrind, Purify, etc. – If you can’t, you might be able to watch it in ‘top’. – To fix, if you can’t use valgrind, then you it becomes very difficult.
9
Q11. What causes a segfault? How do you debug it? – A segfault is caused by access to “unmapped” memory. It doesn’t exist, in other words. – Typically, it means you somehow got garbage values into a pointer. – valgrind is the best tool. Otherwise, gdb can be used.
10
Q12: Is this program correct? What do you think it will print out when you compile and run it? Explain why. – #include #include #include int main() { char *s = (char *) malloc(10); strcpy(s, “hello”); free(s); printf(“%s\n”, s); } A: Some people thought it would give segfault.
11
Q13: Assume that you have a file named foo in the current directory. The first four bytes contain an integer in binary using two’s complement (in native byte order). Let this integer have the value N. The next N bytes then contain a string. The string is not terminated with a 0 (null) byte. Write a program in any language and OS that will read in the string and print it to the console (standard output). A: First read the length, then read the rest. – #include #include #include int main() { int rv; int fd = open(“foo”, O_RDONLY); assert(fd >= 0); unsigned int n; rv = read(fd, &n, 4); assert(rv == 4); char *str = malloc(n + 1); str[n] = ‘\0’; rv = read(fd, str, n); assert(rv == n); rv = close(fd); assert(rv == 0); printf(“%s\n”, str); }
12
Q: Sketch a program that will be CPU-bound. A: A program that solves the TSP.
13
Q: Sketch a program that will be IO-bound. A: Databases are usually I/O bound.
14
Q14: What does a linker do? A: It resolves symbol references in object code to addresses and/or numbers, and combines the files into one file, usually an executable.
15
Q15: Why is a shared library called a shared library? A: Because it’s memory image can be shared by multiple processes.
16
Q16: Which is harder to debug, a deadlock or a race condition? A: Deadlocks are relatively easy. Attach to it with gdb. Check where all the threads are. Next step is harder, but then you need to backtrack to figure out how it got into this state. Usually, you can add a bunch of print statements to trace it. Race conditions can be very hard to debug. That’s because two given concurrent executions can have many different interleavings.
Similar presentations
© 2024 SlidePlayer.com. Inc.
All rights reserved.