flat assembler
Message board for the users of flat assembler.
![]() Goto page Previous 1, 2, 3 Next |
Author |
|
baldr 12 Jan 2010, 16:06
BaseProcessStart() in Kernel32 (XP SP2) calls ExitThread(). The catch is that main thread can be not the last one (or even not one you are aware of: once upon a time I've experienced simple program gone zombie because something created thread on it's behalf, something WmipXxx, thus ret method failed miserably).
Pirata Derek, It's just details of implementation. Windows actively uses process' stack before it's initial thread starts (already noticed two committed stack pages even if you've specified one? This is NtSetInformationThread() footprints), but this behavior is not documented as a part of Win32. For example, ebp points to standard stack frame (of BaseProcessStart()), you may even fetch dword[ebp+8] — your entry point's VA. Or alter C++ exception registration record at ebp-18. Does this qualify as reliable programming practice? No. |
|||
![]() |
|
Borsuc 12 Jan 2010, 18:09
MSDN wrote: Note that returning from the main function of an application results in a call to ExitProcess. |
|||
![]() |
|
baldr 12 Jan 2010, 18:48
Borsuc wrote:
_________________ "Don't belong. Never join. Think for yourself. Peace." – Victor Stone. |
|||
![]() |
|
Borsuc 12 Jan 2010, 20:04
oh I thought it was talking about the main function, not the function called "main"
![]() |
|||
![]() |
|
f0dder 13 Jan 2010, 13:59
Tomasz Grysztar wrote: There's nowhere said that the main thread is different from the other threads, and for the sake of this argument it doesn't really matter how it is created. You're talking about the MSDN documentation for the win32 function CreateThread. Keep in mind that Windows has multiple subsystem support, and nowhere is it mentioned that process creation is done using the win32 subsystem (which indeed it isn't). Tomasz Grysztar wrote: the only logical conclusion is that every thread should be ThreadProc-like, because otherwise we would have some discrimination that would have no explanation in documentation (and I would consider that a bug). ![]() There's a lot of things in Windows that are left unspecified, because it's assumed(!) that you're writing in C or higher languages. Once dropping to assembly and you start making assumptions based on observations, bad things tend to happen... people not knowing about calling convetions, depending on register contents on process startup, et cetera. Yes, it makes an awful lot of sense to have the main thread behave just as any other thread in the system, but why make that assumption when it's basically free to code defensively? Also, if you look at windows internals, you'll see that while the main thread works as basically any other thread of usermode win32 programmers, it isn't entirely equal to other threads - before reaching your process entrypoints it's being used for a fair amount of setup, including RPC to the win32 subsystem for various initialization purposes. baldr wrote: BaseProcessStart() in Kernel32 (XP SP2) calls ExitThread(). ![]() Borsuc wrote: oh I thought it was talking about the main function, not the function called "main" ![]() And as baldr mentioned, additional threads being created in your code will make the "ret" method fail. There's a whole bunch of things that can end up creating additional threads in your app. Might even happen without you calling any external code, in the case of third-party tools injecting code (for whatever reason). ...also, what do you expect program exit code to be if you don't call ExitProcess? One more instance of undocumented behavior. |
|||
![]() |
|
revolution 13 Jan 2010, 14:04
f0dder wrote: And as baldr mentioned, additional threads being created in your code will make the "ret" method fail. There's a whole bunch of things that can end up creating additional threads in your app. Might even happen without you calling any external code, in the case of third-party tools injecting code (for whatever reason). [edit] On my XPSP2 box: using ret goes to ExitThread. When I have another thread running, the main thread closes and the GUI window closes but the exe is still in the process list unable to interact with the world. Caution, zombie alert! |
|||
![]() |
|
Tomasz Grysztar 13 Jan 2010, 14:35
f0dder wrote: Yes, it makes an awful lot of sense to have the main thread behave just as any other thread in the system, but why make that assumption when it's basically free to code defensively? Because I would consider it a bug if it was different from the others without being mentioned in documentation. In my opinion if there is ANY difference from the programmer's point of view between a main thread and the other threads, it should be mentioned somewhere. It's not that I advocate this style of programming - I advocate the good OS design. ![]() Last edited by Tomasz Grysztar on 13 Jan 2010, 14:57; edited 1 time in total |
|||
![]() |
|
revolution 13 Jan 2010, 14:37
Tomasz Grysztar wrote:
![]() |
|||
![]() |
|
Tomasz Grysztar 13 Jan 2010, 14:57
Sorry, I'm not sure how that happened.
![]() |
|||
![]() |
|
Borsuc 13 Jan 2010, 16:44
Tomasz Grysztar wrote: It's not that I advocate this style of programming - I advocate the good OS design. _________________ Previously known as The_Grey_Beast |
|||
![]() |
|
Tomasz Grysztar 13 Jan 2010, 17:39
Borsuc wrote:
![]() As for bugs, they are bugs - even Microsoft does listen to the bug reports. |
|||
![]() |
|
revolution 13 Jan 2010, 17:44
Okay, fine, so we have established that the 'main' thread is just another thread like all the others. Good.
But going way back to the original discussion: simply using RET from 'main' in an attempt to quit the program is WRONG. Because of the above mentioned reasons about injected DLLs (and other things) opening threads without your knowledge and thus creating ZOMBIE processes. |
|||
![]() |
|
Tomasz Grysztar 13 Jan 2010, 17:54
In complex program it may be risky, but simple program should not have any threads created without your knowledge - it is had, that would be another bug. Even when some additional task you don't know about had to be initialized as another thread upon starting your program, it should also exit when the task is finished (and in that case ExitThread is even better, since it would wait for that other task to finish, too)
So if ending main thread only makes your process a zombie, it just uncovers the bad design or loose programming, that's all. |
|||
![]() |
|
revolution 13 Jan 2010, 17:57
Going to the DOCs:
Win32 ExitProcess wrote: ExitProcess is the preferred method of ending a process. Win32 TerminateProcess wrote: Use it only in extreme circumstances. |
|||
![]() |
|
Tomasz Grysztar 13 Jan 2010, 18:01
They write similar things about ExitThread and TerminateThread pair. What's the relevance?
|
|||
![]() |
|
revolution 13 Jan 2010, 18:08
But ExitThread doesn't say that it is the preferred method of ending a process. Just that if, by chance, it happens to be the last thread then the process will also terminate, kind of as a by-product.
The situation of other threads running unexpectedly is the problem with using RET and fully expecting your process to terminate. It is a gotcha! And guess what, when a user has some other app (spyware or whatever) and your program is the only one not properly terminating (because of the RET), then your app will get blamed for causing a problem (perhaps undeservedly but blamed all the same). |
|||
![]() |
|
Tomasz Grysztar 13 Jan 2010, 18:13
It's not the problem of RET, you've got the same problem when using just ExitThread. As I said - it may uncover some problems with your program and your system, thus I would even consider it preferred just for the reason that it will sooner show some problems that otherwise might go unnoticed. That's a very good thing to do.
![]() |
|||
![]() |
|
revolution 13 Jan 2010, 18:45
But it might not be a system problem at all. It could be some authorised spyware (perhaps in a school environment to monitor the children, or a parental control or something) that is expecting your program to exit properly using the "preferred method of ending a process", i.e. ExitProcess. It would be really hard for an average person to diagnose why your program does not properly terminate and it is almost certain that the other (spyware/whatever) app is not going to get blamed for expecting your program to exit normally.
|
|||
![]() |
|
Tomasz Grysztar 13 Jan 2010, 18:52
"Preferred" is not the same as "proper". Assuming the "preferred" to be "the only one right" would also be a fault of bad programming.
|
|||
![]() |
|
Goto page Previous 1, 2, 3 Next < Last Thread | Next Thread > |
Forum Rules:
|
Copyright © 1999-2025, Tomasz Grysztar. Also on GitHub, YouTube.
Website powered by rwasa.