Does a Windows process need to be terminated by ExitProces() or TerminateProcess()? The Next CEO of Stack OverflowHow can I develop for iPhone using a Windows development machine?How can you find out which process is listening on a port on Windows?Really killing a process in WindowsWindows batch files: .bat vs .cmd?Is there an equivalent of 'which' on the Windows command line?Ignoring directories in Git repos on WindowsWhat does the /TSAWARE linker flag do to the PE executable?How do I install pip on Windows?How do I run two commands in one line in Windows CMD?Node.js/Windows error: ENOENT, stat 'C:UsersRTAppDataRoamingnpm'

When airplanes disconnect from a tanker during air to air refueling, why do they bank so sharply to the right?

How to safely derail a train during transit?

Should I tutor a student who I know has cheated on their homework?

Can the Reverse Gravity spell affect the Meteor Swarm spell?

How to write papers efficiently when English isn't my first language?

What can we do to stop prior company from asking us questions?

WOW air has ceased operation, can I get my tickets refunded?

Grabbing quick drinks

How can I quit an app using Terminal?

How can I get through very long and very dry, but also very useful technical documents when learning a new tool?

Can a single photon have an energy density?

How do I go from 300 unfinished/half written blog posts, to published posts?

Are there languages with no euphemisms?

Why does C# sound extremely flat when saxophone is tuned to G?

Apart from "berlinern", do any other German dialects have a corresponding verb?

Is HostGator storing my password in plaintext?

How do I construct this japanese bowl?

India just shot down a satellite from the ground. At what altitude range is the resulting debris field?

Horror movie/show or scene where a horse creature opens its mouth really wide and devours a man in a stables

Which organization defines CJK Unified Ideographs?

Only print output after finding pattern

Why doesn't a table tennis ball float on the surface? How do we calculate buoyancy here?

How to count occurrences of text in a file?

Was a professor correct to chastise me for writing "Prof. X" rather than "Professor X"?



Does a Windows process need to be terminated by ExitProces() or TerminateProcess()?



The Next CEO of Stack OverflowHow can I develop for iPhone using a Windows development machine?How can you find out which process is listening on a port on Windows?Really killing a process in WindowsWindows batch files: .bat vs .cmd?Is there an equivalent of 'which' on the Windows command line?Ignoring directories in Git repos on WindowsWhat does the /TSAWARE linker flag do to the PE executable?How do I install pip on Windows?How do I run two commands in one line in Windows CMD?Node.js/Windows error: ENOENT, stat 'C:UsersRTAppDataRoamingnpm'










0















I have this simple program:



#include <windows.h>
int WINAPI startMeUp()
return 0;



which I compile using the command line tools of Visual Studio like so:



cl /nologo /GS- /Gs- /c /W4 main.c /Fomain.obj
link /nologo main.obj /subsystem:console /entry:startMeUp /nodefaultlib kernel32.lib user32.lib /OUT:the.exe


When I then execute .the.exe, a message box is shown that says the.exe has stopped working - A problem caused the program to stop working correctly. Windows will close the program and notify you if a solution is available



After replacing the return 0; with ExitProcess(0); and re-compiling/linking it, .the.exe runs just fine.



So, it seems to me that ExitProcess() is needed to correctly end a process.



Since I am pretty sure that I already had working programs that returned from the entry-point function by returning an exit value, I am not sure if portable executables require a process to be terminated by ExitProcess().



Edit
Interestingly, if I place a MessageBox(NULL, "world", "hello", 0); before the return 0; (and thus don't have an ExitProcess() call), the executable also runs ok.



Edit II
When I add the linker option /export:startMeUp, the linker warns me with LNK4216 but I can execute the created without problem.



When I use dumpbin /all on both exes created, I see that the faulty executable has



 0 [ 0] RVA [size] of Export Directory


while the new, working one has



2000 [ 40] RVA [size] of Export Directory


Also, the working executable consists of two sections: .text and .rdata while the faulty one only has the .text section. The executable code seems to be included in the .rdata section, thus it is missing in the faulty one.



As to why that is, I have no clue.










share|improve this question
























  • Usually you don't provide /entry, and do provide a WinMain function. This starts up the c/c++ runtime which is going to be important for any non trivial application as its nice to have global initializers run, and floating point and exception support available.

    – Chris Becke
    Mar 8 at 13:15







  • 1





    Also, perhaps your signature is wrong. When ive done my own entry point in the past, the application simply closed when I returned in trivial apps, and did not when I didn't - if you don't call ExitProcess then the process won't close if there are any worker threads created, and lots of things expect to create worker threads.

    – Chris Becke
    Mar 8 at 13:18











  • Yeah, get rid of the custom entry point and let the runtime do the work for you

    – David Heffernan
    Mar 8 at 13:19






  • 2





    Hmm. In NT 6.0+, threads start at RtlUserThreadStart, which gets passed the image entry point and the PPEB. But first an APC calls LdrInitializeThunk to initialize the process. kernel32.dll initializes the Kernel32ThreadInitThunkFunction function pointer to BaseThreadInitThunk, which gets called from RtlUserThreadStart with the image entry point and PPEB. This in turn calls the image entry point with the PPEB. The return value is passed to RtlExitUserThread. If it's the only thread, it calls RtlExitUserProcess, which in turn calls LdrShutdownProcess and NtTerminateProcess.

    – eryksun
    Mar 8 at 15:01






  • 1





    It should work fine. It works for me in Windows 10.

    – eryksun
    Mar 8 at 15:02















0















I have this simple program:



#include <windows.h>
int WINAPI startMeUp()
return 0;



which I compile using the command line tools of Visual Studio like so:



cl /nologo /GS- /Gs- /c /W4 main.c /Fomain.obj
link /nologo main.obj /subsystem:console /entry:startMeUp /nodefaultlib kernel32.lib user32.lib /OUT:the.exe


When I then execute .the.exe, a message box is shown that says the.exe has stopped working - A problem caused the program to stop working correctly. Windows will close the program and notify you if a solution is available



After replacing the return 0; with ExitProcess(0); and re-compiling/linking it, .the.exe runs just fine.



So, it seems to me that ExitProcess() is needed to correctly end a process.



Since I am pretty sure that I already had working programs that returned from the entry-point function by returning an exit value, I am not sure if portable executables require a process to be terminated by ExitProcess().



Edit
Interestingly, if I place a MessageBox(NULL, "world", "hello", 0); before the return 0; (and thus don't have an ExitProcess() call), the executable also runs ok.



Edit II
When I add the linker option /export:startMeUp, the linker warns me with LNK4216 but I can execute the created without problem.



When I use dumpbin /all on both exes created, I see that the faulty executable has



 0 [ 0] RVA [size] of Export Directory


while the new, working one has



2000 [ 40] RVA [size] of Export Directory


Also, the working executable consists of two sections: .text and .rdata while the faulty one only has the .text section. The executable code seems to be included in the .rdata section, thus it is missing in the faulty one.



As to why that is, I have no clue.










share|improve this question
























  • Usually you don't provide /entry, and do provide a WinMain function. This starts up the c/c++ runtime which is going to be important for any non trivial application as its nice to have global initializers run, and floating point and exception support available.

    – Chris Becke
    Mar 8 at 13:15







  • 1





    Also, perhaps your signature is wrong. When ive done my own entry point in the past, the application simply closed when I returned in trivial apps, and did not when I didn't - if you don't call ExitProcess then the process won't close if there are any worker threads created, and lots of things expect to create worker threads.

    – Chris Becke
    Mar 8 at 13:18











  • Yeah, get rid of the custom entry point and let the runtime do the work for you

    – David Heffernan
    Mar 8 at 13:19






  • 2





    Hmm. In NT 6.0+, threads start at RtlUserThreadStart, which gets passed the image entry point and the PPEB. But first an APC calls LdrInitializeThunk to initialize the process. kernel32.dll initializes the Kernel32ThreadInitThunkFunction function pointer to BaseThreadInitThunk, which gets called from RtlUserThreadStart with the image entry point and PPEB. This in turn calls the image entry point with the PPEB. The return value is passed to RtlExitUserThread. If it's the only thread, it calls RtlExitUserProcess, which in turn calls LdrShutdownProcess and NtTerminateProcess.

    – eryksun
    Mar 8 at 15:01






  • 1





    It should work fine. It works for me in Windows 10.

    – eryksun
    Mar 8 at 15:02













0












0








0








I have this simple program:



#include <windows.h>
int WINAPI startMeUp()
return 0;



which I compile using the command line tools of Visual Studio like so:



cl /nologo /GS- /Gs- /c /W4 main.c /Fomain.obj
link /nologo main.obj /subsystem:console /entry:startMeUp /nodefaultlib kernel32.lib user32.lib /OUT:the.exe


When I then execute .the.exe, a message box is shown that says the.exe has stopped working - A problem caused the program to stop working correctly. Windows will close the program and notify you if a solution is available



After replacing the return 0; with ExitProcess(0); and re-compiling/linking it, .the.exe runs just fine.



So, it seems to me that ExitProcess() is needed to correctly end a process.



Since I am pretty sure that I already had working programs that returned from the entry-point function by returning an exit value, I am not sure if portable executables require a process to be terminated by ExitProcess().



Edit
Interestingly, if I place a MessageBox(NULL, "world", "hello", 0); before the return 0; (and thus don't have an ExitProcess() call), the executable also runs ok.



Edit II
When I add the linker option /export:startMeUp, the linker warns me with LNK4216 but I can execute the created without problem.



When I use dumpbin /all on both exes created, I see that the faulty executable has



 0 [ 0] RVA [size] of Export Directory


while the new, working one has



2000 [ 40] RVA [size] of Export Directory


Also, the working executable consists of two sections: .text and .rdata while the faulty one only has the .text section. The executable code seems to be included in the .rdata section, thus it is missing in the faulty one.



As to why that is, I have no clue.










share|improve this question
















I have this simple program:



#include <windows.h>
int WINAPI startMeUp()
return 0;



which I compile using the command line tools of Visual Studio like so:



cl /nologo /GS- /Gs- /c /W4 main.c /Fomain.obj
link /nologo main.obj /subsystem:console /entry:startMeUp /nodefaultlib kernel32.lib user32.lib /OUT:the.exe


When I then execute .the.exe, a message box is shown that says the.exe has stopped working - A problem caused the program to stop working correctly. Windows will close the program and notify you if a solution is available



After replacing the return 0; with ExitProcess(0); and re-compiling/linking it, .the.exe runs just fine.



So, it seems to me that ExitProcess() is needed to correctly end a process.



Since I am pretty sure that I already had working programs that returned from the entry-point function by returning an exit value, I am not sure if portable executables require a process to be terminated by ExitProcess().



Edit
Interestingly, if I place a MessageBox(NULL, "world", "hello", 0); before the return 0; (and thus don't have an ExitProcess() call), the executable also runs ok.



Edit II
When I add the linker option /export:startMeUp, the linker warns me with LNK4216 but I can execute the created without problem.



When I use dumpbin /all on both exes created, I see that the faulty executable has



 0 [ 0] RVA [size] of Export Directory


while the new, working one has



2000 [ 40] RVA [size] of Export Directory


Also, the working executable consists of two sections: .text and .rdata while the faulty one only has the .text section. The executable code seems to be included in the .rdata section, thus it is missing in the faulty one.



As to why that is, I have no clue.







windows winapi portable-executable entry-point






share|improve this question















share|improve this question













share|improve this question




share|improve this question








edited Mar 8 at 15:52







René Nyffenegger

















asked Mar 8 at 13:10









René NyffeneggerRené Nyffenegger

26.4k17109183




26.4k17109183












  • Usually you don't provide /entry, and do provide a WinMain function. This starts up the c/c++ runtime which is going to be important for any non trivial application as its nice to have global initializers run, and floating point and exception support available.

    – Chris Becke
    Mar 8 at 13:15







  • 1





    Also, perhaps your signature is wrong. When ive done my own entry point in the past, the application simply closed when I returned in trivial apps, and did not when I didn't - if you don't call ExitProcess then the process won't close if there are any worker threads created, and lots of things expect to create worker threads.

    – Chris Becke
    Mar 8 at 13:18











  • Yeah, get rid of the custom entry point and let the runtime do the work for you

    – David Heffernan
    Mar 8 at 13:19






  • 2





    Hmm. In NT 6.0+, threads start at RtlUserThreadStart, which gets passed the image entry point and the PPEB. But first an APC calls LdrInitializeThunk to initialize the process. kernel32.dll initializes the Kernel32ThreadInitThunkFunction function pointer to BaseThreadInitThunk, which gets called from RtlUserThreadStart with the image entry point and PPEB. This in turn calls the image entry point with the PPEB. The return value is passed to RtlExitUserThread. If it's the only thread, it calls RtlExitUserProcess, which in turn calls LdrShutdownProcess and NtTerminateProcess.

    – eryksun
    Mar 8 at 15:01






  • 1





    It should work fine. It works for me in Windows 10.

    – eryksun
    Mar 8 at 15:02

















  • Usually you don't provide /entry, and do provide a WinMain function. This starts up the c/c++ runtime which is going to be important for any non trivial application as its nice to have global initializers run, and floating point and exception support available.

    – Chris Becke
    Mar 8 at 13:15







  • 1





    Also, perhaps your signature is wrong. When ive done my own entry point in the past, the application simply closed when I returned in trivial apps, and did not when I didn't - if you don't call ExitProcess then the process won't close if there are any worker threads created, and lots of things expect to create worker threads.

    – Chris Becke
    Mar 8 at 13:18











  • Yeah, get rid of the custom entry point and let the runtime do the work for you

    – David Heffernan
    Mar 8 at 13:19






  • 2





    Hmm. In NT 6.0+, threads start at RtlUserThreadStart, which gets passed the image entry point and the PPEB. But first an APC calls LdrInitializeThunk to initialize the process. kernel32.dll initializes the Kernel32ThreadInitThunkFunction function pointer to BaseThreadInitThunk, which gets called from RtlUserThreadStart with the image entry point and PPEB. This in turn calls the image entry point with the PPEB. The return value is passed to RtlExitUserThread. If it's the only thread, it calls RtlExitUserProcess, which in turn calls LdrShutdownProcess and NtTerminateProcess.

    – eryksun
    Mar 8 at 15:01






  • 1





    It should work fine. It works for me in Windows 10.

    – eryksun
    Mar 8 at 15:02
















Usually you don't provide /entry, and do provide a WinMain function. This starts up the c/c++ runtime which is going to be important for any non trivial application as its nice to have global initializers run, and floating point and exception support available.

– Chris Becke
Mar 8 at 13:15






Usually you don't provide /entry, and do provide a WinMain function. This starts up the c/c++ runtime which is going to be important for any non trivial application as its nice to have global initializers run, and floating point and exception support available.

– Chris Becke
Mar 8 at 13:15





1




1





Also, perhaps your signature is wrong. When ive done my own entry point in the past, the application simply closed when I returned in trivial apps, and did not when I didn't - if you don't call ExitProcess then the process won't close if there are any worker threads created, and lots of things expect to create worker threads.

– Chris Becke
Mar 8 at 13:18





Also, perhaps your signature is wrong. When ive done my own entry point in the past, the application simply closed when I returned in trivial apps, and did not when I didn't - if you don't call ExitProcess then the process won't close if there are any worker threads created, and lots of things expect to create worker threads.

– Chris Becke
Mar 8 at 13:18













Yeah, get rid of the custom entry point and let the runtime do the work for you

– David Heffernan
Mar 8 at 13:19





Yeah, get rid of the custom entry point and let the runtime do the work for you

– David Heffernan
Mar 8 at 13:19




2




2





Hmm. In NT 6.0+, threads start at RtlUserThreadStart, which gets passed the image entry point and the PPEB. But first an APC calls LdrInitializeThunk to initialize the process. kernel32.dll initializes the Kernel32ThreadInitThunkFunction function pointer to BaseThreadInitThunk, which gets called from RtlUserThreadStart with the image entry point and PPEB. This in turn calls the image entry point with the PPEB. The return value is passed to RtlExitUserThread. If it's the only thread, it calls RtlExitUserProcess, which in turn calls LdrShutdownProcess and NtTerminateProcess.

– eryksun
Mar 8 at 15:01





Hmm. In NT 6.0+, threads start at RtlUserThreadStart, which gets passed the image entry point and the PPEB. But first an APC calls LdrInitializeThunk to initialize the process. kernel32.dll initializes the Kernel32ThreadInitThunkFunction function pointer to BaseThreadInitThunk, which gets called from RtlUserThreadStart with the image entry point and PPEB. This in turn calls the image entry point with the PPEB. The return value is passed to RtlExitUserThread. If it's the only thread, it calls RtlExitUserProcess, which in turn calls LdrShutdownProcess and NtTerminateProcess.

– eryksun
Mar 8 at 15:01




1




1





It should work fine. It works for me in Windows 10.

– eryksun
Mar 8 at 15:02





It should work fine. It works for me in Windows 10.

– eryksun
Mar 8 at 15:02












2 Answers
2






active

oldest

votes


















0














windows process exit or when last thread in process exit or when TerminateProcess called. because can be additional (implicitly created) threads in your process - you need call TerminateProcess (or ZwTerminateProcess) direct or indirect.



the ExitProcess internally call TerminateProcess (ok really ZwTerminateProcess), but before this do some job, for correct process shutdown. including calling all DLLs entry points with DLL_PROCESS_DETACH notification



so in general you must call ExitProcess (more correct) or TerminateProcess



in case you write entrypoint yourself, the correct signature must be



int WINAPI startMeUp(void*)


this is stdcall function which take 1 param (pointer to PEB). when you return from this api to system - just RtlExitUserThread called, which cause to thread exit or all process exit if this is last thread in process. even desite on x86 system stack pointer is incorrect after your return from startMeUp this not lead to error because just RtlExitUserThread and it never return. hard say what lead to crash in your test without view your binary file, but faster need look(debug) on your concrete system. but this is unusual - this must not be. your process must or just exit or still live (infinite or some time) in background in additional thread in process exist






share|improve this answer


















  • 1





    Note that before calling LdrShutdownProcess, RtlExitUserProcess (i.e. ExitProcess) first terminates all other threads in the process with a special NtTerminateProcess call using a NULL handle value. After the loader has shut down the process, it calls NtTerminateProcess a second time to really terminate the process.

    – eryksun
    Mar 8 at 15:59











  • @eryksun - yes, you absolute correct, simply i not describe here in details how RtlExitUserProcess work

    – RbMm
    Mar 8 at 16:05






  • 1





    It's relevant to the fact that simply returning from the image entry point isn't a deterministic way to exit the process. It works in the OP's case since there's only one thread, but RtlExitUserThread won't call RtlExitUserProcess if it's not the last thread (as determined via NtQueryInformationThread). Thus, as you said in your answer, if we want to reliably exit in general, we have to call ExitProcess from the entry point instead of returning from it.

    – eryksun
    Mar 8 at 16:13


















-2














Yes, ExitProcess is required, or you will eventually throw an exception because there is nowhere to go and you cannot stop the processor.



However, the entry is not usually user- provided, it is provided by the CRT (WinMainCRTStartup) which also initializes global variables before calling WinMain() function.



Therefore, all you need to do is to provide a WinMain.



Edit after your edit: ExitProcess might be called by some exception handler which is created after MessageBox call. You do not (and cannot) know.






share|improve this answer

























    Your Answer






    StackExchange.ifUsing("editor", function ()
    StackExchange.using("externalEditor", function ()
    StackExchange.using("snippets", function ()
    StackExchange.snippets.init();
    );
    );
    , "code-snippets");

    StackExchange.ready(function()
    var channelOptions =
    tags: "".split(" "),
    id: "1"
    ;
    initTagRenderer("".split(" "), "".split(" "), channelOptions);

    StackExchange.using("externalEditor", function()
    // Have to fire editor after snippets, if snippets enabled
    if (StackExchange.settings.snippets.snippetsEnabled)
    StackExchange.using("snippets", function()
    createEditor();
    );

    else
    createEditor();

    );

    function createEditor()
    StackExchange.prepareEditor(
    heartbeatType: 'answer',
    autoActivateHeartbeat: false,
    convertImagesToLinks: true,
    noModals: true,
    showLowRepImageUploadWarning: true,
    reputationToPostImages: 10,
    bindNavPrevention: true,
    postfix: "",
    imageUploader:
    brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
    contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
    allowUrls: true
    ,
    onDemand: true,
    discardSelector: ".discard-answer"
    ,immediatelyShowMarkdownHelp:true
    );



    );













    draft saved

    draft discarded


















    StackExchange.ready(
    function ()
    StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f55063923%2fdoes-a-windows-process-need-to-be-terminated-by-exitproces-or-terminateprocess%23new-answer', 'question_page');

    );

    Post as a guest















    Required, but never shown

























    2 Answers
    2






    active

    oldest

    votes








    2 Answers
    2






    active

    oldest

    votes









    active

    oldest

    votes






    active

    oldest

    votes









    0














    windows process exit or when last thread in process exit or when TerminateProcess called. because can be additional (implicitly created) threads in your process - you need call TerminateProcess (or ZwTerminateProcess) direct or indirect.



    the ExitProcess internally call TerminateProcess (ok really ZwTerminateProcess), but before this do some job, for correct process shutdown. including calling all DLLs entry points with DLL_PROCESS_DETACH notification



    so in general you must call ExitProcess (more correct) or TerminateProcess



    in case you write entrypoint yourself, the correct signature must be



    int WINAPI startMeUp(void*)


    this is stdcall function which take 1 param (pointer to PEB). when you return from this api to system - just RtlExitUserThread called, which cause to thread exit or all process exit if this is last thread in process. even desite on x86 system stack pointer is incorrect after your return from startMeUp this not lead to error because just RtlExitUserThread and it never return. hard say what lead to crash in your test without view your binary file, but faster need look(debug) on your concrete system. but this is unusual - this must not be. your process must or just exit or still live (infinite or some time) in background in additional thread in process exist






    share|improve this answer


















    • 1





      Note that before calling LdrShutdownProcess, RtlExitUserProcess (i.e. ExitProcess) first terminates all other threads in the process with a special NtTerminateProcess call using a NULL handle value. After the loader has shut down the process, it calls NtTerminateProcess a second time to really terminate the process.

      – eryksun
      Mar 8 at 15:59











    • @eryksun - yes, you absolute correct, simply i not describe here in details how RtlExitUserProcess work

      – RbMm
      Mar 8 at 16:05






    • 1





      It's relevant to the fact that simply returning from the image entry point isn't a deterministic way to exit the process. It works in the OP's case since there's only one thread, but RtlExitUserThread won't call RtlExitUserProcess if it's not the last thread (as determined via NtQueryInformationThread). Thus, as you said in your answer, if we want to reliably exit in general, we have to call ExitProcess from the entry point instead of returning from it.

      – eryksun
      Mar 8 at 16:13















    0














    windows process exit or when last thread in process exit or when TerminateProcess called. because can be additional (implicitly created) threads in your process - you need call TerminateProcess (or ZwTerminateProcess) direct or indirect.



    the ExitProcess internally call TerminateProcess (ok really ZwTerminateProcess), but before this do some job, for correct process shutdown. including calling all DLLs entry points with DLL_PROCESS_DETACH notification



    so in general you must call ExitProcess (more correct) or TerminateProcess



    in case you write entrypoint yourself, the correct signature must be



    int WINAPI startMeUp(void*)


    this is stdcall function which take 1 param (pointer to PEB). when you return from this api to system - just RtlExitUserThread called, which cause to thread exit or all process exit if this is last thread in process. even desite on x86 system stack pointer is incorrect after your return from startMeUp this not lead to error because just RtlExitUserThread and it never return. hard say what lead to crash in your test without view your binary file, but faster need look(debug) on your concrete system. but this is unusual - this must not be. your process must or just exit or still live (infinite or some time) in background in additional thread in process exist






    share|improve this answer


















    • 1





      Note that before calling LdrShutdownProcess, RtlExitUserProcess (i.e. ExitProcess) first terminates all other threads in the process with a special NtTerminateProcess call using a NULL handle value. After the loader has shut down the process, it calls NtTerminateProcess a second time to really terminate the process.

      – eryksun
      Mar 8 at 15:59











    • @eryksun - yes, you absolute correct, simply i not describe here in details how RtlExitUserProcess work

      – RbMm
      Mar 8 at 16:05






    • 1





      It's relevant to the fact that simply returning from the image entry point isn't a deterministic way to exit the process. It works in the OP's case since there's only one thread, but RtlExitUserThread won't call RtlExitUserProcess if it's not the last thread (as determined via NtQueryInformationThread). Thus, as you said in your answer, if we want to reliably exit in general, we have to call ExitProcess from the entry point instead of returning from it.

      – eryksun
      Mar 8 at 16:13













    0












    0








    0







    windows process exit or when last thread in process exit or when TerminateProcess called. because can be additional (implicitly created) threads in your process - you need call TerminateProcess (or ZwTerminateProcess) direct or indirect.



    the ExitProcess internally call TerminateProcess (ok really ZwTerminateProcess), but before this do some job, for correct process shutdown. including calling all DLLs entry points with DLL_PROCESS_DETACH notification



    so in general you must call ExitProcess (more correct) or TerminateProcess



    in case you write entrypoint yourself, the correct signature must be



    int WINAPI startMeUp(void*)


    this is stdcall function which take 1 param (pointer to PEB). when you return from this api to system - just RtlExitUserThread called, which cause to thread exit or all process exit if this is last thread in process. even desite on x86 system stack pointer is incorrect after your return from startMeUp this not lead to error because just RtlExitUserThread and it never return. hard say what lead to crash in your test without view your binary file, but faster need look(debug) on your concrete system. but this is unusual - this must not be. your process must or just exit or still live (infinite or some time) in background in additional thread in process exist






    share|improve this answer













    windows process exit or when last thread in process exit or when TerminateProcess called. because can be additional (implicitly created) threads in your process - you need call TerminateProcess (or ZwTerminateProcess) direct or indirect.



    the ExitProcess internally call TerminateProcess (ok really ZwTerminateProcess), but before this do some job, for correct process shutdown. including calling all DLLs entry points with DLL_PROCESS_DETACH notification



    so in general you must call ExitProcess (more correct) or TerminateProcess



    in case you write entrypoint yourself, the correct signature must be



    int WINAPI startMeUp(void*)


    this is stdcall function which take 1 param (pointer to PEB). when you return from this api to system - just RtlExitUserThread called, which cause to thread exit or all process exit if this is last thread in process. even desite on x86 system stack pointer is incorrect after your return from startMeUp this not lead to error because just RtlExitUserThread and it never return. hard say what lead to crash in your test without view your binary file, but faster need look(debug) on your concrete system. but this is unusual - this must not be. your process must or just exit or still live (infinite or some time) in background in additional thread in process exist







    share|improve this answer












    share|improve this answer



    share|improve this answer










    answered Mar 8 at 15:41









    RbMmRbMm

    18.4k11327




    18.4k11327







    • 1





      Note that before calling LdrShutdownProcess, RtlExitUserProcess (i.e. ExitProcess) first terminates all other threads in the process with a special NtTerminateProcess call using a NULL handle value. After the loader has shut down the process, it calls NtTerminateProcess a second time to really terminate the process.

      – eryksun
      Mar 8 at 15:59











    • @eryksun - yes, you absolute correct, simply i not describe here in details how RtlExitUserProcess work

      – RbMm
      Mar 8 at 16:05






    • 1





      It's relevant to the fact that simply returning from the image entry point isn't a deterministic way to exit the process. It works in the OP's case since there's only one thread, but RtlExitUserThread won't call RtlExitUserProcess if it's not the last thread (as determined via NtQueryInformationThread). Thus, as you said in your answer, if we want to reliably exit in general, we have to call ExitProcess from the entry point instead of returning from it.

      – eryksun
      Mar 8 at 16:13












    • 1





      Note that before calling LdrShutdownProcess, RtlExitUserProcess (i.e. ExitProcess) first terminates all other threads in the process with a special NtTerminateProcess call using a NULL handle value. After the loader has shut down the process, it calls NtTerminateProcess a second time to really terminate the process.

      – eryksun
      Mar 8 at 15:59











    • @eryksun - yes, you absolute correct, simply i not describe here in details how RtlExitUserProcess work

      – RbMm
      Mar 8 at 16:05






    • 1





      It's relevant to the fact that simply returning from the image entry point isn't a deterministic way to exit the process. It works in the OP's case since there's only one thread, but RtlExitUserThread won't call RtlExitUserProcess if it's not the last thread (as determined via NtQueryInformationThread). Thus, as you said in your answer, if we want to reliably exit in general, we have to call ExitProcess from the entry point instead of returning from it.

      – eryksun
      Mar 8 at 16:13







    1




    1





    Note that before calling LdrShutdownProcess, RtlExitUserProcess (i.e. ExitProcess) first terminates all other threads in the process with a special NtTerminateProcess call using a NULL handle value. After the loader has shut down the process, it calls NtTerminateProcess a second time to really terminate the process.

    – eryksun
    Mar 8 at 15:59





    Note that before calling LdrShutdownProcess, RtlExitUserProcess (i.e. ExitProcess) first terminates all other threads in the process with a special NtTerminateProcess call using a NULL handle value. After the loader has shut down the process, it calls NtTerminateProcess a second time to really terminate the process.

    – eryksun
    Mar 8 at 15:59













    @eryksun - yes, you absolute correct, simply i not describe here in details how RtlExitUserProcess work

    – RbMm
    Mar 8 at 16:05





    @eryksun - yes, you absolute correct, simply i not describe here in details how RtlExitUserProcess work

    – RbMm
    Mar 8 at 16:05




    1




    1





    It's relevant to the fact that simply returning from the image entry point isn't a deterministic way to exit the process. It works in the OP's case since there's only one thread, but RtlExitUserThread won't call RtlExitUserProcess if it's not the last thread (as determined via NtQueryInformationThread). Thus, as you said in your answer, if we want to reliably exit in general, we have to call ExitProcess from the entry point instead of returning from it.

    – eryksun
    Mar 8 at 16:13





    It's relevant to the fact that simply returning from the image entry point isn't a deterministic way to exit the process. It works in the OP's case since there's only one thread, but RtlExitUserThread won't call RtlExitUserProcess if it's not the last thread (as determined via NtQueryInformationThread). Thus, as you said in your answer, if we want to reliably exit in general, we have to call ExitProcess from the entry point instead of returning from it.

    – eryksun
    Mar 8 at 16:13













    -2














    Yes, ExitProcess is required, or you will eventually throw an exception because there is nowhere to go and you cannot stop the processor.



    However, the entry is not usually user- provided, it is provided by the CRT (WinMainCRTStartup) which also initializes global variables before calling WinMain() function.



    Therefore, all you need to do is to provide a WinMain.



    Edit after your edit: ExitProcess might be called by some exception handler which is created after MessageBox call. You do not (and cannot) know.






    share|improve this answer





























      -2














      Yes, ExitProcess is required, or you will eventually throw an exception because there is nowhere to go and you cannot stop the processor.



      However, the entry is not usually user- provided, it is provided by the CRT (WinMainCRTStartup) which also initializes global variables before calling WinMain() function.



      Therefore, all you need to do is to provide a WinMain.



      Edit after your edit: ExitProcess might be called by some exception handler which is created after MessageBox call. You do not (and cannot) know.






      share|improve this answer



























        -2












        -2








        -2







        Yes, ExitProcess is required, or you will eventually throw an exception because there is nowhere to go and you cannot stop the processor.



        However, the entry is not usually user- provided, it is provided by the CRT (WinMainCRTStartup) which also initializes global variables before calling WinMain() function.



        Therefore, all you need to do is to provide a WinMain.



        Edit after your edit: ExitProcess might be called by some exception handler which is created after MessageBox call. You do not (and cannot) know.






        share|improve this answer















        Yes, ExitProcess is required, or you will eventually throw an exception because there is nowhere to go and you cannot stop the processor.



        However, the entry is not usually user- provided, it is provided by the CRT (WinMainCRTStartup) which also initializes global variables before calling WinMain() function.



        Therefore, all you need to do is to provide a WinMain.



        Edit after your edit: ExitProcess might be called by some exception handler which is created after MessageBox call. You do not (and cannot) know.







        share|improve this answer














        share|improve this answer



        share|improve this answer








        edited Mar 8 at 13:34

























        answered Mar 8 at 13:20









        Michael ChourdakisMichael Chourdakis

        1,58911836




        1,58911836



























            draft saved

            draft discarded
















































            Thanks for contributing an answer to Stack Overflow!


            • Please be sure to answer the question. Provide details and share your research!

            But avoid


            • Asking for help, clarification, or responding to other answers.

            • Making statements based on opinion; back them up with references or personal experience.

            To learn more, see our tips on writing great answers.




            draft saved


            draft discarded














            StackExchange.ready(
            function ()
            StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f55063923%2fdoes-a-windows-process-need-to-be-terminated-by-exitproces-or-terminateprocess%23new-answer', 'question_page');

            );

            Post as a guest















            Required, but never shown





















































            Required, but never shown














            Required, but never shown












            Required, but never shown







            Required, but never shown

































            Required, but never shown














            Required, but never shown












            Required, but never shown







            Required, but never shown







            Popular posts from this blog

            Identity Server 4 is not redirecting to Angular app after login2019 Community Moderator ElectionIdentity Server 4 and dockerIdentityserver implicit flow unauthorized_clientIdentityServer Hybrid Flow - Access Token is null after user successful loginIdentity Server to MVC client : Page Redirect After loginLogin with Steam OpenId(oidc-client-js)Identity Server 4+.NET Core 2.0 + IdentityIdentityServer4 post-login redirect not working in Edge browserCall to IdentityServer4 generates System.NullReferenceException: Object reference not set to an instance of an objectIdentityServer4 without HTTPS not workingHow to get Authorization code from identity server without login form

            2005 Ahvaz unrest Contents Background Causes Casualties Aftermath See also References Navigation menue"At Least 10 Are Killed by Bombs in Iran""Iran"Archived"Arab-Iranians in Iran to make April 15 'Day of Fury'"State of Mind, State of Order: Reactions to Ethnic Unrest in the Islamic Republic of Iran.10.1111/j.1754-9469.2008.00028.x"Iran hangs Arab separatists"Iran Overview from ArchivedConstitution of the Islamic Republic of Iran"Tehran puzzled by forged 'riots' letter""Iran and its minorities: Down in the second class""Iran: Handling Of Ahvaz Unrest Could End With Televised Confessions""Bombings Rock Iran Ahead of Election""Five die in Iran ethnic clashes""Iran: Need for restraint as anniversary of unrest in Khuzestan approaches"Archived"Iranian Sunni protesters killed in clashes with security forces"Archived

            Can't initialize raids on a new ASUS Prime B360M-A motherboard2019 Community Moderator ElectionSimilar to RAID config yet more like mirroring solution?Can't get motherboard serial numberWhy does the BIOS entry point start with a WBINVD instruction?UEFI performance Asus Maximus V Extreme