We’re working on execv and we’re having some trouble with the final portion when it comes to copying out the
argv pointer values back onto the user stack.
As a preface, by the time we reach this problem we’ve already safely copied in all arguments from the user stack, loaded them into one large string (including the necessary null terminator offsets to keep everything 4-byte aligned), copied that string out to the user stack, and then copied out an empty
char ** argv array with a
NULL value for the final element to the user stack. Note that this array size is the number of arguments + 1 for the
NULL element at the end of the array.
Initially we tried filling this
argv array with the proper userstack addresses pointing to each string argument before copying out, but apparently (as noted by two different TA’s), those addresses are “lost in translation” during the
copyout process (I’d be interested to hear the “why” on this).
For this reason, we instead are trying to
copyout the “empty”
argv array first, and then 1-by-1
copyout the proper
char * address (the user stack address of the first character of each arg) to each 4-byte element in
The problem is that after the
copyout, the address value that ends up in
argv[i] on the userstack doesn’t match the value of the
src argument that we pass to
copyout. We verified this by printing the address value right before the
copyout call, and then right after doing a
copyin of 4 bytes at that same address we just copied out to see the difference. If we copy out the address
0x7fffffe0, when we copy back in to verify that the addresses are the same (i.e. the same value made it onto the user stack), we get back
0x2f746573. Another example is copying out
0x7ffffff4, and getting back
The error thrown after our call to
enter_new_process is a TLB miss on load error. The
vaddr is one-off from one of the values that’s (incorrectly) copied out…
Fatal user mode trap 2 sig 11 (TLB miss on load, epc 0x401480, vaddr 0x44616c64)
To explain our
copyout call in more detail, our
src argument is a
userptr_t that contains the address value that we want to copy out, which we cast to a
char * (behavior is the same if we don’t cast). This points to the relevant arg’s first char address on the user stack. The destination arg is a
userptr_t that is set to the first byte of
argv[i] on the user stack, and the size argument is set to 4 bytes.
We’re not sure how to proceed on this. I’m definitely going to try and get a TA’s help tomorrow, but with everyone in crunch time it’s sometimes hard to get help. Can anyone see anything we’re doing wrong here? Please let me know if any additional info would be helpful. Thanks for taking the time to read!