Thread: signals on windows

  1. #1
    Registered User awsdert's Avatar
    Join Date
    Jan 2015
    Posts
    1,733

    signals on windows

    I replicated kill( pid, SIGTERM ), kill( pid, SIGSTOP ) & kill( SIGCONT ) using TerminateProcess, CreateToolhelp32Snapshot, SuspendThread & ResumeThread but struggling to find info on how to replicate kill( pid, SIGSEGV ), anyone have any ideas? And yes I know it's unlikely to have any actual use but if I'm going to replicate the kill function then I should do it properly and implement everything that it supports on linux

  2. #2
    Registered User awsdert's Avatar
    Join Date
    Jan 2015
    Posts
    1,733
    So far this is all I've been able to come up with:
    Code:
    #ifdef PAW_API_MSW
    /*BOOL CALLBACK EnumThreadWndProc( HWND hwnd, LPARAM lParam );*/
    BOOL CALLBACK term_window( HWND hwnd, LPARAM lParam )
    	{ return PostMessageA( hwnd, WM_QUIT, EXIT_FAILURE, 0 ); }
    BOOL CALLBACK segv_window( HWND hwnd, LPARAM lParam )
    	{ return PostMessageA( hwnd, WM_QUIT, ERROR_INVALID_ACCESS, 0 ); }
    RAWPAW_API pawd pawsigid( pawjd tid, PAWSIG sig )
    {
    	pawd err = 0;
    	HANDLE thread = OpenThread( THREAD_ALL_ACCESS, FALSE, tid );
    	if ( !thread )
    		return -1;
    	switch ( sig )
    	{
    	case PAWSIG_KILL: TerminateThread( thread, EXIT_SUCCESS ); break;
    	case PAWSIG_TERM:
    		err = -(EnumThreadWindows( tid, term_window, 0 ) != TRUE);
    		break;
    	case PAWSIG_STOP: SuspendThread( thread ); break;
    	case PAWSIG_CONT: ResumeThread( thread ); break;
    	default: err = -1;
    	}
    	CloseHandle( thread );
    	return err;
    }
    static pawd pawsig_threads( DWORD pid, PAWSIG sig )
    {
    	HANDLE threads = CreateToolhelp32Snapshot( TH32CS_SNAPTHREAD, pid );
    	THREADENTRY32 thread;
    	BOOL valid = FALSE;
    
    	if ( !threads )
    		return -1;
    
    	thread.dwSize = sizeof(THREADENTRY32);
    
    	for
    	(
    		valid = Thread32First(threads, &thread)
    		; valid == TRUE
    		; pawsigid( thread.th32ThreadID, sig )
    		, valid = Thread32Next(threads, &thread)
    	);
    
    	CloseHandle(threads);
    	return 0;
    }
    RAWPAW_API pawd pawsigpid( pawjd pid, PAWSIG sig )
    {
    	pawd err = 0;
    	HANDLE proc = NULL;
    	switch ( sig )
    	{
    	case PAWSIG_KILL:
    		proc = OpenProcess( PROCESS_TERMINATE, FALSE, pid );
    		if ( !proc )
    			return -1;
    		TerminateProcess( proc, EXIT_SUCCESS );
    		CloseHandle( proc );
    		break;
    	default:
    		err = pawsig_threads(pid,sig);
    	}
    	return err;
    }
    #else
    RAWPAW_API pawd pawsigid( pawjd tid, PAWSIG sig )
    	{ return pthread_kill( tid, pawsignals[sig] ); }
    RAWPAW_API pawd pawsigpid( pawjd pid, PAWSIG sig )
    	{ return kill( pid, pawsignals[sig] ); }
    #endif
    Not even sure ERROR_INVALID_ACCESS is the right code to mimic SEGV

  3. #3
    Registered User
    Join Date
    Sep 2022
    Posts
    55
    The return value for segfaults on Windows is -1073741819 (0xC0000005). You can reproduce it with this line of code
    Code:
    int main(void){ (void)(*(volatile char *)0 = 0); }

    Run the program in a cmd prompt and execute echo %errorlevel% to get the return value.

    You could pass this value to the second parameter of TerminateProcess().

  4. #4
    Registered User awsdert's Avatar
    Join Date
    Jan 2015
    Posts
    1,733
    Quote Originally Posted by aGerman View Post
    The return value for segfaults on Windows is -1073741819 (0xC0000005). You can reproduce it with this line of code
    Code:
    int main(void){ (void)(*(volatile char *)0 = 0); }

    Run the program in a cmd prompt and execute echo %errorlevel% to get the return value.

    You could pass this value to the second parameter of TerminateProcess().
    Thank you Won't use it in TerminateProcess since it's supposed to be catchable last I checked, even in linux but if I find otherwise then yeah, I'll switch at that time

  5. #5
    'Allo, 'Allo, Allo
    Join Date
    Apr 2008
    Posts
    639
    I'm pretty sure there's a difference between PostMessage(WM_QUIT) and PostQuitMessage(), in that one is likely to be ignored and one will end the message loop.
    Quote Originally Posted by https://learn.microsoft.com/en-us/windows/win32/winmsg/wm-quit
    Do not post the WM_QUIT message using the PostMessage function; use PostQuitMessage.
    Since you can't PostQuitMessage to a foreign thread, just post WM_CLOSE instead. You can't set the exit code of the thread with this, but you couldn't guarantee the app would respect the exit code you set anyway.

    Also CreateToolhelp32Snapshot returns INVALID_HANDLE_VALUE when it fails, that value is not 0.

    The return value for segfaults on Windows is -1073741819 (0xC0000005).
    STATUS_ACCESS_VIOLATION is the define.

  6. #6
    Registered User awsdert's Avatar
    Join Date
    Jan 2015
    Posts
    1,733
    Quote Originally Posted by adeyblue View Post
    I'm pretty sure there's a difference between PostMessage(WM_QUIT) and PostQuitMessage(), in that one is likely to be ignored and one will end the message loop.

    Since you can't PostQuitMessage to a foreign thread, just post WM_CLOSE instead. You can't set the exit code of the thread with this, but you couldn't guarantee the app would respect the exit code you set anyway.

    Also CreateToolhelp32Snapshot returns INVALID_HANDLE_VALUE when it fails, that value is not 0.


    STATUS_ACCESS_VIOLATION is the define.
    Right, I forgot windows was designed by idiots, sure they're smart programmers but when it comes to design they leave a LOT to be desired

    Edit: Forgot to say thanks for the info on the other stuff, been so long since I did any real windows programming that I forgot they have 1001 ways to do the same thing with only 1 being the right way

  7. #7
    Registered User
    Join Date
    May 2012
    Location
    Arizona, USA
    Posts
    948
    Quote Originally Posted by awsdert View Post
    Edit: Forgot to say thanks for the info on the other stuff, been so long since I did any real windows programming that I forgot they have 1001 ways to do the same thing with only 1 being the right way
    There seems to be many ways to skin a cat, but there's only one way that actually works (some ways will leave you skinned instead).

  8. #8
    Registered User
    Join Date
    Sep 2022
    Posts
    55
    Probably I would have used SendMessageTimeout() then However, I don't know if it works along with WM_QUIT as I didn't test.

    STATUS_ACCESS_VIOLATION is the define.
    D'oh. I looked it up in the HRESULTs instead of the list of NTSTATUS values

  9. #9
    Registered User awsdert's Avatar
    Join Date
    Jan 2015
    Posts
    1,733
    Quote Originally Posted by aGerman View Post
    Probably I would have used SendMessageTimeout() then However, I don't know if it works along with WM_QUIT as I didn't test.


    D'oh. I looked it up in the HRESULTs instead of the list of NTSTATUS values
    Probably does, seg faults typically trigger core dumps so the 2 combined would be rather natural

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Signals
    By it01y2 in forum C Programming
    Replies: 4
    Last Post: 02-22-2010, 11:03 PM
  2. Signals?
    By ldb88 in forum Windows Programming
    Replies: 4
    Last Post: 08-12-2009, 05:06 PM
  3. signals?
    By C_ntua in forum C# Programming
    Replies: 12
    Last Post: 12-19-2008, 12:35 PM
  4. Signals
    By Govtcheez in forum A Brief History of Cprogramming.com
    Replies: 9
    Last Post: 07-02-2002, 12:30 PM
  5. catch signals
    By shaka87 in forum C++ Programming
    Replies: 0
    Last Post: 06-07-2002, 03:06 AM

Tags for this Thread