Thread in C++ DLL called by EPrime causes exception - c++

I have a DLL written in C++, which exports a function that calls a thread. If the function returns before the thread terminates (which is the standard usecase), EStudio crashes. My platform is Windows 10, 64 bits, but the DLL is compiled in x86 mode.
The function is thus declared in EPrime:
Declare Function moop stdcall Lib "meep.dll" () As Long
Dim oPtr As Long
oPtr = moop()
and the DLL code looks like this:
void* event_loop_func(void* eye_tracker)
{
Sleep(3000);
return 0;
}
void * __stdcall moop()
{
void * hThread = CreateThread(
NULL, // default security attributes
0, // use default stack size
(LPTHREAD_START_ROUTINE)event_loop_func, // thread function name
NULL, // argument to thread function
0, // use default creation flags
NULL);
return 0;
}
Any advice on how to run a thread from the DLL without crashing EStudio?

Related

Self-deleting program works fine in C but error in C++ project

I need a way to self-delete the executable within my Win32 C++ project, and I found a program that does it in C:
selfdel.c:
// http://www.catch22.net/tuts/win32/self-deleting-executables
// selfdel.c
//
// Self deleting executable for Win9x/WinNT (works for all versions of windows)
//
// J Brown 1/10/2003
//
// This source file must be compiled with /GZ turned OFF
// (basically, disable run-time stack checks)
//
// Under debug build this is always on (MSVC6)
//
//
/**
* The way this works is:
* Firstly a child process is created in a suspended state (any process will do - i.e. explorer.exe).
* Some code is then injected into the address-space of the child process.
* The injected code waits for the parent-process to exit.
* The parent-process is then deleted.
* The injected code then calls ExitProcess, which terminates the child process.
*/
#include <windows.h>
#include <tchar.h>
#pragma pack(push, 1)
#define CODESIZE 0x200
//
// Structure to inject into remote process. Contains
// function pointers and code to execute.
//
typedef struct _SELFDEL
{
struct _SELFDEL *Arg0; // pointer to self
BYTE opCodes[CODESIZE]; // code
HANDLE hParent; // parent process handle
FARPROC fnWaitForSingleObject;
FARPROC fnCloseHandle;
FARPROC fnDeleteFile;
FARPROC fnSleep;
FARPROC fnExitProcess;
FARPROC fnRemoveDirectory;
FARPROC fnGetLastError;
BOOL fRemDir;
TCHAR szFileName[MAX_PATH]; // file to delete
} SELFDEL;
#pragma pack(pop)
#ifdef _DEBUG
#define FUNC_ADDR(func) (PVOID)(*(DWORD *)((BYTE *)func + 1) + (DWORD)((BYTE *)func + 5))
#else
#define FUNC_ADDR(func) func
#endif
//
// Routine to execute in remote process.
//
static void remote_thread(SELFDEL *remote)
{
// wait for parent process to terminate
remote->fnWaitForSingleObject(remote->hParent, INFINITE);
remote->fnCloseHandle(remote->hParent);
// try to delete the executable file
while(!remote->fnDeleteFile(remote->szFileName))
{
// failed - try again in one second's time
remote->fnSleep(1000);
}
// finished! exit so that we don't execute garbage code
remote->fnExitProcess(0);
}
//
// Delete currently running executable and exit
//
BOOL SelfDelete(BOOL fRemoveDirectory)
{
STARTUPINFO si = { sizeof(si) };
PROCESS_INFORMATION pi;
CONTEXT context;
DWORD oldProt;
SELFDEL local;
DWORD entrypoint;
TCHAR szExe[MAX_PATH] = _T("explorer.exe");
//
// Create executable suspended
//
if(CreateProcess(0, szExe, 0, 0, 0, CREATE_SUSPENDED|IDLE_PRIORITY_CLASS, 0, 0, &si, &pi))
{
local.fnWaitForSingleObject = (FARPROC)WaitForSingleObject;
local.fnCloseHandle = (FARPROC)CloseHandle;
local.fnDeleteFile = (FARPROC)DeleteFile;
local.fnSleep = (FARPROC)Sleep;
local.fnExitProcess = (FARPROC)ExitProcess;
local.fnRemoveDirectory = (FARPROC)RemoveDirectory;
local.fnGetLastError = (FARPROC)GetLastError;
local.fRemDir = fRemoveDirectory;
// Give remote process a copy of our own process handle
DuplicateHandle(GetCurrentProcess(), GetCurrentProcess(),
pi.hProcess, &local.hParent, 0, FALSE, 0);
GetModuleFileName(0, local.szFileName, MAX_PATH);
// copy in binary code
memcpy(local.opCodes, FUNC_ADDR(remote_thread), CODESIZE);
//
// Allocate some space on process's stack and place
// our SELFDEL structure there. Then set the instruction pointer
// to this location and let the process resume
//
context.ContextFlags = CONTEXT_INTEGER|CONTEXT_CONTROL;
GetThreadContext(pi.hThread, &context);
// Allocate space on stack (aligned to cache-line boundary)
entrypoint = (context.Esp - sizeof(SELFDEL)) & ~0x1F;
//
// Place a pointer to the structure at the bottom-of-stack
// this pointer is located in such a way that it becomes
// the remote_thread's first argument!!
//
local.Arg0 = (SELFDEL *)entrypoint;
context.Esp = entrypoint - 4; // create dummy return address
context.Eip = entrypoint + 4; // offset of opCodes within structure
// copy in our code+data at the exe's entry-point
VirtualProtectEx(pi.hProcess, (PVOID)entrypoint, sizeof(local), PAGE_EXECUTE_READWRITE, &oldProt);
WriteProcessMemory(pi.hProcess, (PVOID)entrypoint, &local, sizeof(local), 0);
FlushInstructionCache(pi.hProcess, (PVOID)entrypoint, sizeof(local));
SetThreadContext(pi.hThread, &context);
// Let the process continue
ResumeThread(pi.hThread);
CloseHandle(pi.hThread);
CloseHandle(pi.hProcess);
return TRUE;
}
return FALSE;
}
Compiling this alone using the Visual Studio Developer Command Prompt and cl creates an executable and it runs just as expected. Putting this in my C++ project creates an error within remote_thread:
I can't figure out this error. Building in x64 and x86 causes the same error. I have tried putting it in there just by itself, adding extern "C" {} as a wrapper, bringing the file in as a .c file and then linking with a header file, but then the header method broke all the other windows header files (probably because the compiler couldn't differentiate between c headers and cpp headers?) but that's besides the point, what am I missing here?
FARPROC does not work the same way in C++ as it does in C. This is actually described in the CallWindowProc documentation:
...
The FARPROC type is declared as follows:
int (FAR WINAPI * FARPROC) ()
In C, the FARPROC declaration indicates a callback function that has an unspecified parameter list. In C++, however, the empty parameter list in the declaration indicates that a function has no parameters. This subtle distinction can break careless code.
...
So, you will have to use proper function-pointer signatures instead, eg:
typedef struct _SELFDEL
{
...
DWORD (WINAPI *fnWaitForSingleObject)(HANDLE, DWORD);
BOOL (WINAPI *fnCloseHandle)(HANDLE);
BOOL (WINAPI *fnDeleteFile)(LPCTSTR);
void (WINAPI *fnSleep)(DWORD);
void (WINAPI *fnExitProcess)(UINT);
BOOL (WINAPI *fnRemoveDirectory)(LPCTSTR);
DWORD (WINAPI *fnGetLastError)();
...
} SELFDEL;
SELFDEL local;
...
local.fnWaitForSingleObject = &WaitForSingleObject;
local.fnCloseHandle = &CloseHandle;
local.fnDeleteFile = &DeleteFile;
local.fnSleep = &Sleep;
local.fnExitProcess = &ExitProcess;
local.fnRemoveDirectory = &RemoveDirectory;
local.fnGetLastError = &GetLastError;
...
As covered in the comments, the problem here is the code is not valid when compiled as C++ because the function prototypes are incorrect. You can force the compiler to compile the code as C by giving the file a .c suffix.
Your calling C++ code must then be informed the SelfDelete is a C function rather than a C++ function. This is because C++ functions have mangled names to allow for things like overloading. You do this by declaring the function as extern "C" in your C++ code:
extern "C" BOOL SelfDelete(BOOL fRemoveDirectory);
Just put this in your calling C++ code, somewhere before you actually call the function. Without this, your program will not link, because the C code and C++ code will disagree on what the function is actually called behind the scenes.

How address of a function will pass to the std::thread

I was debugging a multithreaded application that is using std::thread to run a function. I reach to the following code when debugging.
extern "C" uintptr_t __cdecl _beginthreadex(
void* const security_descriptor,
unsigned int const stack_size,
_beginthreadex_proc_type const procedure,
void* const context,
unsigned int const creation_flags,
unsigned int* const thread_id_result
)
{
_VALIDATE_RETURN(procedure != nullptr, EINVAL, 0);
unique_thread_parameter parameter(create_thread_parameter(procedure, context));
if (!parameter)
{
return 0;
}
DWORD thread_id;
HANDLE const thread_handle = CreateThread(
reinterpret_cast<LPSECURITY_ATTRIBUTES>(security_descriptor),
stack_size,
thread_start<_beginthreadex_proc_type, true>,
parameter.get(),
creation_flags,
&thread_id);
if (!thread_handle)
{
__acrt_errno_map_os_error(GetLastError());
return 0;
}
if (thread_id_result)
{
*thread_id_result = thread_id;
}
// If we successfully created the thread, the thread now owns its parameter:
parameter.detach();
return reinterpret_cast<uintptr_t>(thread_handle);
}
But I couldn't understand how address of the function passed to the CreateThread API. Why is it using thread_start<_beginthreadex_proc_type, true>, and how the address of a function will calculate by this statement in order to run by threads?
The code shown (_beginthreadex function) is part of VC++ CRT (can be found in, e.g.
C:\Program Files (x86)\Windows Kits\10\Source\10.0.17763.0\ucrt\startup\thread.cpp).
An instance of unique_thread_parameter is a structure that holds the thread procedure pointer, the context argument, and thread and module HANDLEs:
// corecrt_internal.h
typedef struct __acrt_thread_parameter
{
// The thread procedure and context argument
void* _procedure;
void* _context;
// The handle for the newly created thread. This is initialized only from
// _beginthread (not _beginthreadex). When a thread created via _beginthread
// exits, it frees this handle.
HANDLE _thread_handle;
// The handle for the module in which the user's thread procedure is defined.
// This may be null if the handle could not be obtained. This handle enables
// us to bump the reference count of the user's module, to ensure that the
// module will not be unloaded while the thread is executing. When the thread
// exits, it frees this handle.
HMODULE _module_handle;
// This flag is true if RoInitialized was called on the thread to initialize
// it into the MTA.
bool _initialized_apartment;
} __acrt_thread_parameter;
// thread.cpp
using unique_thread_parameter = __crt_unique_heap_ptr<
__acrt_thread_parameter,
thread_parameter_free_policy>;
create_thread_parameter creates such an instance:
static __acrt_thread_parameter* __cdecl create_thread_parameter(
void* const procedure,
void* const context
) throw()
{
unique_thread_parameter parameter(_calloc_crt_t(__acrt_thread_parameter, 1).detach());
if (!parameter)
{
return nullptr;
}
parameter.get()->_procedure = procedure;
parameter.get()->_context = context;
// Attempt to bump the reference count of the module in which the user's
// thread procedure is defined, to ensure that the module will stay loaded
// as long as the thread is executing. We will release this HMDOULE when
// the thread procedure returns or _endthreadex is called.
GetModuleHandleExW(
GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS,
reinterpret_cast<LPCWSTR>(procedure),
&parameter.get()->_module_handle);
return parameter.detach();
}
thread_start is a template function that invokes the thread procedure:
template <typename ThreadProcedure>
static unsigned long WINAPI thread_start(void* const parameter) throw()
{
if (!parameter)
{
ExitThread(GetLastError());
}
__acrt_thread_parameter* const context = static_cast<__acrt_thread_parameter*>(parameter);
__acrt_getptd()->_beginthread_context = context;
if (__acrt_get_begin_thread_init_policy() == begin_thread_init_policy_ro_initialize)
{
context->_initialized_apartment = __acrt_RoInitialize(RO_INIT_MULTITHREADED) == S_OK;
}
__try
{
ThreadProcedure const procedure = reinterpret_cast<ThreadProcedure>(context->_procedure);
_endthreadex(invoke_thread_procedure(procedure, context->_context));
}
__except (_seh_filter_exe(GetExceptionCode(), GetExceptionInformation()))
{
// Execution should never reach here:
_exit(GetExceptionCode());
}
// This return statement will never be reached. All execution paths result
// in the thread or process exiting.
return 0;
}
It essentially calls invoke_thread_procedure, which just invokes procedure, passing in context:
static __forceinline unsigned int invoke_thread_procedure(
_beginthreadex_proc_type const procedure,
void* const context
) throw()
{
return procedure(context);
}
The code around the calls does some bookkeeping to keep the CRT consistent, for example it
automatically cleans up the thread upon exit (_endthreadex).

Create thread within DLL

I'm working on a .NET profiler which I'm writing in c++ (a dll that uses ATL). I want to create a thread that writes into a file every 30 seconds. I want the thread function to be a method of one of my classes
DWORD WINAPI CProfiler::MyThreadFunction( void* pContext )
{
//Instructions that manipulate attributes from my class;
}
when I try to start the thread
HANDLE l_handle = CreateThread( NULL, 0, MyThreadFunction, NULL, 0L, NULL );
I got this error :
argument of type "DWORD (__stdcall CProfiler::*)(void *pContext)"
is incompatible with parameter of type "LPTHREAD_START_ROUTINE"
How to properly create a thread within a DLL?
Any help would be apreciated.
You cannot pass a pointer to a member function as if it were a regular function pointer. You need to declare your member function as static. If you need to call the member function on an object you can use a proxy function.
struct Foo
{
virtual int Function();
static DWORD WINAPI MyThreadFunction( void* pContext )
{
Foo *foo = static_cast<Foo*>(pContext);
return foo->Function();
}
};
Foo *foo = new Foo();
// call Foo::MyThreadFunction to start the thread
// Pass `foo` as the startup parameter of the thread function
CreateThread( NULL, 0, Foo::MyThreadFunction, foo, 0L, NULL );

Define thread in C++

How do I start a thread using _beginthreadex(), making it execute void myFunction(wchar_t *param);? I try to use this:
_beginthread(NULL, 0, myFunction, L"someParam", 0, &ThreadID);
but there is compilation error:
error C2664: 'beginthreadex' : cannot convert parameter 3 from 'void (_cdecl *)(wchar_t *)' to 'unsigned int (__stdcall *)(void *)'.
How I can resolve this error? I seem able to do _beginthread((void(*)(void*))myFunction, 0 , (void *)L"someParam");. But for _beginthreadex() these casts don't seem to work. What do
I need to do?
This code doesn't output anything. What's wrong?
unsigned int __stdcall myFunction( void *someParam )
{
printf("Hello world!");
return 0;
}
int _tmain(int argc, _TCHAR* argv[])
{
_beginthreadex(NULL, 0, myFunction, L"param", 0, NULL);
return 0;
}
_beginthreadex requires a function that uses the __stdcall calling convention, not the __cdecl calling convention, which is the default. To fix it, declare your thread procedure with the __stdcall calling convention:
unsigned int __stdcall myFunction(void *arg)
{
...
}
Do NOT cast the function pointer you're passing into _beginthread or _beginthreadex: a function pointer cast is a bug waiting to happen.
Function prototype requirements for each Microsoft CRT thread launch functions are:
_beginthread: void __cdecl procname(void * arg);
_beginthreadex: unsigned int __stdcall procname(void *arg);
You should also be aware of the differences between the two.
_beginthread: allocates a new thread and invokes the thread procedure passed as the argument. Using this API the thread-creation parameters are somewhat limited. The return value of this function is a uintptr_t, but is actually a Windows thread handle of type HANDLE. It must be cast to a HANDLE variable to be used in such functions as WaitForSingleObject, etc. When the thread procedure finishes through normal function-exit the thread handle is automatically closed for you by the runtime. This is important. Although this function returns a thread handle just like _beginthreadex, it is conceivable for the thread to start and finish before you can do anything with the handle (such as a wait, suspend, etc.). Once the thread procedure finishes the RT will close the handle, and therefore your local variable holding the initial returned handle is now invalid.
_beginthreadex: allocates a new thread and invokes the thread procedure passed as the argument. This version allows significantly more control over how the thread is created, including the stack size, initial suspended state, etc. The return value of this function is a uintptr_t, but is actually a Windows thread handle of type HANDLE. It must be cast to a HANDLE variable to be used in such functions as WaitForSingleObject, etc. When the thread procedure finishes through normal function-exit the thread handle is NOT automatically closed for you by the runtime. You are responsible for closing the thread handle returned by this function, and should do so as soon as it is no longer needed.
Which to use: Use _beginthread if you have no need for the thread handle to be used in Wait functions and such, and have no special thread-creation needs (like creating a thread with an initially-suspended state). Use _beginthreadex when you need a wait'able thread handle, finer control over the creation parameters, etc.
EDIT: Sample for the OP
#include <windows.h>
#include <tchar.h>
#include <stdio.h>
#include <process.h>
unsigned int __stdcall MyThread(void *p)
{
_tprintf(_T("%s\n"), p);
_tprintf(_T("Thread finishing!\n"));
return 0;
}
int _tmain(int argc, TCHAR *argv[])
{
HANDLE hThread = (HANDLE)_beginthreadex(NULL, 0, MyThread, _T("Hello, World!"), 0, NULL);
if (hThread != INVALID_HANDLE_VALUE)
{
WaitForSingleObject(hThread, INFINITE);
CloseHandle(hThread);
_tprintf(_T("Thread finished!\n"));
}
return 0;
}
As in the other answer above, don't forget to wait for your thread to finish before _tmain exits, or you likely will see no output.

C++: _beginthreadex, thread function name not showing in Visual Studio Threads window

I recently learnt that ::_beginthreadex() is always preferable to ::CreateThread(), so I changed all my calls that used ::CreateThread().
The only downside is that I no longer see the thread function's name in Visual Studio's Threads window making it hard to quickly identify threads. I assume this was somehow done automatically by the debugger when I used ::CreateThread(), since the parameters are exactly the same, I just changed the name of the function used.
Is there any way to keep using ::_beginthreadex() and to see the thread's name in the Threads window of Visual Studio?
This happens because _beginthreadex() calls CreateThread() with its own thread function that calls the one you specify (so the debugger uses the _threadstartex function name - the one that _beginthreadex() invokes).
You can manually set the thread name yourself using the SetThreadName() example from MSDN. What you might want to do is create your own wrapper for _beginthreadex() that maybe looks something like:
uintptr_t startthreadex(
void* security,
unsigned stacksize,
unsigned (__stdcall * threadproc) (void *),
void* args,
unsigned flags,
unsigned * pThread_id,
char* thread_name)
{
unsigned alt_thread_id;
if (!pThread_id) {
pThread_id = & alt_thread_id;
}
uintptr_t result = _beginthreadex(security, stacksize, threadproc, args, flgas, pThread_id);
if (result == 0) return result;
SetThreadName( *pThread_id, thread_name);
}
Now you can call startthreadex() instead of _beginthreadex() and pass it a thread name. A small advantage to this is that if you use the same function to run several threads, you can easily give them each unique names that reflect the parameters passed ot the thread or whatever.
If you want the thread name to automatically take be the thread proc function name as the debugger's thread name, you could make a wrapper macro that stringizes the function name parameter (all it takes is another level of indirection or to to solve any problem...).
Here's SetThreadName() (it's from http://msdn.microsoft.com/en-us/library/xcb2z8hs.aspx):
//
// Usage: SetThreadName (-1, "MainThread");
//
#include <windows.h>
const DWORD MS_VC_EXCEPTION=0x406D1388;
#pragma pack(push,8)
typedef struct tagTHREADNAME_INFO
{
DWORD dwType; // Must be 0x1000.
LPCSTR szName; // Pointer to name (in user addr space).
DWORD dwThreadID; // Thread ID (-1=caller thread).
DWORD dwFlags; // Reserved for future use, must be zero.
} THREADNAME_INFO;
#pragma pack(pop)
void SetThreadName( DWORD dwThreadID, char* threadName)
{
THREADNAME_INFO info;
info.dwType = 0x1000;
info.szName = threadName;
info.dwThreadID = dwThreadID;
info.dwFlags = 0;
__try
{
RaiseException( MS_VC_EXCEPTION, 0, sizeof(info)/sizeof(ULONG_PTR), (ULONG_PTR*)&info );
}
__except(EXCEPTION_EXECUTE_HANDLER)
{
}
}
There is no particular advantage with using _beginthreadex over CreateThread. The CRT functions would eventually call CreateThread only.
You should read:
Windows threading: _beginthread vs _beginthreadex vs CreateThread C++
http://www.codeguru.com/forum/showthread.php?t=371305
http://social.msdn.microsoft.com/forums/en-US/vclanguage/thread/c727ae29-5a7a-42b6-ad0b-f6b21c1180b2