4

I'm very new to threads, processes, execv, etc. I have researched and found that when you execute an execv, it takes the space of the calling process. I am wondering what happens when you create a thread in main, and then call execv, directly after the thread (not before it finishes but right after the thread is created). I know execv will replace main but does this mean that it will also replace the thread or will the thread be able to execute and complete like normal?

Small example of what I'm asking:

  int main(){
      printf("hello from main!);
      char *buffer = "some data";

    if(pthread_creat(&mythreadpid, NULL, thread1, buffer){
        printf("ERROR!!");
     }

     execv(...) //do execv here

}

void *thread1(void *buffer){
  printf("calling from my thread!");

 //do something else

}

I have tested this and I did experience strange behavior as my thread wouldn't complete so I want to know if this is the reason for it

unconditionalcoder
  • 723
  • 1
  • 13
  • 25
  • `execv` replaces the whole process, not just one thread. – Barmar Oct 28 '16 at 01:17
  • so it will replace my thread created from main AND main? – unconditionalcoder Oct 28 '16 at 01:17
  • 1
    Yes, all the memory and state of the current process is overwritten by exec, except for the environment and open file descriptors. – Barmar Oct 28 '16 at 01:19
  • okay, will this be the same if I were to create a process instead of a thread or will that new process not get replaced? – unconditionalcoder Oct 28 '16 at 01:20
  • the child process wild execute the new code but not his parent. use fork() in C – Stargateur Oct 28 '16 at 01:23
  • @Barmar, the environment is also specified in execv and by that reason is also replaced (the calls that don't specify it, take it from the received environment), like the `argc` and `argv` parameters to `main()`. Open file descriptors that don't have the `O_CLOEXEC` are also preserved, but others are closed on an `exec*(2)` syscall. – Luis Colorado Nov 03 '16 at 07:00
  • @LuisColorado I didn't think I needed to put a full description of exec in my one-line comment. As pointed out by caf in his comment to my answer, there are lots of other things preserved by exec, that's why I took the detail out of my answer. – Barmar Nov 03 '16 at 16:46
  • @Barmar, i completely agree with you, but i'd never put the environment in the first place of resources preserved acros an `exec*(2)` call, because is *always* replaced by the one passed to the syscall. And the reason is the one I used, and I also write my comments to illustrate things. – Luis Colorado Nov 03 '16 at 17:27

1 Answers1

7

All the exec functions replace the entire process with the program being executed. All threads are destroyed.

If you want to execute another program without affecting the current process, you should use fork() first to create a new process, and call execv() in the child process. See Is it safe to fork from within a thread? for some caveats to be aware of when using fork() in a multi-threaded program.

Community
  • 1
  • 1
Barmar
  • 741,623
  • 53
  • 500
  • 612
  • Far more state than just environment and open file descriptors are maintained across exec: eg. current working directory; the disposition of ignored signals and signal masks; umask; ptrace state... – caf Oct 28 '16 at 01:28
  • @caf Thanks, I had a feeling I was missing some details. I just removed that since it's not really important to this question. – Barmar Oct 28 '16 at 01:32
  • @caf, as I tell in another comment to the question, environment **is specified** in the call to `exec*(2)`, so it's also replaced. Environment is saved in the virtual space of a process, and the only preserved things are resources like open descriptors, that are not stored in the process virtual address space. The calls that don't ask for a new environment, just use the environment received as parameter to the new `exec*(2)` call. Only open descriptors that *don't have* the `O_CLOEXEC` flag are preserved. The ones that have it will be closed. You also loose all the `mmap(2)`ed segments. – Luis Colorado Nov 03 '16 at 07:07
  • @LuisColorado The environment is only specified in `execve` and `execle`. But all of this is irrelevant to my answer, that's why I took out any mention of what's retained. – Barmar Nov 03 '16 at 16:48
  • @Barmar, I only stated that the environment is mapped on the virtual space of a process, and as such, it cannot be preserved. No unix saves the environment in a system place, as accesing it would require system calls. The other `execl(2)` and `execv(2)` and their path counterparts take the environment from the `environ` global variable. Indeed you can pass `NULL` and then you get no environment at all. – Luis Colorado Nov 03 '16 at 17:22
  • @LuisColorado Isn't that what we mean by saying that `exec` preserves the environment? – Barmar Nov 03 '16 at 17:39