0

I implemented a function to simulate load_arg in i386. When debugging with VSCode, I found that on the third last line of the function:

*(size_t*)stack_top = argc;

At the end of this line, argc was not stored in *(size_t*)stack_top, and VSCode displayed "optimized out" (as shown in the figure).

How can I solve this problem? Or how can I put the value of argc into *(size_t*)stack_top?

uint32_t load_arg(PD *pgdir, char *const argv[]) {
  char *stack_top = (char*)vm_walk(pgdir, USR_MEM - PGSIZE, 7) + PGSIZE;

  size_t argv_va[MAX_ARGS_NUM + 1];
  int argc;
  for (argc = 0; argv[argc]; ++argc) {
    assert(argc < MAX_ARGS_NUM);
    // push the string of argv[argc] to stack, record its va to argv_va[argc]
    stack_top -= (strlen(argv[argc])+1);
    strcpy(stack_top, argv[argc]);
    argv_va[argc] = USR_MEM - PGSIZE + ADDR2OFF(stack_top);
  }
  argv_va[argc] = 0; // set last argv NULL
  stack_top -= ADDR2OFF(stack_top) % 4; // align to 4 bytes
  for (int i = argc; i >= 0; --i) {
    // push the address of argv_va[argc] to stack to make argv array
    stack_top -= sizeof(size_t);
    *(size_t*)stack_top = argv_va[i];
  }

  // push the address of the argv array as argument for _start
  stack_top -= sizeof(size_t);
  *(size_t*)stack_top = USR_MEM - PGSIZE + ADDR2OFF(stack_top);

  //push argc as argument for _start
  stack_top -= sizeof(size_t);
  *(size_t*)stack_top = argc;
  stack_top -= sizeof(size_t); // a hole for return value (useless but necessary)
  return USR_MEM - PGSIZE + ADDR2OFF(stack_top);
}

VSCode screenshot

Peter Cordes
  • 328,167
  • 45
  • 605
  • 847
  • 1
    How did you verify that you cannot store that value? The message in the debugger does not mean you could not store. It just means that there is no storage location available in debug information for that variable. – Gerhardh Mar 06 '23 at 10:37
  • Because, for example, the following statement will display the assigned value in the VSCode debugger. So, if it is not displayed in the debugger, I assume that it has not been assigned: *(size_t*)stack_top = argv_va[i]; – Peter Harry Mar 06 '23 at 10:50
  • 2
    No, that just means the debugger doesn't know where in the asm (registers or memory) to look for the current value of that named C variable from the C abstract machine. This is common when you compile with optimization, since compilers often invent temporaries that get used instead of named C vars, even though they often hold the same data if it didn't transform an array index into a pointer incr . (This is not ideal, but compiling without optimization gives consistent debugging. The actual return value should still be the same with optimization enabled, if there's no undefined behaviour.) – Peter Cordes Mar 06 '23 at 10:59
  • 1
    The instructions in your description don't match those in your code. `(size_t)stack_top` is not the same as `*(size_t*)stack_top`. Please be precise. Also `(size_t)stack_top` is not something you could assign a value to. The result of a cast can never be used as target for an assignment. Regarding your doubts: If you want to see if you could assign the value, you must either inspect `*stack_top` in debugger or print the value in your code. – Gerhardh Mar 06 '23 at 11:13
  • @Gerhardh: Look at the italics; they wrote `*(size_t*)stack_top` in the markdown without putting backticks around it, so it came out as *(size_t*)stack_top. I didn't notice that when I edited to fix the tags, but I'll edit again now. – Peter Cordes Mar 06 '23 at 14:26

0 Answers0