I have used DebugActiveProcess to attach a process. After that I used WaitForDebugEvent, but it seems that the application is stuck in some infinite loop and I am not able to debug the attached process.
Below is my code:
DebugActiveProcess( processID );
int temp = 0;
DEBUG_EVENT DBEvent;
while (1)
{
WaitForDebugEvent( &DBEvent, INFINITE );
if ( DBEvent.dwDebugEventCode == EXIT_PROCESS_DEBUG_EVENT )
break;
if ( DBEvent.dwDebugEventCode == CREATE_PROCESS_DEBUG_EVENT )
{
//MessageBox(0,"Debugging started!","Ble",0);
temp = 1;
}
else if ( DBEvent.dwDebugEventCode == EXCEPTION_DEBUG_EVENT )
{
if ( DBEvent.u.Exception.ExceptionRecord.ExceptionCode == EXCEPTION_BREAKPOINT )
{
ContinueDebugEvent( processID, qalsrvid, DBG_CONTINUE );
continue;
}
ContinueDebugEvent( processID, qalsrvid, DBG_EXCEPTION_NOT_HANDLED );
}
}
You are not calling ContinuteDebugEvent on CREATE_PROCESS_DEBUG_EVENT event.
If you have not read it yet, you should:
Writing Windows Debugger and Part 2
Related
The windows functions, CreateEvent, WaitForSingleObject and WaitForMultipleObjects are handy but only used in win32. Can I replace them using Modern C++ threading in a generic way?
I find a post, https://vorbrodt.blog/2019/02/08/event-objects/, to manually set and reset event in modern c++. is there a better way to do that?
The below is the code snippet of old windows code:
DWORD TX_LAYER::__TX_THREAD(HANDLE *done)
{
CONNECTIONS *con = nullptr;
void *temp = nullptr;
const HANDLE h[] =
{
*doneEvent,
evtTX
};
const DWORD num_evts = _countof(h);
while ( true )
{
DWORD ret = -1;
ret = WaitForMultipleObjects(num_evts, h, FALSE, INFINITE);
// Stop signal or critical error.
if ( (ret == 0) || (ret == WAIT_FAILED) )
break;
// TX the packet.
EnterCriticalSection(&csTX);
if ( _tx.empty() == true )
{
ResetEvent(evtTX);
LeaveCriticalSection(&csTX);
continue;
}
temp = *_tx.begin();
_tx.erase(_tx.begin());
if ( _tx.empty() == true )
ResetEvent(evtTX);
else
SetEvent(evtTX);
LeaveCriticalSection(&csTX);
....
....
....
temp = nullptr;
}
I am using CreateEvent to prevent multiple instances of my application:
CreateEvent(NULL, TRUE, FALSE, "MyEvent");
if (GetLastError() == ERROR_ALREADY_EXISTS)
{
// Do Stuff
return FALSE;
}
However, at startup I have noticed that this doesn't work:
After the desktop is shown I automatically run a batch script that attempts to launch multiple instances of my program. The batch script succeeds and I can indeed see multiple instances.
Investigation so far:
OutputDebug shows that each instance does not get ERROR_ALREADY_EXISTS
ProcessExplorer.exe shows that each instance was able to get a handle to the event "MyEvent".
Can anybody think why this might be happening, and how I could solve it?
We use the function below, which is in our common utility DLL. The method is derived from a Microsoft article explaining how to prevent multiple instances in WIN32.
#define STRICT
#include <stdheaders.h>
HANDLE ghSem;
BOOL IExist( LPSTR lpszWindowClass )
{
HWND hWndMe;
int attempt;
for( attempt=0; attempt<2; attempt++ )
{
// Create or open a named semaphore.
ghSem = CreateSemaphore( NULL, 0, 1, lpszWindowClass );
// Close handle and return NULL if existing semaphore was opened.
if( (ghSem != NULL) &&
(GetLastError() == ERROR_ALREADY_EXISTS) )
{ // Someone has this semaphore open...
CloseHandle( ghSem );
ghSem = NULL;
hWndMe = FindWindow( lpszWindowClass, NULL );
if( hWndMe && IsWindow(hWndMe) )
{ // I found the guy, try to wake him up
if( SetForegroundWindow( hWndMe ) )
{ // Windows says we woke the other guy up
return TRUE;
}
}
Sleep(100); // Maybe the semaphore will go away like the window did...
}
else
{ // If new semaphore was created, return FALSE.
return FALSE;
}
}
// We never got the semaphore, so we must
// behave as if a previous instance exists
return TRUE;
}
Just do something like this in your WinMain:
if( IExist("MyWindowClass") )
{
return 1;
}
Of course, you could replace the return with whatever you need to do when you are not the first instance (such as activating the existing instance).
I'm writing an API and I'm facing problems with a Mutex.
The main thread, at some point, does:
void sendMessage (char* g_lpTxBuffer)
{
for ( int i = 0; ( i < 2) && ( FALSE == g_bAckRecvd) ; i++ )
{
sendToSerial( g_lpTxBuffer );
g_iRecvMessage = YES;
g_iState = WAITING_FOR_ACK;
Sleep(50);
}
WaitForSingleObject(g_hMutex, INFINITE);
and I have a child thread, who does:
DWORD WINAPI ThreadProc(void* lpv)
{
g_hMutex = OpenMutex( MUTEX_ALL_ACCESS, FALSE, "MUTEX_RECEIVE" );
while (TRUE)
{
g_bNAKflag = FALSE;
if ( YES == g_iRecvMessage )
{
WaitForSingleObject(g_hMutex, INFINITE);
receiveMessage();
}
if ( MESSAGE_READY == g_iState )
{
processMessage(); // interpret the message
if ( FALSE == g_bNAKflag )
{
g_iState = IDLE;
}
ReleaseMutex(g_hMutex);
}
} // while
return 0;
}
What I found is, if I place the ReleaseMutex() at the place pointed above, the main thread never comes back from the WaitForSingleObject() function. However, if I place it inside the
if ( YES == g_iRecvMessage )>
(which is not good because the receiveMessage is called several times, to receive byte per byte from the serial) it works, and the WaitForSingleObject runs fine..
I create the mutex with
g_hMutex = CreateMutex(NULL, FALSE, "MUTEX_RECEIVE");
and I checked, the ReleaseMutex() returns true
Any ideas?
Thanks..
I've been trying to find a good architecture for one application for the last few days, and after some research I'm finally stuck, and the reason is COM.
The app in question will have multiple GUI threads, and they will schedule work items for worker thread. The worker thread will initialize COM via CoInitialize(NULL);, create few COM components and will go into a loop which will wait for WaitForMultipleObjects(2, ...) (ExitEvent - to indicate that app is shutting down and ManualResetEvent - to indicate that there are actually work items to process), and on successful wait, will process the items and PostMessage them back to GUI threads. The ManualResetEvent will be reset inside worker if the queue will be empty and will happen inside queue critical section.
The problem is that COM, as usual, makes EVERYTHING 1000x harder...
If I understand correctly, CoInitialize(NULL); creates a hidden window, and any message posted during WaitForSingle/MultipleObject/s can cause a deadlock.
So, I need to call the MsgWaitForMultiple objects. Which in turn can fail if messages are not pumped correctly. Unfortunately, I can't quite understand how to pump them in a correct way. Do I have to create my own message loop? Will the app crash if COM decides to create a messagebox?
So far it seems I have to proceed like this?
HANDLE hEvents[2] = {};
int ThreadProc(LPVOID lpParam) {
int nRetVal = 0;
CoInitialize(NULL);
CComPtr<ISomething> smthn;
smthn.CoCreateInstance(...);
MSG msg = {};
bool bRun = true;
while(bRun) {
while(PeekMessage(&msg, ??NULL/-1??, 0, 0, PM_REMOVE)) { /*Which one here?*/
if(msg.Message == WM_QUIT) {
bRun = false;
nRetVal = msg.wParam;
break;
}
TranslateMessage(&msg);
DispatchMessage(&msg);
}
if(MsgWaitForMultipleObjects(2, &hEvents, ...)) {
if(exitevent) { bRun = false; nRetVal = 0; }
else if(processevent) { [processdata] }
}
}
smthn.release();
CoUninitialize();
return nRetVal;
}
But what about hidden window, messageboxes, am I even on the right path?
Just use CoWaitForMultipleHandles and it will do the necessary message pumping on the hidden COM window for inter-thread syncing.
The hidden window is of class OleMainThreadWndClass with OleMainThreadWndName as caption but on win9x its class is WIN95 RPC Wmsg. It's hidden which means you can't use straight EnumThreadWindows to find it.
Seems like overkill, but this worked for me :
int waitAndDispatch( HANDLE* event_handle, unsigned int ev_count, DWORD timeout )
{
int rval = -1;
bool bLoop = true; // if the loop should terminate
HANDLE* pHList = new HANDLE[ev_count];
for( unsigned int i = 0; i < ev_count; ++i )
{
pHList[i] = event_handle[i];
}
while( bLoop )
{
DWORD res = ::MsgWaitForMultipleObjects( ev_count, pHList, false, timeout, QS_ALLPOSTMESSAGE | QS_SENDMESSAGE );
if( res == WAIT_OBJECT_0 + ev_count ) // messages arrived
{
MSG tmpMsg;
bool hasMsg = true;
while( bLoop && hasMsg )
{
::PeekMessage( &tmpMsg, 0, 0, 0, PM_NOREMOVE );
if( ::PeekMessage( &tmpMsg, 0, WM_USER, WM_USER, PM_REMOVE ) || // WM_USER for COM
::PeekMessage( &tmpMsg, 0, 0, WM_KEYFIRST - 1, PM_REMOVE ) // all destroy update, ...
)
{
DWORD val = ::WaitForMultipleObjects( ev_count, pHList, false, 0 );
if( val >= WAIT_OBJECT_0 && val <= (WAIT_OBJECT_0 + ev_count) )
{
rval = val - WAIT_OBJECT_0;
bLoop = false;
}
::DispatchMessage( &tmpMsg );
}
else
{
hasMsg = false;
}
}
}
else if( res >= WAIT_OBJECT_0 && res < (WAIT_OBJECT_0 + ev_count) )
{
rval = res - WAIT_OBJECT_0;
bLoop = false;
}
else if( res == WAIT_TIMEOUT )
{
rval = ev_count;
bLoop = false;
}
else
{
rval = -1;
bLoop = false;
}
}
delete[] pHList;
return rval;
}
I had to write this piece for VB6 and its thread interactions over com compartments ... .
If you initialize your thread apartment with CoInitializeEx( 0, COINIT_MULTITHREADED ), your COM calls will not be queued into an message queue. But then you have the problem of objects created in different COM apartments. These need to be marshaled ... .
I have developed a console ATL application and want to trap the close?, exit?, terminate? event so that I can close log files and perform a general clean-up on exit.
How can I trap the 'terminate' event that would result from someone ending the .exe in the task manager?
EDIT:
It's a console application, I've attached the main class. Could you possibly point to where and how I should use SetConsoleCtrlHandler?
// Override CAtlExeModuleT members
int WinMain(int nShowCmd) throw()
{
if (CAtlBaseModule::m_bInitFailed) //ctor failed somewhere
{
ATLASSERT(0);
return -1;
}
HRESULT hr = S_OK;
LPTSTR lpCmdLine = GetCommandLine(); //this line necessary for _ATL_MIN_CRT
if( ParseCommandLine( lpCmdLine, &hr ) )
{
if( SUCCEEDED( RegisterClassObjects( CLSCTX_LOCAL_SERVER, REGCLS_MULTIPLEUSE ) ) )
{
CComPtr<IRORCAdapterMain> pAdapter;
if( SUCCEEDED( pAdapter.CoCreateInstance( L"RORCAdapter.RORCAdapterMain" ) ) )
{
if( SUCCEEDED( pAdapter->StartAdapter() ) )
{
MSG msg;
while( GetMessage( &msg, 0, 0, 0 ) )
DispatchMessage( &msg );
}
}
RevokeClassObjects();
}
}
You can't trap "End Process" from the Processes tab in Task Manager. If a program could trap it, how would you kill it?
To respond to "End Process" on the Applications tab in Task Manager, handle the WM_CLOSE message in your main window.
This assumes that your ATL app is a Windows GUI application. If it's a console application, you need to look at SetConsoleCtrlHandler.
Catching Ctrl-C / Ctrl-Break is not to hard.
Just call SetConsoleCtrlHandler to specify which call-back function should handle it.
(Hopefully) illustrating example:
#include <wincon.h>
bool g_terminate = false;
int main(void)
{
SetConsoleCtrlHandler( control_handler, TRUE );
while ( !g_terminate )
{
doWork();
}
}
int WINAPI control_handler ( DWORD dwCtrlType )
{
switch( dwCtrlType )
{
case CTRL_BREAK_EVENT:
case CTRL_C_EVENT:
g_terminate = true;
return 1;
default:
return 0;
}
}
/L
Off course, to have you example terminating, in control_handler replace
g_terminate = true;
with
PostMessage(HWND_BROADCAST, WM_CLOSE, 0, 0);