quiz for week 1

313 people have viewed this quiz

Answer the following questions about the lecture for this week.

Question 1 (4 pt; mean 3.41)

Suppose we build a dynamically linked library and a program that uses it as follows

clang -c utility1.c
clang -c utility2.c
clang -shared -o libutility.so utility1.o utility2.o
clang -c main.c
clang -o main.exe main.o -L. -l utility -Wl,-rpath .

If we modify utility2.c, then we should rerun which commands in order to make sure main.exe uses the most recent version of that the code in utility2.c? Select all that apply.

Regrade request

Suppose a C project has a header file constants.h that is generated by processing a CSV constants.csv file with C program called csvtoconstantsh.

Then constants.h is used with main.c to generate a main executable. When run by hand the following sequence of commands are used:

clang -c csvtoconstantsh.c
clang -o csvtoconstantsh csvtoconstants.o
./csvtoconstantsh constants.csv constants.h
clang -c main.c
clang -o main main.o
Question 2 (4 pt; mean 3.84) (see above)

Suppose the above commands are run, and then constants.csv is modified. Which commands should be rerun to handle these changes? Select all that apply.

Regrade request
Question 3 (6 pt; mean 5.65) (see above)

When writing a Makefile to handle building this project, one might have a rule for constants.h:

constants.h: ...
(tab)./csvtoconstantsh constants.csv constants.h

where ... is is a list that includes ___ (and (tab) represents a tab character). Select all that apply.

  1. would not be harmful to include, but should not be necessary since we need another rule to handle building csvtoconstantsh from csvtoconstantsh.o, and that rule should have this dependency

Regrade request
Question 4 (4 pt; mean 2.88)

Consider a Makefile with the following contents:

foo.exe: foo.c
(tab)clang -c foo.c
(tab)clang -o foo.exe foo.o

compared to a Makefile with the following contents:

foo.exe: foo.o
(tab)clang -o foo.exe foo.o

foo.o: foo.c
(tab)clang -c foo.c

((tab) represents a tab character.)

It is possible to set the modifications times of foo.exe, foo.o and foo.c such that running make foo.exe will ____ with the first Makefile, but ____ with the second.

Regrade request


quiz for week 2

308 people have viewed this quiz

Answer the following quesitons about the lecture material for this week.

Question 1 (3 / 4 pt; mean 2.87)

Operating systems could provide a system call that provides the functionality of printf, but they usually do not. Instead, printf is usually implemented in a library function that may internally make some system calls.

What are typically advantages of this approach? Select all that apply.

  1. I think the better answer is that this is not the case. Generally, it's usually the case that devices cannot be accessed without being in kernel mode. It's true that there are exceptions to this, but even so, since the screen being a shared resource means the OS needs to arbitrate access to it so those accesses necessairily need to happen in kernel mode, but there are corner cases where it isn't true (I should've phrased the question to more explicitly refer to a situation where the screen is definitely shared)

Regrade request

Consider a Unix-like system with a single-core running three (single-threaded) processes, an SSH client, a graphical terminal (which is being used to display the SSH client), and a program performing a long computation

Initially process SSH client is active on the CPU, then the following events happen in the following order:

  1. The SSH client computes some data and outputs it to the network.
  2. The SSH client waits for new input from the network or its terminal
  3. While the SSH client is waiting, the long computation program runs.
  4. An "enter" keypress occurs, so the terminal program starts running to process it.
  5. The terminal program adjusts the image it displays to account for a new line.
  6. The terminal program forwards the keypress to the SSH client.
  7. The SSH client receives the keypress.
  8. As a result of the keypress, the SSH client sends something on the network.
Question 2 (0 / 4 pt; mean 3.7) (see above)

How many context switches must occur between steps 1 and 8 above?

Answer:
Key: 3
Regrade request
Question 3 (0 / 4 pt; mean 3.25) (see above)

A non-system-call exception is likely to occur as part of which steps above? Write the numbers of the relevant steps; for example, if you think steps 2 and 7 will have a a non-system-call exception occur, then write "27".

Answer:
Key: 4

also accepted 1 and 8 on the theory that the network interface needs to inform the OS when more output can be accepted via exception, though I don't think this is especially likely except on very loaded network (and it wasn't my intention to test about this kind of issue)

also accepted 2 or 3 (but not both) [theory that SSH client is waiting in a loop rather than having a system call that puts the program to sleep, so we need an timer interrupt to switch to the long computation. I think this is unlikely (we don't like our programs hogging the processor while waiting for input), but not unreasonable.]

[to be handled in manual grading]: -1 point per disagreement

Regrade request
Question 4 (0 / 4 pt; mean 2.11) (see above)

One or more system calls are likely to be started during which of the steps above? Write the numbers of the relevant steps; for example, if you think steps 2 and 7 will have a system call be started, then write "27".

Do not include steps for which a system call already in progress is resumed (but do include cases where a system call is both started and finished within the step).

Answer:
Key: 12568 or 1258

(12568 is a better answer, but we have not taught enough about how processes communicate to discount number 6 happening via shared memory instead of a system call)

[to be handled in manual grading]: -1 point per disagreement

Regrade request
Question 5 (0 / 4 pt; mean 3.83)

Suppose a program running on a Linux system contains the following line:

*pointer = 42;

When pointer does not specify a valid memory location (and no setup has been done to handle this situation specially), this line will cause the program to crash (terminating with an error). To make this happen, ____.

  1. I think this (C) is the best answer.

  2. We gave full credit to this answer during regrading. The intention of this question was to state that the hardware runs the handler for C and D, which would make D definitely incorrect. The language "causes" is unfortunately less precise, though I believe "the hardware runs the handker" would be the most natural reading. Also, when there's no signal handler registered, the default action is taken by the kernel without running code in user mode, so the notion that a default handler makes a system call is not correct.

Regrade request


quiz for week 3

302 people have viewed this quiz

Consider the following C code:

int global = 0;

void handle_sigint(int id) {
    global += 1;
    printf("SIGINT: global=%d\n", global);
}

int main() {
    Initialize();
    struct sigaction sa;
    sa.sa_handler = &handle_sigint;
    sigemptyset(&sa.sa_mask);
    sa.sa_flags = SA_RESTART;
    sigaction(SIGINT, &sa, NULL);

    char line[128];
    while (fgets(line, sizeof line, stdin)) {
        Process(line);
    }
}

Assume all necessary #includes and an implementation of the Initialize and Process functions are included, that these functions do not do anything with signals, that the system is setup so control-C always sends the signal SIGINT, and the C code is compiled into an executable.

Question 1 (4 pt; mean 3.87) (see above)

While the executable is waiting for input, a user presses control-C, which results in the SIGINT signal being triggered and the signal handler printing out a message like SIGINT: global=1.

When the signal handler runs in this scenario, the signal handler will ____. Select all that apply.

  1. should have written "starts any system calls" (in which case it is clearly false), "makes a system call" had some other interperations I did not expectt

Regrade request
Question 2 (4 pt; mean 3.23) (see above)

While running this program, a developer observes that pressing control-C usually results in it printing a message like SIGINT: global=1 and continuing to look for input, but sometimes instead it makes the program terminate.

Which of the following situations will cause the program to terminate this way?

  1. [adjusted to half-credit on 10 Dec for consistency with how some TAs graded comments on this question (which was more lenient than I had intended/expected)]

Regrade request
Question 3 (4 pt; mean 3.94)

On a Unix-like system, generally two processes with the same user IDs and group IDs ____. Select all that apply.

Regrade request
Question 4 (4 pt; mean 2.32)

Consider the following access control list:

user:aaa1a:r--
user:bbb1b:rw-
user:ccc1c:r--
other::---

(other::--- represents that users and groups not otherwise listed have no access.)

To allow us to replicate the effects of this access control list with chmod-style permissions, we could create a new group and make it so programs run by ____ are assigned to that group.

  1. I made a mistake by not having an "either A or B" option when writing this question. We'll accept either A or B or none of the above explaining A or B would be okay.

  2. we will accept this answer if it explains A or B, but that will be done via manual grading

Regrade request
Question 5 (4 pt; mean 3.47)

Which of the following scenarios can we achieve on a shared machine like the portal servers with the POSIX access control lists we discussed in lecture? Select all that apply.

Regrade request


quiz for week 4

301 people have viewed this quiz

Answer the following questions about the lecture material for this week.

For the following questions, consider a system with 7-bit page offsets, 10-bit virtual addresses and 11-bit physical addresses and the following page table:

index (virtual page #, in binary)valid?physical page # (in binary)
0000
00110110
01011001
01111010
10011111
10110010
11010110
1110
Question 1 (4 pt; mean 3.87) (see above)

What is a physical address for virtual address (written in binary) 0100001110? Write your answer in binary; if there is no corresponding physical address write "none".

Answer:
Key: 10010001110
Regrade request
Question 2 (4 pt; mean 3.76) (see above)

What is a virtual address for the physical address (written in binary) 01100001110? Write your answer in binary; if there is no corresponding virtual address write "none".

Answer:
Key: 0010001110 or 1100001110
Regrade request
Question 3 (4 pt; mean 3.52)

Consider a program executing the following instruction:

movq %rax, (%rcx)

whose machine code is located at address 0x300010. Suppose %rax contains 0x999000, and %rcx contains 0x123450, and the system uses 4096-byte pages (so addresses have 12-bit page offsets).

In the process of fetching and executing that instruction, the processor will access a page table entry for virtual pages ____. List the virtual page numbers in hexadecimal separated by commas. For example, if you think the answer is virtual pages 0x33, 0x43 and 0x45, write 0x33,0x44,0x45.

Answer:
Key: 0x123,0x300 or 0x300,0x123

half-credit for just one

Regrade request

Consider a system with page tables that are stored in memory as a single array. Suppose the system uses 65536 byte pages (so addresses have 16-bit page offsets), 4-byte page entries, and the page table base register is set to physical (byte) address 0x30000 (so the page table entry with index 0 is at 0x30000, the one with index 1 at 0x30004, the one with index 2 at 0x30008, etc.)

As part of translating a virtual address to a physical address, the system:

Question 4 (4 pt; mean 3.54) (see above)

What was the physical page number contained in the page table entry that was found? Write your answer as a hexadecimal number.

Answer:
Key: 0x99
Regrade request
Question 5 (4 pt; mean 3.09) (see above)

What was the virtual address being translated? Write your answer as a hexadecimal number.

Answer:
Key: 0x449433
Regrade request
Question 6 (4 pt; mean 3.9)

On a system with a page tables stored in memory as a single array, if one process can access twice as many addresses as another, then ____. Select all that apply.

intended reading of quesiton was that "would cause segfault" means "can't access". Under that interpration, only C is correct. Some students said that, yes, we can access an address if that always triggers an exception. Under that interpretation, only A and D are correct

Regrade request


quiz for week 5

300 people have viewed this quiz

Answer the following questions about the lecture material for this week.

For the following questions, consider a system with:

Question 1 (4 pt; mean 3.36) (see above)

Consider an access to virtual address 0xABCD, where during the access:

  • the page table base register has the (byte) address 0x03300,
  • the first-level page table entry used contains the physical page number 0x0123
  • the second-level page table entry used contains the physical page number 0x0456

Then, at what physical address is the first-level page table entry located? Write your answer as a hexadecimal number.

Answer:
Key: 0x332a

VA = [5 bit VPN part 1][5 bit VPN part 2][6 bit page offset]

first-level addr = PTBR + VPN part 1 * 2 = 0x3300 + (binary 10101) * 2

Regrade request
Question 2 (4 pt; mean 2.54) (see above)

If a process's page tables allow it to access 6400 bytes worth of distinct physical addresses, then its page tables take up at least ____ bytes.

(Assume none of the 6400 bytes of addresses the process can access are used to store its page table entries.)

Answer:
Key: 320

half-credit for 256

each 2nd-level table can point to up to 64 * 32 bytes of data (if all the entries are valid and point to distinct data pages), to total more than 6400 bytes we need at least 4 2nd-level tables, which take up 256 bytes. We also need a first-level table to point to the second-level table tthat will take up 64 bytes even though it is mostlyinvalid entries), giving 320 bytes total.

Regrade request
Question 3 (4 pt; mean 3.7)

Consider the instruction

movq %rax, (%rcx)

As part of executing an instruction a last-level page table entry corresponding to the value of %rcx will be retrieved.

Assume in addition to a valid bit, the page table entry contains a "writeable" bit, an "executable" bit, and a "user-mode" bit, each of which indicate if that kind of memory access can be completed using that page table entry.

The instruction will trigger an exception as a result of the page table lookup if ____. Select all that apply.

Regrade request

Consider the following C program (which uses the POSIX API):

// some needed #includes not shown
int global;
int main() {
    global = 0;
    printf("1"); fflush(stdout);
    pid_t p = fork();
    printf("2"); fflush(stdout);
    if (p == 0) {
        global = 3;
    } else {
        global = 4;
    }
    printf("%d", global); fflush(stdout);
    return 0;
}

For the following questions, assume:

Question 4 (4 pt; mean 3.42) (see above)

12423 and 12324 are possible outputs of the above program. How many other possible outputs are there?

Answer:
Key: 2

12234 and 12243; the parent outputs 124 and the child outputs 23.

To figure out the possible outputs, let's consider where the child can output its characters. The earliest it can do it is immediately after the parent outputs the 1 (because of where the fork() is) and the latest is after it outputs 4. So our output "template" looks like 1[_]2[_]4[_] where [_] represents blanks where the child runs. We can either put "23" in exactly one slot (the child runs entirely in between two parent outputs); or we can put "2" in one slot and "3" in a later one.

This gives possibilities of 1[23]24, 12[23]4, 124[23], 1[2]2[3]4, 1[2]24[3], 12[2]4[3]. After accounting for some these appearing identical (since we can't distinguish the child writing 2 from the parent writing 2 generally), we have 12324, 12234, 12423, 12243 --- four possible outputs.

Regrade request
Question 5 (3 pt; mean 2.78) (see above)

Suppose the system the above program runs on uses copy-on-write to implement fork. Immediately after the fork, ____. Select all that apply.

Regrade request
Question 6 (3 pt; mean 2.78) (see above)

Suppose the system the above program runs on uses copy-on-write to implement fork. Suppose both the parent a child process completed their assignment to global but have not yet started the following printf call. Then, ____. Select all that apply.

Regrade request


quiz for week 6

296 people have viewed this quiz

Answer the following questions about the lecture material for this week.

Question 1 (4 pt; mean 3.47)

Consider the following C snippet (which uses the POSIX API):

pid_t pids[3];
for (int i = 0; i < 3; i += 1) {
    printf("A"); fflush(stdout);
    pids[i] = fork();
    if (pids[i] == 0) {
        /* child process */
        printf("%d", i); fflush(stdout);
        exit(0);
    }
    if (i >= 1) {
        waitpid(pids[i-1], NULL, 0);
    }
}
printf("B"); fflush(stdout);
waitpid(pids[2], NULL, 0);

Assume that fork and waitpid do not fail (and that all needed header files are included).

Some possible outputs of this snippet are AA01AB2 and AA0A12B (where the As and Bs are outputted by the parent process and the 0, 1, and 2 are outputted by one of the three child processes created by the call to fork() in the loop.)

Which of the following are other possible outputs? Select all that apply.

  1. need 0 printed before third A (because of waitpid() call when i = 1 in parent)

  2. need two As printed before 1 (before fork() call can happen when i = 1).

Regrade request

Consider the following incomplete C snippet (which uses the POSIX API):

int input_fd = open("input.txt", O_RDONLY);
if (input_fd < 0)
    handle_error();
pid_t pid = fork();

____________ /* 1 */
if (pid == 0) {
    ____________ /* 2 */
    const char *argv[] = {"./a.out", NULL};
    execv("./a.out", argv);
} else if (pid > 0) {
    ____________ /* 3 */
    int status;
    if ((pid_t) -1 == waitpid(pid, &status, 0)) {
        handle_error();
    }
}

In the snippet, __________ represents a blank to be replaced with code to complete the snippet.

For the following questions, assume that this program containing this snippet is not called a.out, and that open, fork, dup2,execv,closeandwaitpid` do not fail.

This code is intended to run a program called a.out, which normally would take input from the terminal using stdin, and have it read its input from input.txt

Question 2 (4 pt; mean 3.48) (see above)

In order to make a.out read from input.txt for its standard input, one could add a call to dup2 (like dup2(input_fd, STDIN_FILENO)) to one of the blanks above. Where can it be added to achieve this? (Identify the blank by the number in the comment labeling it.)

  1. blank 2 is better, but blank 1 also works --- we just need to close input_fd in the parent to avoid wasting resources

Regrade request
Question 3 (4 pt; mean 3.33) (see above)

Normally, we'd use a dup2 call like dup2(input_fd, STDIN_FILENO) to redirect a.out's input. What would happen if we erroneously used dup2(STDIN_FILENO, input_fd)? Select all that apply.

  1. the erroneous dup2 call does not change what a.out's stdin will be, so it will refer to the terminal from the terminal (or whatever the normal stdin was)

  2. close() just makes the particular file descriptor point to nothing. So although this would make input_fd not useful, STDIN_FILENO would be unaffected by the close

  3. input_fd would now refer to stdin, likely the terminal instead

Regrade request
Question 4 (4 pt; mean 3.57)

In lecture, we mentioned that temporal locality is a property that a program that accesses a value is likely to access that same value again soon.

Consider the following C snippet:

for (int i = 0; i < 1024; ++i) {
    printf("%s %s\n", A[i], B[i]);
}

The snippet would exhibit more temporal locality in its array accesses if ____. Select all that apply.

Regrade request

Consider a direct-mapped cache whose contents are as follows:

index (written in binary)validtag (written in binary)data (written as hexadecimal bytes, lowest address first)
0011100AB CD
0110110EF 01
101111023 45
110
Question 5 (6 pt; mean 5.74) (see above)

Based on the contents of the cache shown above, accessing which of the following addresses would be a cache hit? All the addresses are written in binary. Select all that apply.

Regrade request
Question 6 (5 pt; mean 4.64) (see above)

If a processor used this cache to read the byte value 0x99 from an address with index 01, tag 0000, and offset 1, then the cache would ____. Select all that apply.

  1. cache needs to read in whole block (get all bytes from addresses with that tag+index)

Regrade request


quiz for week 7

298 people have viewed this quiz

For the following questions, consider a 2-way set associative cache with an LRU (least recently used) replacement policy whose contents are as follows.

In the cache contents below, indices and tags are written in binary, and data bytes are written as a sequence of hexadecimal bytes with the lowest address first.

way 0way 1
index (written in binary) validtag (written in binary)data validtag (written in binary)data LRU way
00 11100AB CD 11101DE EF 0
01 1001001 02 1001103 04 1
10 1111023 45 0 1
11 0 0 0
Question 1 (3 pt; mean 2.72) (see above)

What is the address with index 00, tag 1101, and (block) offset 1 in the above cache? Write your answer as a binary number.

Answer:
Key: 1101001
Regrade request
Question 2 (4 pt; mean 3.93) (see above)

Using the above cache, reading a byte from an address with index 01, tag 0011, offset 0 will _____. (Ignore effects from any changes in the other questions.) Select all that apply.

Regrade request
Question 3 (4 pt; mean 3.67) (see above)

Using the above cache, reading a byte from an address with index 11, tag 1110, offset 0 will _____. (Ignore effects from any changes in the other questions.) Select all that apply.

Regrade request

Suppose an array is declared as follows:

unsigned char array[16];

which is located at a memory address that is a multiple of 1024 (two to the tenth power).

and then we run the following C snippet:

int count = 0;
count += array[0];
count += array[3];
count += array[6];
count /= array[1];
count /= array[4];
count /= array[7];
Question 4 (5 pt; mean 4.69) (see above)

Suppose the above code snippet is run with a two-set direct-mapped data cache with 2 byte blocks. [Note that unlike the examples in lecture, the array elements take up 1 byte and the cache blocks are smaller]

Accessing array[0] will use set 0 of this cache. Access which of the following other array elements would also use set 0? Select all that apply.

mapping to set is based on addresses; because array[0]'s address is a multiple of 1024 and therefore 2, it is at the start of a 2-byte block. This block includes {array[0], array[1]}. The next block in memory is {array[2], array[3]}, and must map to the next set, set 1. After that {array[4], array[5]}, which would map to the next set, but since the cache only has two sets, this is set 0 instead of set 2. Then the next set {array[6], array[7]} maps to set 1.

Regrade request
Question 5 (4 pt; mean 3.38) (see above)

Suppose the above code snippet is run with a two-set direct-mapped data cache with 2 byte blocks. Assume the cache is initially empty when the snippet starts and only accesses to array use the cache. How many cache misses will occur?

Answer:
Key: 4

(showing {contents of set 0 in cache}{contents of set 1 in cache} after each miss is processed) array[0] M: {01}{--}; array[3] M: {01}{23}; array[6] M: {01}{67}; array[1] H; array [4] M: {45}{67}; array[7] H

Regrade request
Question 6 (4 pt; mean 3.63) (see above)

Suppose the above code snippet is run with a two-block fully associative data cache with 2 byte blocks and an LRU (least recently used) replacement policy. This cache could also be described as a 2-way set associative cache with 1 set and 2-byte blocks and an LRU replacement policy. Assume the cache is initially empty when the snippet starts and only accesses to array use the cache. How many cache misses will occur?

Answer:
Key: 6

(showing which blocks present in cache, most recently accessed block first) array[0] M: {01}{--}; array[3] M: {23}{01}; array[6] M: {67}{23}; array[1] M {01}{67}; array [4] M: {45}{01}; array[7] M {67}{45}

Regrade request


quiz for week 8

297 people have viewed this quiz

For the following questions, consider a 2-way set associative cache with an LRU (least recently used) replacement policy, a write-back policy, and a write-allocate policy, whose contents are as follows.

In the cache contents below, indices and tags are written in binary, and data bytes are written as a sequence of hexadecimal bytes with the lowest address first.

way 0way 1
index (written in binary) validtag (written in binary)datadirty validtag (written in binary)datadirty LRU way
00 11100AB CD1 11101DE EF0 0
01 1001001 020 1001103 041 1
10 1111023 450 00 1
11 00 00 0
Question 1 (4 pt; mean 3.79) (see above)

Using the above cache, writing a byte to an address with index 00, tag 1101, offset 1 will _____. Select all that apply.

  1. modifying most recently used way of this set, so least recently used does not change

Regrade request
Question 2 (4 pt; mean 3.58) (see above)

Using the above cache, writing a byte to an address with index 01, tag 1111, offset 0 will _____. (Ignore effects from any changes in the other questions.) Select all that apply.

  1. replaces something already dirty, so dirty bit remains at 1

  2. to read rest of this cache block (byte at address with index 01, tag 1111, offset 1)

  3. to write dirty bytes 03 04 (least recently used way) back to memory

Regrade request
Question 3 (4 pt; mean 3.61)

A system with:

Suppose the virtual address 0x56123 translates to the physical address 0x43123. When a TLB lookup occurs as a part of accessing this virtual address, which TLB index will be used? Write your answer as a hexadecimal number.

Answer:
Key: 0x16 -- early version of question had 32 entries instead of 128, so also accepted 0x6 (based on 3 index bits)

TLB lookup uses virtual page 0x56; lower 5 bits are the TLB index

Regrade request

Consider the following C code which is run only by calling the example() function:

struct thread_data {
    int x;
    int *p;
};

void *thread_func(void *raw_ptr) {
    struct thread_data *td;
    td = (struct thread_data *)raw_ptr;
    *(td->p) += td->x;      /* LINE A */
    td->x = *(td->p);       /* LINE B */
    return &td->x;
}

int global_array[2] = {0, 0};

void example() {
    pthread_t threads[2];
    for (int x = 0; x < 2; ++x) {
        struct thread_data *td;
        td = malloc(sizeof(struct thread_data));
        td->x = x;
        td->p = &global_array[x];
        int ret = pthread_create(&threads[x], NULL, thread_func, (void*) td);
        /* LINE C */
    }
    /* LINE D */
    for (int i = 0; i < 2; ++i) {
        void *raw_ptr;
        pthread_join(threads[i], &raw_ptr);
        int *p;
        p = (int*) raw_ptr;
        printf("got result %d\n", *p); /* LINE E */
    }
    /* LINE F */
}

The comments of the form "LINE X" are label particular parts of the code for the questions below.

Assume all appropriate #includes are used and the example() function is run and the example() function is the only thing that causes thread_func to be called or global_array to be accessed.

Question 4 (4 pt; mean 3.58) (see above)

When example() causes the function thread_func to run, the line labeled LINE B modifies ____.

  1. td is local variable on the stack of example(), but td->x is part of something malloc'd in example()

Regrade request
Question 5 (4 pt; mean 3.16) (see above)

In the function example(), the line labeled LINE E prints out an integer that is stored ____.

  1. p is &td->x because of what thread_func returns; &td->x is a pointer to part of what's malloc'd earlier in example()

Regrade request
Question 6 (4 pt; mean 3.66) (see above)

The example() function in the above code has a memory leak because the malloc call in the first for loop in example() does not have any corresponding free calls. Which of the following is the earliest that a free call or calls could be safely added? (Assume that extra code is added to track the malloc'd pointers so they can be freed.)

  1. because value from this malloc is printed on LINE E

Regrade request


quiz for week 9

299 people have viewed this quiz

Consider the following code that uses mutexes:

pthread_mutex_t int_lock = PTHREAD_MUTEX_INITIALIZER;
pthread_mutex_t ptr_lock = PTHREAD_MUTEX_INITIALIZER;

int global_int1 = 1;
int global_int2 = 2;
int global_int3 = 3;
int *global_ptr = &global_int1;

void thread1() {
    int *old_pointer;
    pthread_mutex_lock(&ptr_lock);
    old_pointer = global_ptr;
    global_ptr = &global_int3;
    pthread_mutex_unlock(&ptr_lock);        /* A */
    pthread_mutex_lock(&int_lock);
    global_int2 += global_int1;
    pthread_mutex_unlock(&int_lock);
    pthread_mutex_lock(&ptr_lock);          /* A */
    old_pointer = global_ptr;
    global_ptr = old_pointer;
    pthread_mutex_unlock(&ptr_lock);
}

void thread2() {
    pthread_mutex_lock(&ptr_lock);

    pthread_mutex_lock(&int_lock);          /* B */
    global_int1 += *global_ptr;         
    pthread_mutex_unlock(&int_lock);        /* B */
                                            /* C */
    global_ptr = &global_int2;
    pthread_mutex_unlock(&ptr_lock);
}

For the following questions, assume that thread1 and thread2 are started at the same time from different threads and run exactly once, and no other code manipulates the global variables above.

Question 1 (4 pt; mean 3.43) (see above)

Removing the lock and unlock call marked with the comment /* B */ would ____. Select all that apply.

Regrade request
Question 2 (4 pt; mean 4) (see above)

It's possible for global_ptr's final value to be &global_int1 despite thread2's code setting to &global_int2. Which of the following changes would prevent that? Select all that apply.

[Question dropped due to error in code above.]

Gave everyone full credit for this question, since it did not make sense due to an error. I intended to ask the question without the old_pointer = global_ptr line repeated. With it repeated, global_ptr cannot be &global_int1.

Regrade request

Consider the following code that uses barriers and mutexes:

pthread_barrier_t barrier;
pthread_mutex_t lock;
int x = 1, y = 2, z = 3;

void *thread1_func(void *) {
    pthread_mutex_lock(&lock);      /* LOCK A */
    y += z; 
    pthread_mutex_unlock(&lock);    /* UNLOCK A */
    pthread_barrier_wait(&barrier);
    pthread_mutex_lock(&lock);      /* LOCK B */
    x += z;
    pthread_mutex_unlock(&lock);    /* UNLOCK B */
    pthread_barrier_wait(&barrier);
}

void *thread2func(void *) {
    pthread_mutex_lock(&lock);      /* LOCK C */
    y += z;
    pthread_mutex_unlock(&lock);    /* UNLOCK C */
    pthread_barrier_wait(&barrier);
    pthread_mutex_lock(&lock);      /* LOCK D */
    y += z;
    pthread_mutex_unlock(&lock);    /* UNLOCK D */
    pthread_barrier_wait(&barrier);
    pthread_mutex_lock(&lock);      /* LOCK E */
    x += z;
    pthread_mutex_unlock(&lock);    /* UNLOCK E */
}

int main() {
    pthread_barrier_init(&barrier, 2);
    pthread_mutex_init(&lock, NULL);
    pthread_t thread1;
    pthread_t thread2;
    pthread_create(&thread1, NULL, thread1_func, NULL);
    pthread_create(&thread2, NULL, thread2_func, NULL);
    pthread_join(thread1, NULL);
    pthread_join(thread2, NULL);
    printf("%d %d %d\n", x, y, z);
    return 0;
}
Question 3 (5 pt; mean 4.61) (see above)

Each of the calls to pthread_mutex_lock and pthread_mutex_unlock above are labeled LOCK X or UNLOCK X where X is a letter. Which (if any) of them could be removed without causing a race condition? (That is, without making the values of x, y, and z vary depending on the relative timing of threads.) (Assume that only matching pairs of locks and unlocks would be removed.) Select all that apply.

Regrade request
Question 4 (4 pt; mean 3.78) (see above)

The printf in main() avoids race conditions and always outputs the final values of x, y, and z. This would also happen if the printf were placed ____. Select all that apply.

Regrade request

Suppose we have a system for booking plane flights. This system needs to support booking a single ticket that encompasses multiple plane flights. To support this, the system, implemented in C with pthreads, uses the following data structures:

struct flight {
    pthread_mutex_t lock;
    int flight_id;
    int remaining_seats;
    struct tickets *tickets[MAX_SEATS];
};

struct ticket {
    int ticket_number;
    int num_flights;
    struct flight *flights[MAX_FLIGHTS];
};

The support booking and cancelling tickets, the system implements the following functions:

Psuedocode for these functions are as follows. Assume the AddTicketToFlight and RemoveTicketFromFlight functions handle adjusting remaining_seats.

struct ticket *BookTicket(int num_flights, struct flight *flights) {
    int can_book = 1;
    for (int i = 0; i < num_flights; i += 1) {
        pthread_mutex_lock(&flights[i]->lock);
        if (flights[i]->remaining_seats == 0) {
            can_book = 0;
        }
    }
    struct ticket *result;
    if (can_book) {
        result = AllocateTicket(num_flights, flights);
        for (int i = 0; i < num_flights; i += 1) {
            AddTicketToFlight(result, flights[i]);
        }
    }
    for (int i = 0; i < num_flights; i += 1) {
        pthread_mutex_unlock(&flights[i]->lock);
    }
    return result;
}

int ChangeTicket(struct ticket *ticket, int index, struct flight *new_flight) {
    int successful = 0;
    pthread_mutex_lock(&new_flight->lock);
    if (new_flight->remaining_seats > 0) {
        pthread_mutex_lock(&ticket->flights[index]->lock);
        RemoveTicketFromFlight(ticket->flights[index]);
        ticket->flights[index] = new_flight;
        AddTicketToFlight(ticket, new_flight);
        pthread_mutex_unlock(&ticket->flights[index]->lock);
        successful = 1;
    }
    pthread_mutex_unlock(&new_flight->lock);
    return successful;
}
Question 5 (5 pt; mean 4.7) (see above)

If precautions are not taken, multiple simultaneous calls to BookTicket can deadlock. Which of the following are sufficient adjustments to prevent the deadlock? Select all that apply.

For this question:

  • assume ChangeTicket is not in use; and
  • ignore the trivial deadlock that occurs when the same flight is listed multiple times in a single call to BookTicket; only consider deadlocks that involve multiple calls to BookTicket.
Regrade request
Question 6 (4 pt; mean 3.52) (see above)

It's possible for a simulatenous call to ChangeTicket and BookTicket to deadlock (even when those calls would not deadlock if they occurred separately and when there are no other functions manipulating the tickets and flights). Which of the following are examples of calls that could trigger this deadlock? Select all that apply.

In the psuedocode below A, B, etc. represent distinct flights, {X, Y, Z} represents an array of flights X, Y, and Z, and <X, Y> represents a ticket whose flights are X and Y.

Regrade request


quiz for week 10

294 people have viewed this quiz

Consider a server where users connect to the server and receive messages from a list of announcements. The server implementation uses one thread for each connected user, and in addition has another thread that adds messages Each user is part of a single "channel" that has a message history. These are represented using structs as follows:

const char *messages[MAX_MESSAGES];
int last_message_index = -1;
struct User users[NUM_USERS];
pthread_mutex_t message_lock;
pthread_cond_t new_message_cv;

struct User {
    int last_read_message_index; /* initially -1 */
};

When adding a message to the list of announcements, the server calls an AddMessage function. The threads representing user connections repeatedly calls a function called GetNextMessage to wait for and return a next message.

Partial implementations of these functions is shown below (where a blank written with underscores like __________ represents some omitted code):

void AddMessage(const char *message) {
    pthread_mutex_lock(&message_lock);
    last_message_index += 1;
    messages[last_messsage_index] = message;

    ________________________________________________        /* BLANK 1 */
    pthread_mutex_unlock(&message_lock);
}

const char *GetNextMessage(struct User *user) {
    pthread_mutex_lock(&message_lock);

    while (___________________________________________________) {       /* BLANK 2 */
        pthread_cond_wait(&new_message_cv, &message_lock);             
    }
    user->last_read_message_index += 1;
    const char *result = messages[user->last_read_message_index];
    pthread_mutex_unlock(&message_lock);
    return result;
}
Question 1 (4 pt; mean 3.82) (see above)

What code would be most appropriate to place in the blank marked with the comment BLANK 1?

Regrade request
Question 2 (4 pt; mean 3.49) (see above)

What code would be most appropriate to place in the blank marked with the comment BLANK 2?

Regrade request
Question 3 (4 pt; mean 3.59)

Consider a scheme for sending a message from machine A to machine B using unreliable messages like the one we discussed in lecture:

Suppose we use this scheme to transmit a message and the network is very unreliable: specifically, it loses the every other message machine A sends, starting with the first; and also loses every third message machine B sends, starting with the first.

Assume, however, that the network does not corrupt messages and when messages are not lost they are received quickly.

How many messages will machine A send as part of its effort to transmit this data? If A will never finish sending messages, write "infinity".

Answer:
Key: 4

A -> B: part 1 (lost); A -> B: part 1; B -> A: ACK part 1 (lost); A -> B: part 1 (lost); A -> B: part 1; B -> A: ACK part 1

Regrade request

As part of retrieving a web page from a remote web server, a machine running a web browser will send an acknowledgment to the remote web server.

To send this, the machine running the web browser will send an Ethernet frame on its local network, that contains a IP packet, which contains a TCP segment.

Question 4 (4 pt; mean 3.31) (see above)

The frame that the machine running the web browser sends on its local network for this acknowledgment will contain as its destination MAC address ____.

Regrade request
Question 5 (4 pt; mean 3.38) (see above)

The frame that the machine running the web browser sends on its local network for this acknowledgment will contain as its destination IP address ____.

Regrade request
Question 6 (4 pt; mean 3.7) (see above)

The frame that the machine running the web browser sends on its local network for this acknowledgment will contain as its source port number ____.

Regrade request


quiz for week 11

297 people have viewed this quiz
Question 1 (4 pt; mean 3.53)

In lecture we discussed how when contacting a webserver like kytos02.cs.virginia.edu, several DNS servers are involved --- typically one or more a local DNS server run by the local ISP, DNS server(s) for cs.virginia.edu, server(s) for virginia.edu, and server(s) for .edu, and one for the root of the DNS hierarchy. If all the DNS servers for virginia.edu become inaccessible , then we would expect accessing web pages on kytos02.cs.virginia.edu from a machine outside UVa ___.

  1. also accepted

  2. best answer --- work from machines whose ISP's DNS server has it cached for a while until that cached version expires

was accidentally set as select-all-that-apply, but not intended

Regrade request
Question 2 (4 pt; mean 3.56)

Let's say two machines A and B connected to the same wifi network are erroneously configured to have the same IP address 10.1.2.3. When a third machine C on the same wifi network attempts to send a message to 10.1.2.3, the message is only received by machine A. What most likely happened?

Regrade request

For the following questions assume that:

Question 3 (4 pt; mean 3.51) (see above)

Suppose A receives a packet on the network with a destination of A and a source of B, and the packet contains:

  • a name;
  • data generated by encrypting the string "The number chosen is 1923437." with the shared encryption key
  • a message authentication code generated using the shared MAC key and the name

In this situation, A can be assured that ____. Select all that apply.

Regrade request
Question 4 (4 pt; mean 3.49) (see above)

Suppose A receives a packet on the network with a destination of A and a source of B, and the packet contains message encrypted with A's public key, and having as its contents:

  • a timestamp
  • B's public encryption key and
  • other data

In this situation, A can be assured that ____. Select all that apply.

  1. "other data" could have been produced by corrupting whatever A/B originally encrypted

Regrade request
Question 5 (5 pt; mean 4.36) (see above)

Suppose B manages a popular concert venue and trusts A to handle selling tickets for it. B receives information about what tickets are booked from A, and intends to use the shared encryption and MAC key to send this information over the network without the attacker being able to fraudalently book additional tickets.

B receives messages from A with a reports of sold ticket, containing:

  • the ticket holder's name
  • the seat number, encrypted with the shared encryption key
  • the concert date
  • the price for which A sold the ticket, encrypted with the shared encryption key
  • a message authentication code generated using the shared MAC key and the seat number and the concert date

B always recomputes that the message authentication code to verify that it matches the rest of the data in the message, and if it does not, B ignores the message and alerts A to the problem.

Which of the following can the machine-in-the-middle attacker do to disrupt the information B receives (without B detecting something is wrong)? Select all that apply.

Regrade request
Question 6 (4 pt; mean 3.31)

Suppose A and B want to communicate over an insecure network to agree about what to order for lunch.

They arrange to share public encryption and public signing keys, and decide to use the following [broken] protocol:

An attacker with sufficient control over the network (but who cannot interfere with A and B sharing their public keys securely) can interfere with the protocol to do which of the following? Selcet all that apply.

Regrade request


quiz for week 12

292 people have viewed this quiz

Answer the following questions about the lecture material for this week.

Question 1 (4 pt; mean 3.78)

One application of digital signatures is to support hardware "tokens" as an alternative or supplement to passwords. For example, users might be given a small device (called a "token") that plugs into a USB port that contains a low-power processor and a private key. To login to a computer, they would plug this device into that machine's USB port, Then, the computer would send a login request to the token, and the token would send back a digital signature of the request. The computer would verify the signature and permit the login accordingly.

In order to verify the signature, suppose the computer uses certificates.

Which of the following would be appropriate way to use certificates in this case? Select all that apply.

  1. would be true if read "signed by a certificate authority's private key" or "that can be verified with the certificate authority's public key" (which was what I intended, but not what I wrote); not true because of this error as written

Regrade request
Question 2 (5 pt; mean 4.78)

Consider the following insecure scheme for sending "secure" emails from A to B.

A and B share an (symmetric) encryption key. When A wants to send an email to B, A takes a cryptographic hash of their email's text. Then, they send an encrypted version of their email's text, followed by the cryptographic hash.

When B receives the email, B decrypts the text, and recomputes the hash value. If the hash value B recomputes does not match, B rejects the message as tampered with and discards it silently.

Which of the following attacks does this scheme allow, assuming the encryption algorithm and cryptographic hash themselves are secure? Select all that apply.

  1. assuming encryption scheme allows them to know how their tampering affects the message --- can change hash to hash for tampered message

  2. intended to write "prevent B from receivin email from A"; scheme did not address sending messages in the other direction, but the attacker could also prevent that

Regrade request
Question 3 (4 pt; mean 3.9)

A typical TLS handshake includes signing a cryptographic hash of prior messages with a long-term public key from the server.

A client that fails to verify this signature may ____. Select all that apply.

  1. the clients would be able to complete the key exchange operation, which is what I intended to test with this question. I see that a number of students read it as the clients being unable to know that the keys were correct, so gave credit for either answer.

This question's wording confused two separate operations in the handshake --- signing of the key share, and a Finished message which is created using a MAC over the prior handshake messages. I think the problem with either case is B --- but the reason why for the case where this is just the MAC is more that the handshake could have been part of some kind of replay attack (but that's hard to reason about).

Regrade request
Question 4 (4 pt; mean 3.54) (see above)

When executing the instruction addq %r8, %r9 on a single-cycle processor, the register file's inputs will include ___. Select all that apply.

Regrade request
Question 5 (4 pt; mean 3.8) (see above)

When executing the instruction addq %r8, %r9 on a five-stage pipelined processor uses the stages we discussed in lecture, during the decode stage, the register file's inputs will include ___. Select all that apply.

Regrade request
Question 6 (4 pt; mean 3.71)

Suppose a pipelined processor has three stages and a cycle time of 200ps.

When this processor executes five instructions, the amount of time from when the processor starts executing the first stage of the first instruction until when it finishes executing the last stage of the last instruction is _____ ps.

Assume nothing prevents the processor from starting a new instruction each cycle.

If not enough information is provided, write "unknown" and explain in the comments.

Answer:
Key: 3 * 200 (first instruction) + 4 * 200 (last stage of next 4 instructions) = 1400
Regrade request


quiz for week 13-4

294 people have viewed this quiz
Question 1 (4 pt; mean 3.56)

Suppose a single-cycle processor takes 1350 ps to execute each instruction. If we can divide the processor into a pipelined processor with:

and use pipeline registers (used to transfer values from one stage to the next, and not included in the work described above) with a 50ps delay. What (as integer number of ps) is the minimum cycle time the pipelined processor can have?

Answer:
Key: 400
Regrade request

Consider a seven-stage pipelined processor where the stages are:

Assume that the results of arithmetic instructions are not available until near the end of the execute, part 2 stage. The results of instructions that load values from memory are not available until near the end of the memory, part 2 stage. Instructions that perform arithmetic need the values for the arithmetic by near the beginning of the execute, part 1 stage.

The processor uses forwarding (when possible without dramatically increasing cycle time) in combination with stalling to resolve data hazards.

Question 2 (4 pt; mean 2.89) (see above)

When executing the following assembly snippet:

movq 0x1234(%r8), %r9     
addq %r9, %r10            

The processor will complete the writeback stage of the addq instruction ___ cycle(s) after it completes the writeback stage of the movq instruction.

Answer:
Key: 4
Regrade request
Question 3 (4 pt; mean 3.32) (see above)

When executing the following assembly snippet:

addq %r8, %r9
xorq %r9, %r10
subq %r9, %r11

The processor will complete the xorq instruction ___ cycle(s) after it completes the addq instruction, and will be complete the subq instruction ___ cycle(s) after it completes the xorq instruction.

Regrade request
Question 4 (4 pt; mean 3.36)

Consider a pipelined processor design with six pipeline stages with a cycle time of 500 ps.

When a benchmark program is run on this processor:

Suppose these are the only cause of the processor not running one instruction per cycle.

If the benchmark program has one billion instructions, how long, in milliseconds to the nearest millisecond, does it take to run on this processsor?

[1 billion picoseconds is 1 millisecond.]

Answer:
Key: 640

meant to write "of stalling and forwarding" instead of "of stalling a forwarding" (I hope this didn't confuse people???)

(1 + .1 + .05 * 2 + .02 * 4) cycles/instruction * 500 ps/cycle = 640 ps/instruction

1B instructions * 640 ps/instruction = 640 ms

Regrade request

Suppose a processor runs the following assembly snippet:

    movq $3, %r10
outer: 
    movq $2, %r11
inner:
    call foo
    subq $1, %r11
    cmpq $0, %r11
    jg inner
    subq $1, %r10
    cmpq $0, %r10
    jg outer

which could have been generated from this C code:

for (int i = 3; i > 0; i--) {
    for (int j = 2; j > 0; j--) {
        foo();
    }
}
Question 5 (4 pt; mean 2.26) (see above)

Suppose this processor uses a branch prediction strategy where it predicts a branch (such as a conditional jump) as taken if and only if it ran before and was taken the last time it ran (and predicts it as not taken otherwise). (This means that if a conditional jump has never been run before, it is always predicted as not taken.)

Ignoring what happens in the function foo, the first time the above snippet is run, how many correct branch predictions for the jg instructions will happen?

Answer:
Key: 1
Regrade request
Question 6 (4 pt; mean 3.56)

Consider the following assembly snippet:

addq %r9, %r10
movq 0(%r13), %r9
subq %r9, %r11

On an out-of-order processor, it's possible for the addq's result to be computed after the subq's result is, depending on the speed of the instructions before the assembly snippet and the movq in the assembly snippet. Which of the following make this more likely to happen than otherwise? (In this question, when an instruction is "unusually slow", it takes longer than normal for an instruction's result to be available once it is fetched.) Select all that apply.

Regrade request


quiz for week 15

287 people have viewed this quiz
Question 1 (5 pt; mean 3.95)

Consider the following assembly snippet:

addq %r8, %r9
xorq %r9, %r10
imulq %r10, %r12
addq %r11, %r10
imulq %r10, %r13
subq %r9, %r14

When executed on an out-of-order processor, which instructions from the snippet could have their results computed at the same time as imulq %r10, %r12 on this processor? Select all that apply.

Regrade request
Question 2 (4 pt; mean 3.76)

Suppose an out-of-order processor using a design like we discused in lecture has 3 ALUs that each can perform an addition in one cycle.

If the processor is running the following assembly snippet:

addq %r8,  %r14
addq %r9,  %r15
addq %r10, %r14
addq %r11, %r15
addq %r12, %r14
addq %r13, %r15
addq %r14, %r15

To perform the additions for the assembly snippet, the processor must use a minimum of ___ cycles. (Do not include the time needed to load the instructions into the instruction queue or needed to writeback values or commit instructions. Assume once a computation is performed, its results can be used in a computation during the next cycle.)

Answer:
Key: 4
Regrade request

Consider the following C function that adds two arbitrary-precision integers represented by an array of digit values ranging from 0 to 9, starting with the 1's place.

void AddNumbers(int num_digits, const char *a_digits, const char *b_digits, char *result_digits) {
    char carry = 0;
    for (int i = 0; i < num_digits; ++i) {
        result_digits[i] = a_digits[i] + b_digits[i] + carry;
        carry = 0;
        while (result_digits[i] > 10) {
            result_digits[i] -= 10;
            carry += 1;
        }
    }
}

Assume this is translated to assembly in a way which does not omit any arithmetic operations written in the C code above and that it runs on a processor where each arithmetic and comparison instruction takes a constant amount of time.

Question 3 (4 pt; mean 3.71) (see above)

Suppose we find that running the function with num_digits of 4 and a_digits of {9, 8, 7, 0} and b_digits of {2, 2, 1, 1} is consistently slower than running with an a_digits value of {5, 8, 1, 1} and an unknown value of b_digits.

Which of the following would be plausible values for b_digits?

  1. would be false if code corrected to do result_digits[i] >= 10

  2. would be false if code corrected to do result_digits[i] >= 10

Regrade request
Question 4 (4 pt; mean 2.27) (see above)

Suppose we knew that the AddNumbers() function above was called with a_digits being the address 0x1000000, b_digits the address 0x2000000 and result_digits the address 0x3000000.

Using a side-chanel we determine that running AddNumbers() accesses cache set indexes 0 through 2 inclusive of a 64KB direct-mapped cache with 32-byte blocks. Assuming that only accesses to a_digits, b_digits, and result_digits used this cache, give a possible value of num_digits.

Answer:
Key: between 65 and 96 inclusive
Regrade request

Consider the following C code:

struct message {
    unsigned int message_type;
    unsigned int message_length;
    char *data;
}; 

struct message_type {
     unsigned int seen_messages;
     ...
};

struct message pending_messages[MAX_NUM_MESSAGES];
struct message_type message_types[NUM_MESSAGE_TYPES];

void HandleMessage(int index) {
     if (index < MAX_NUM_MESSAGES) {
         unsigned int type = pending_messages[index].message_type;
         if (type < NUM_MESSAGE_TYPES) {
              message_types[type].seen_messages += 1;
              ... // additional message handling code
         }
     } else {
         abort();
     }
}

Assume that:

If an attacker can cause the above code to execute speculatively with a chosen value of the argument index, then they can use the above code to execute a Spectre-style attack and read an integer from memory at an attacker-chosen address that the above code can access but the attacker cannot.

In particular, the attacker would set index such that pending_messages[index].message_type ends up being located at the address. The code that increments seen_messages would access a memory location based on this value, which will cause the cache to be modified (even if this code is only executed speculatively).

The attacker will use a side channel to determine which sets of the data cache were accesssed when the increment of seen_messages was speculatively executed, and therefore learn about the value of type, which is the same as the value in the memory location the attacker chose.

Question 5 (4 pt; mean 2.51) (see above)

Suppose an attacker selects index such that type ends up being the value of an attacker-chosen address when the above code is run as part of a branch misprediction. If the attacker discovers that cache set index 44 is modified as a result of message_types[type].seen_messages += 1, then a possible value of type was ____. Write your answer as a hexadecimal number.

Answer:
Key: 0x716 or 0xf16 or 0x1716 or 0x1f16 or, etc.

messge_types[0].seen_messages is in set 512, message_types[1].seen_messages in set 514, message_types[2].seen_messages in set 516, message_types[3].seen_messages in set 519, message_types[4].seen_messages in set 520, etc.

44 - 512 + 4096 = 3628 blocks away, or 3628 + 4096, or 4628 + 4096 * 2, etc.

3628 or 3628 + 4096 or 3628 + 4096*2 blocks ~~ index 3628/2 = 1814 or 1814+2048 = 3862 or ...

or, converted to hex 0x716 or 0xf16 or 0x1716 or 0x1f16, etc.

Regrade request
Question 6 (4 pt; mean 3.37) (see above)

Which of the following changes to the above code would make the attack infeasible? Select all that apply.

Regrade request