I have a function with the prototype
DWORD WINAPI blah(LPVOID arg);
Which was meant to be used with CreateThread for a threaded app.
I call it with CreateThread with no problem. But then somewhere else in the code, I call it normally, just by blah(NULL). When it gets to this part, it crashes. Is this because the WINAPI part makes it __stdcall and you can't just call __stdcall functions like that?
It is not because of __stdcall. Start your program in the debugger and check which line of the code gives you a crash.
The only problem would be if blah() specifically calls TerminateThread(self) to end, instead of just returning off the bottom. The CreateThread call sets up the return address such that when blah() returns, it calls TerminateThread.
If blah() doesn't have any code like that, then an examination of the code is needed to see if it somehow does something thread specific which makes it fail. Offhand, I can't think of anything else (besides TerminateThread()) which might cause code written to be a thread which would prevent it from being called directly.
Related
I used exit(EXIT_FAILURE) in a precise function which is not the main one, but after its execution nothing is executed in the main function.
I really wanna know why ?
Thanks a lot in advance.
In order to understand how exit works it helps to understand how program termination upon returning from main works.
When the program returns from main it returns to a piece of helper code in the C or C++ runtime. That piece performs some cleanup and then calls the _exit system call with the return value of main. The kernel will stop execution of the process at that point.
The exit function has similar behavior, it performs the same cleanup as the helper code from the C and C++ runtime does when returned from main, then calls the _exit system call. It's this last call to the _exit system call that prevents execution of anything else (in main or otherwise) after calling of exit.
While working on a thread (fiber) scheduling class, I found myself writing a function that never returns:
// New thread, called on an empty stack
// (implementation details, exception handling etc omitted)
[[noreturn]] void scheduler::thread() noexcept
{
current_task->state = running;
current_task->run();
current_task->state = finished;
while (true) yield();
// can't return, since the stack contains no return address.
}
This function is never directly called (by thread();). It is "called" only by a jmp from assembly code, right after switching to a new context, so there is no way for it to "return" anywhere. The call to yield(), at the end, checks for state == finished and removes this thread from the thread queue.
Would this be a valid use of the [[noreturn]] attribute? And if so, would it help in any way?
edit: Not a duplicate. I understand what the attribute is normally used for. My question is, would it do anything in this specific case?
I'd say that it is valid but pointless.
It's valid because the function does not return. The contract cannot be broken.
It's pointless because the function is never called from C++ code. So no caller can make use of the fact that the function does not return because there is no caller. And at the point of definition of the function, the compiler should not require your assistance to determine that code following the while statement is dead, including a function postlude if any.
Well, the jmp entering the function is a bit weird, but to answer your Question is
"Most likely no".
Why most likely ? Because I don't believe you understand the idea of no return OR you are stating your use case wrongfully.
1st of all the function is never entered (or so you are stating) which means that by default is not a no-return (dead code could be removed by the compiler).
But let's consider that you are actually calling the function without realizing it (via that "JMP").
The idea of a no-return function is to never reach the end of scope (or not in a normal way at least). Meaning that either the whole Program is terminated within the function OR an error is thrown (meaning that the function won't pop the stack in a normal way). std::terminate is a good example of such a function. If you call it within your function, then your function becomes no return.
In your case, you are checking if the thread is finished.
If you are in a scenario where you are murdering the thread through suicide , and this is the function which is checking for the thread completion , and you call this function from the thread itself (suicide, which I highly doubt, since the thread will become blocked by the while and never finish), and you are forcing the thread to exit abruptly (OS Specific how to do that) then yes the function is indeed a no return because the execution on the stack won't be finished.
Needless to say, if you're in the above scenario you have HUGE problems with your program.
Most likely you are calling this function from another thread, or you are exiting the thread normally, cases in which the function won't be a no-return.
I am a novice in the windows API, and recently I learned I should not use CreateThread and TerminateThread. I switched to _beginthreadex, however I am not sure how I am supposed to use _endthreadex?
For example, here is a basic function I was testing with:
// MyThreadFunction - outputs "#.) I Work" and ends
unsigned int __stdcall MyThreadFunction( void * lpParam )
{
int i = (int)lpParam;
cout << i << ".) I work! " << endl;
_endthreadex(0);
return 0;
}
Is my placement of _endthreadex correct? I have it before the return 0, which just seems odd to me? I read in the msdn pages about _endthreadex that it is called automatically when a function ends, but you should call it for better memory cleanup, and that is why I tried putting it in. It just doesn't seem right, sorry if this is a bad question. I just want to make sure I am doing everything right to the best of my abilities
You actually don't need to call _endthreadex() at all. It will be called for you automatically after your thread function returns anyway.
The answer is already given in short version, and if you fancy to know more - the return from your function will actually be used as an argument in _endthreadex call. Here is what runtime is doing when you start a thread. The thread is indeed started with a starting point somewhere in CRT, where internal _callthreadstartex is doing:
_endthreadex(MyThreadFunction(...));
That is, as soon as you return, _endthreadex will be immediately called for you and it will exit from the thread.
Can you use it explicitly? Yes you can, and your code is also good because it does not matter much whether you call it yourself or it will be called for you, provided that no leaks take place on the way (such as, in particular, not yet called destructors of local variables).
Since it will anyway be called for you, and return from function is safer in terms of freeing local resources, there is no use, advantage and sense to make an explicit call.
MSDN basically explains exactly the same right there in Remarks section.
You can call _endthread or _endthreadex explicitly to terminate a
thread; however, _endthread or _endthreadex is called automatically
when the thread returns from the routine passed as a parameter to
_beginthread or _beginthreadex. Terminating a thread with a call to endthread or _endthreadex helps ensure proper recovery of resources
allocated for the thread.
You don't have to call it, as already mentioned. Concerning your code, I think that the final return 0; will not even be called because _endthreadex() never returns. This could also cause destructors of local objects not to be called (which is what I believe the MSDN wanted to say), so using this function could even be harmful in C++. Consider using Boost.Thread, they have an exception dedicated specifically to ending a thread, which should do the right thing if you want to terminate the thread somewhere in the middle.
I used "StartServiceCtrlDispatcher" function to register a callback function (called ServiceMain) in windows, but the callback function I declared got compiled with the wrong calling convention.
The thing is that on some computers, when the application returned from the callback function, the application crashed, but on other computers the application did not crash.
Now, once I found the bug everything worked, but I just don't understand why on some computers it worked correctly without crashing ?
Thanks! :-)
This is all very Windows-specific, we're not talking standard C++ here.
Checking out the documentation of StartServiceDispatcher it has only one argument, and is declared as WINAPI which in turn means __stcall calling convention.
For freestanding functions, __stdcall is one of two main calling conventions. The other one is __cdecl. The machine code level difference is simply who restores the stack pointer: with __stdcall it is the function itself, while with __cdecl it is the calling code.
When the function actually is __stdcall but is invoked as if it was __cdecl, the situation is that there are two attempts to restore the stack pointer: one at the exit from the function, and one in the calling code. The one in the function will succeed. Depending on how the attempt in the calling code is done, it can mess things up thoroughly (e.g. if just adding the required offset, treating the stack pointer as relative), or it may have no harmful effect. But it's very likely to create a mess, since the assumption about the stack pointer value on return from the function, is incorrect.
When the function actually is __cdecl it will not itself restore the stack pointer, since that is the calling code's responsibility. And if the calling code is treating it as __stdcall then the calling code won't restore it either, since from the calling code's view the function is doing that. The result, if you don't get an early crash (because of broken assumptions), should then be that repeated calls, say in a loop, will eat stack space.
It's all very much Undefined Behavior.
And one property of Undefined Behavior is that it can do anything, including apparently working…
Cheers & hth.,
Calling conventions differ in the details, like which registers are preserved. If you happened to not store anything you still needed in those registers, then it didn't matter that they were erased when they didn't have to be. Similarly, if your calling convention differs about how it deals with return values, if you don't return anything, then it doesn't matter.
Fortunately, x64 only has one calling convention and this whole mess will be in the past.
The computers where the application crashed might have been using .NET Framework version 4.
Have a look at the following article:
http://msdn.microsoft.com/en-us/library/ee941656.aspx
It states the following under Interoperability - Platform Invoke:
"To improve performance in interoperability with unmanaged code, incorrect calling conventions in a platform invoke now cause the application to fail. In previous versions, the marshaling layer resolved these errors up the stack."
This is all related to what is current in the memory. Let's assume you have two functions like this:
void stdcall f1(...) { ... }
void cdecl f2(...) { ... }
stdcall is Windows calling convention, while cdecl is used by most compilers. The difference between them is who owns the responsibility to clear the stack after the call. In stdcall, the callee (f1, or f2) does, in cdecl, the caller does.
The stack, after all, is filled with unknown values. Therefore, when it gets cleaned up (wrongly), the next value that you access in the stack is undetermined. It could very well be an acceptable value, or it could be a very bad one. This is, in principle, how stack overflow (the bug, not the site) works.
I am just trying to understand some source code written in C++. I am a bit familiar
with C++, however, the following code sequence is absolutley new to me. A guess would be
that here I register some thread routine with the kernel, ptest->Run(). Could that be right?
static unsigned int __stdcall ThreadProc(void *lParameter)
{
CTest *ptest;
ptest= (Ctest *)lParameter;
ptest->Run();
return 0;
}
CTest::CTest(int n)
{
...
}
A bit simplified but a thread is a function, in this case ThreadProc. When the thread starts, the function is called and when the function exits the thread dies.
In this case, someone has started a thread with CreateThread, begin_thread or something else and passed in a pointer to a class called CTest as an argument. The thread then casts it back to a CTest* (as you can see the argument is delivered by the CreateThread API as a more generic void*) and calls the CTest::Run method before exiting.
Edit: Also, except for the "__stdcall" declaration, this is not very Windows specific. Threads in C and C++ works more or less like this on all OSes.
This is a function signature that would be used to define a function that is exported from a DLL or used as a callback function. In this case it is probably going to be used a the main loop of a worker thread.
the __stdcall keyword indicates that the function call is passed on the stack using the stdcall calling convention in Windows (same as used by methods exported from the Win32 API)
OOPS: this link doesn't play nice with markdown http://msdn.microsoft.com/en-us/library/zxk0tw93(VS.80).aspx
Not quite. This is your thread function:
static unsigned int __stdcall ThreadProc(void *lParameter)
It will be executed an different thread than whatever caused it. Calling code creates an object of type CTest, creates a thread that runs ThreadProc, which in turn runs ptest->Run();
ThreadProc is just a convenience wrapper to launch ptest->Run(). (Because otherwise it is kinda hard to use pointers to member functions)
What OS? Looks like a Windows sample, if so begin_thread(), or CreateThread or...several
The code you show declares a pointer to a CTest class object, converts the input parameter into one of those, then calls its run method.
The why this is done is the tricky part. Normally you wouldn't write code like this, however, the profile of ThreadProc is that of a thread's main entry point. For one of those, Windows doesn't give you any choice for the parameter profile of it, and it can't be a class member.
What you have there is fairly standard code to convert a thread entry-point callback from the Windows' required form into a class method call.
For a full discussion of this, see my (accepted) answer for the question: Passing Function pointers in C++