3

Manpage of execve() says

execve() executes the program pointed to by filename. This causes the program that is currently being run by the calling process to be replaced with a new program, with newly initialized stack, heap, and (initialized and uninitialized) data segments.

In case that the calling process was created by vfork(), it means that exec() provides a new address space for the new program; it doesn’t modify the parent address space..

If the calling process was created more generally by fork(), what normally happens to the old "stack, heap, and (initialized and uninitialized) data segments"? Are their spaces deallocated?

Does the behavior of execve() depend on how the calling process was created?

Before seeing the quote, I thought that execve() would overwrite the old "stack, heap, and (initialized and uninitialized) data segments", instead of creating new ones. So when I saw the quote, wonder why waste the new space?

Thanks.

1 Answer 1

3

Does the behavior of execve() depend on how the calling process was created?

No.

Before seeing the quote, I thought that execve() would overwrite the old "stack, heap, and (initialized and uninitialized) data segments", instead of creating new ones.

No: execve() creates new segments and deallocates the old ones.

So when I saw the quote, wonder why waste the new space?

Try to remember, we are talking about virtual memory!

Creating a blank segment only allocates a small amount of physical memory, to track the segment. The size of that allocation is fixed, no matter how large the segment is.

A physical page must be allocated for each page you write to. The parent process might have written to a large number of pages. But if the child only uses a little stack/heap/data when it runs, there is no good reason for it to keep references to all the dirty pages from the parent! It will waste memory if the parent exits and the child continues running.

Removing the references to the old segments and the old pages is the most efficient approach. Because if that was the only reference to that memory, the physical memory can be deallocated.

4
  • with aslr off, the same stack is used even after exec, I checked and verified this
    – Arun Kp
    Commented Dec 4, 2021 at 5:27
  • 1) how did you? 2) I think you're missing a criteria if RLIMIT_STACK was changed, at least if it was reduced then the stack shouldn't always be re-used in the exact same form, right? I had a quick search and it doesn't look like the kernel bothers to keep the old stack if RLIMIT_STACK is not changed, I could be missing something though.
    – sourcejedi
    Commented Dec 4, 2021 at 12:05
  • i checked the stack virtual address range before and after exec using a kernel module and it remained same. Please correct me If I am wrong here
    – Arun Kp
    Commented Dec 6, 2021 at 17:48
  • I don't know how the stack base address is chosen. But, as per the answer, if the old stack was kept but re-initialized, it could waste physical memory which might never be needed by the new process. (It also seems like a waste of time). Being efficient at core unix features like fork()+exec() has been a key concern for Linux developers for many years, so I think it allocates completely new virtual memory for the new stack.
    – sourcejedi
    Commented Dec 6, 2021 at 19:40

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .