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'
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
|
show 5 more comments
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
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 atRtlUserThreadStart
, which gets passed the image entry point and the PPEB. But first an APC callsLdrInitializeThunk
to initialize the process. kernel32.dll initializes theKernel32ThreadInitThunkFunction
function pointer toBaseThreadInitThunk
, which gets called fromRtlUserThreadStart
with the image entry point and PPEB. This in turn calls the image entry point with the PPEB. The return value is passed toRtlExitUserThread
. If it's the only thread, it callsRtlExitUserProcess
, which in turn callsLdrShutdownProcess
andNtTerminateProcess
.
– eryksun
Mar 8 at 15:01
1
It should work fine. It works for me in Windows 10.
– eryksun
Mar 8 at 15:02
|
show 5 more comments
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
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
windows winapi portable-executable entry-point
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 atRtlUserThreadStart
, which gets passed the image entry point and the PPEB. But first an APC callsLdrInitializeThunk
to initialize the process. kernel32.dll initializes theKernel32ThreadInitThunkFunction
function pointer toBaseThreadInitThunk
, which gets called fromRtlUserThreadStart
with the image entry point and PPEB. This in turn calls the image entry point with the PPEB. The return value is passed toRtlExitUserThread
. If it's the only thread, it callsRtlExitUserProcess
, which in turn callsLdrShutdownProcess
andNtTerminateProcess
.
– eryksun
Mar 8 at 15:01
1
It should work fine. It works for me in Windows 10.
– eryksun
Mar 8 at 15:02
|
show 5 more comments
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 atRtlUserThreadStart
, which gets passed the image entry point and the PPEB. But first an APC callsLdrInitializeThunk
to initialize the process. kernel32.dll initializes theKernel32ThreadInitThunkFunction
function pointer toBaseThreadInitThunk
, which gets called fromRtlUserThreadStart
with the image entry point and PPEB. This in turn calls the image entry point with the PPEB. The return value is passed toRtlExitUserThread
. If it's the only thread, it callsRtlExitUserProcess
, which in turn callsLdrShutdownProcess
andNtTerminateProcess
.
– 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
|
show 5 more comments
2 Answers
2
active
oldest
votes
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
1
Note that before callingLdrShutdownProcess
,RtlExitUserProcess
(i.e.ExitProcess
) first terminates all other threads in the process with a specialNtTerminateProcess
call using aNULL
handle value. After the loader has shut down the process, it callsNtTerminateProcess
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 howRtlExitUserProcess
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, butRtlExitUserThread
won't callRtlExitUserProcess
if it's not the last thread (as determined viaNtQueryInformationThread
). Thus, as you said in your answer, if we want to reliably exit in general, we have to callExitProcess
from the entry point instead of returning from it.
– eryksun
Mar 8 at 16:13
add a comment |
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.
add a comment |
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
);
);
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
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
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
1
Note that before callingLdrShutdownProcess
,RtlExitUserProcess
(i.e.ExitProcess
) first terminates all other threads in the process with a specialNtTerminateProcess
call using aNULL
handle value. After the loader has shut down the process, it callsNtTerminateProcess
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 howRtlExitUserProcess
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, butRtlExitUserThread
won't callRtlExitUserProcess
if it's not the last thread (as determined viaNtQueryInformationThread
). Thus, as you said in your answer, if we want to reliably exit in general, we have to callExitProcess
from the entry point instead of returning from it.
– eryksun
Mar 8 at 16:13
add a comment |
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
1
Note that before callingLdrShutdownProcess
,RtlExitUserProcess
(i.e.ExitProcess
) first terminates all other threads in the process with a specialNtTerminateProcess
call using aNULL
handle value. After the loader has shut down the process, it callsNtTerminateProcess
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 howRtlExitUserProcess
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, butRtlExitUserThread
won't callRtlExitUserProcess
if it's not the last thread (as determined viaNtQueryInformationThread
). Thus, as you said in your answer, if we want to reliably exit in general, we have to callExitProcess
from the entry point instead of returning from it.
– eryksun
Mar 8 at 16:13
add a comment |
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
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
answered Mar 8 at 15:41
RbMmRbMm
18.4k11327
18.4k11327
1
Note that before callingLdrShutdownProcess
,RtlExitUserProcess
(i.e.ExitProcess
) first terminates all other threads in the process with a specialNtTerminateProcess
call using aNULL
handle value. After the loader has shut down the process, it callsNtTerminateProcess
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 howRtlExitUserProcess
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, butRtlExitUserThread
won't callRtlExitUserProcess
if it's not the last thread (as determined viaNtQueryInformationThread
). Thus, as you said in your answer, if we want to reliably exit in general, we have to callExitProcess
from the entry point instead of returning from it.
– eryksun
Mar 8 at 16:13
add a comment |
1
Note that before callingLdrShutdownProcess
,RtlExitUserProcess
(i.e.ExitProcess
) first terminates all other threads in the process with a specialNtTerminateProcess
call using aNULL
handle value. After the loader has shut down the process, it callsNtTerminateProcess
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 howRtlExitUserProcess
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, butRtlExitUserThread
won't callRtlExitUserProcess
if it's not the last thread (as determined viaNtQueryInformationThread
). Thus, as you said in your answer, if we want to reliably exit in general, we have to callExitProcess
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
add a comment |
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.
add a comment |
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.
add a comment |
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.
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.
edited Mar 8 at 13:34
answered Mar 8 at 13:20
Michael ChourdakisMichael Chourdakis
1,58911836
1,58911836
add a comment |
add a comment |
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.
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
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
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
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
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 callsLdrInitializeThunk
to initialize the process. kernel32.dll initializes theKernel32ThreadInitThunkFunction
function pointer toBaseThreadInitThunk
, which gets called fromRtlUserThreadStart
with the image entry point and PPEB. This in turn calls the image entry point with the PPEB. The return value is passed toRtlExitUserThread
. If it's the only thread, it callsRtlExitUserProcess
, which in turn callsLdrShutdownProcess
andNtTerminateProcess
.– eryksun
Mar 8 at 15:01
1
It should work fine. It works for me in Windows 10.
– eryksun
Mar 8 at 15:02