1

I was always a bit hazy on this little bit of C magic. When you call execv, you're "replacing the process image." What exactly does that mean? Just the DATA segment? Everything allocated to the process? The stack? The heap?

My question is about what happens to the storage used by the parameters that you pass to execv? If they were local variables to the function that called execv, then they're on the stack. But if you replace the process image, and call the new process's main() function, bad things would happen when main() returned, because the stack information that points to the return location from the main call was replaced by the new process image. Same thing for variables, yes? And what if those variables were allocated on the heap?

Inquiring minds are inquiring to anybody who knows.

too honest for this site
  • 12,050
  • 4
  • 30
  • 52
stu
  • 8,461
  • 18
  • 74
  • 112
  • I think [this](http://www.qnx.com/developers/docs/6.3.2/neutrino/lib_ref/e/execv.html) could be the best answer. – Punit Vara Dec 06 '15 at 13:29
  • The official documentation for you reference: http://pubs.opengroup.org/onlinepubs/9699919799/functions/exec.html – alk Dec 06 '15 at 13:31
  • The OS is required to set up the new address space so that everything the program needs to get started is available - which may include copying the parameters. – Alan Stokes Dec 06 '15 at 13:33
  • There's no such thing as a "return location from the main call". When `main` returns the program ends. – interjay Dec 06 '15 at 13:33

2 Answers2

2

The exec family of functions replace the process wholesale - data, stack, text, heap, everything. Some file descriptors can stay open (those opened by the original process without FD_CLOEXEC set). But apart from that, you pretty much get a whole new process - see the link for all the details.

What happens to the parameters you passed in is the OS's problem - it has to make sure they're passed to the new process's main function in a way that complies with the standard, but I don't think POSIX dictates exactly how it does that.

For Linux, you can look at the fs/exec.c file to see the implementation. Jump near the end (line 1484 as I post this) to look at the do_execveat_common function which is the main part of the implementation. You'll see the arguments are copied into the new address space (calls to copy_strings near the end of the function).

Mat
  • 202,337
  • 40
  • 393
  • 406
2

Just the DATA segment?

No, all memory mappings are erased and re-create for the new executable

Everything allocated to the process? The stack? The heap?

Yes, all memory. Some kernel resources, documented here, are inherited from the parent process though, such as file descriptors. These resources are managed by the kernel, and are not part of the process memory. All of this is quite operating system specific though, it can accomplish this through various means as long as it complies with the mentioned exec() documentation.

what happens to the storage used by the parameters that you pass to execv?

Typically the kernel makes a copy of those arguments, and injects them into the memory of the new executable.

But if you replace the process image, and call the new process's main() function, bad things would happen when main() returned,

No, when main() returns, that process ends. The code and memory of the original process that called exec() doesn't exist any more, there's nothing to return to.

nos
  • 223,662
  • 58
  • 417
  • 506
  • Right, that's what I meant by bad things would happen. I just didn't get the disconnect between the storage of params passed to a new universe where the old universe is gone. – stu Dec 06 '15 at 14:44