int piunlock (pimutex_t *mtx){ Initialize(); TCB_t* blocked; if(mtx != NULL){ //IF MUTEX IS ALREADY LOCKED BY ANOTHER THREAD if(mtx->flag == 0){ //UNLOCK MUTEX mtx->flag = 1; blocked = mtx->first; if(blocked){ blocked->next = NULL; mutexBlockedThreads = RemoveThread(mutexBlockedThreads, blocked->tid); mtx->first = RemoveFromMutex(mtx->first); if(blocked->credReal){ activeThreads = AddThread(activeThreads, blocked); } else{ expiredThreads = AddThread(expiredThreads, blocked); } } return 0; } } return -1; }
int TcpServThr::Run() { while (Accept() != -1) { /* Create new thread */ MyThread *Rthread, *Wthread; if(CreateThr(&Rthread,&Wthread) == -1) return -1; AddThread(Rthread); AddThread(Wthread); if (Rthread->Start()) return -1; if (Wthread->Start()) return -1; } return -1; }
int picreate(int cred, void* (*entry)(void*), void *arg){ Initialize(); TCB_t* thread; if( ( newStack = (char*)malloc(SIGSTKSZ*(sizeof(char)) ) ) ){ if( ( thread = (TCB_t*)malloc(sizeof(TCB_t)) ) ){ if(cred > 100) cred = 100; if(cred < 1) cred = 1; // NEW THREAD CREATION thread->tid = counter++; thread->state = ABLE; // precisa ter um state "CREATION"? thread->credCreate = cred; thread->credReal = cred; getcontext(&thread->context); thread->context.uc_link = finishCtx; thread->context.uc_stack.ss_sp = newStack; thread->context.uc_stack.ss_size = SIGSTKSZ; thread->context.uc_stack.ss_flags = 0; makecontext(&thread->context, (void (*)(void)) entry, 1, arg); activeThreads = AddThread(activeThreads, thread); return thread->tid; } } return -1; }
void unblock(){ TCB_t* blockedThread = NULL; WaitQueue_t* waited = NULL; //IF THERE ARE THREADS TO BE WAITED FOR if(waitTids){ //VERIFY IF THE FINISHED THREAD IS WAITED //FOR ANOTHER THREAD waited = GetWait(waitTids,runningThread->tid); if(waited){ //FIND THE CORRESPONDING BLOCKED THREAD, //REMOVES IT FROM THE BLOCKED THREADS LIST //AND ADDS IT TO THE ABLE THREADS LIST blockedThread = GetThread(blockedThreads, waited->waiting); blockedThread->state = ABLE; blockedThreads = RemoveThread(blockedThreads, blockedThread->tid); waitTids = RemoveWait(waitTids,runningThread->tid); activeThreads = AddThread(activeThreads, blockedThread); } } }
//=========================================================================== // build the bsp tree using a node list // // Parameter: - // Returns: - // Changes Globals: - //=========================================================================== void BuildTree( tree_t *tree ) { int i; firstnode = NULL; lastnode = NULL; //use a node queue or node stack if ( use_nodequeue ) { AddNodeToList = AddNodeToQueue; } else { AddNodeToList = AddNodeToStack;} //setup thread locking ThreadSetupLock(); ThreadSetupSemaphore(); numwaiting = 0; // Log_Print( "%6d threads max\n", numthreads ); if ( use_nodequeue ) { Log_Print( "breadth first bsp building\n" ); } else { Log_Print( "depth first bsp building\n" );} qprintf( "%6d splits", 0 ); //add the first node to the list AddNodeToList( tree->headnode ); //start the threads for ( i = 0; i < numthreads; i++ ) AddThread( BuildTreeThread ); //wait for all added threads to be finished WaitForAllThreadsFinished(); //shutdown the thread locking ThreadShutdownLock(); ThreadShutdownSemaphore(); } //end of the function BuildTree
int pilock(pimutex_t *mtx){ Initialize(); if(mtx != NULL){ //IF MUTEX IS ALREADY LOCKED BY ANOTHER THREAD if(mtx->flag == 0){ runningThread->state = BLOCKED; mutexBlock = 1; //PUTS THREAD IN MUTEX LOCKED LIST mutexBlockedThreads = AddThread(mutexBlockedThreads, runningThread); mtx->first = AddToMutex(mtx->first, runningThread); swapcontext(&runningThread->context, schedulerCtx); } //LOCK MUTEX mtx->flag = 0; return 0; } return -1; }
void sprawl::threading::ThreadManager::AddThreads(uint64_t threadFlags, int count) { for(int i = 0; i < count; ++i) { AddThread(threadFlags); } }
void TaskPool::QueueJob(JobProc * fun, void * arg, HANDLE * event) { static JobInfo info; int length; //Get access to the queue WaitForSingleObject(m_hQueueMutex, INFINITE); //Build the job info info.fun = fun; info.arg = arg; if (event) *event = info.event = CreateEvent(NULL, FALSE, FALSE, NULL); else info.event = NULL; //Add the job m_jobsQueue.push_back(info); //Get the length of the queue length = (int)m_jobsQueue.size(); //Release access to the queue ReleaseMutex(m_hQueueMutex); //Let the new job be processed ReleaseSemaphore(m_hPendingWindowsSem, 1, NULL); //Increase the number of thread, if needed if ((length<<1) > m_nThreadCount) AddThread(); }
void sprawl::threading::ThreadManager::Start(uint64_t thisThreadFlags) { m_running = true; if(m_maxStage != 0) { m_syncState = SyncState::Threads; m_currentStage = 1; } for(auto& threadInfo : m_threads) { threadInfo.thread->Start(); } AddThread(thisThreadFlags, "Main Thread"); m_mainThreadMailbox = &m_threads.Back().data->mailbox; m_mainThreadQueue = &m_flagGroups.Get(m_threads.Back().data->flags)->taskQueue; if(m_maxStage != 0) { size_t threadCount = m_threads.Size() - 1; while(m_syncCount != threadCount) { m_workerSyncEvent.Wait(); } } m_mailmanThread.Start(); }
void sprawl::threading::ThreadManager::AddThreads(uint64_t threadFlags, int count, const char* const threadName) { for(int i = 0; i < count; ++i) { AddThread(threadFlags, threadName); } }
SSLInitCls::SSLInitCls() { Socket::Init(); MemoryIgnoreLeaksBlock __; CRYPTO_set_mem_functions(SSLAlloc, SSLRealloc, SSLFree); SSL_load_error_strings(); SSL_library_init(); AddThread(); }
// GetSpoolMessages - Manages creation & deletion of spooler message threads DWORD GetSpoolMessages() { if (!GdiInitSpool()) { DBGMSG(DBG_TRACE, ("Error calling GdiInitSpool()\n")); return GetLastError(); } return AddThread(); }
//-------------------------------------------------------------------------------- CMonitorSubSystem::CMonitorSubSystem(CSecuritySystem* pParent) : CSSSubSystem<CThreadPoolSubSystem>(pParent) { m_pHandler = new CSystemMonitorThread(this); m_pHandler->StartThread(); CSSConfigPerformance config(this); for(UINT i = 0; i < config.m_nMonitorPoolSize; i++) AddThread(new CSystemMonitorHandlerThread(this)); }
Threads::Threads(wxWindow *parent) : wxGrid(parent, wxID_ANY) , numThreads(0) , activeThread(0) { CreateGrid(0, 2); HideRowLabels(); // Add the headers. SetColLabelValue(0, "PID"); SetColLabelValue(1, "Name"); SetColSize(0, 40); SetColSize(1, 160); // tmp AddThread("123", "main_thread"); AddThread("6001", "worker_pool_0"); AddThread("6013", "worker_pool_1"); UpdateActiveThread(); }
int Run(LPTSTR lpstrCmdLine, int nCmdShow) { MSG msg; // force message queue to be created ::PeekMessage(&msg, NULL, WM_USER, WM_USER, PM_NOREMOVE); AddThread(lpstrCmdLine, nCmdShow); int nRet = m_dwCount; DWORD dwRet; while(m_dwCount > 0) { dwRet = ::MsgWaitForMultipleObjects(m_dwCount, m_arrThreadHandles, FALSE, INFINITE, QS_ALLINPUT); if(dwRet == 0xFFFFFFFF) { ::MessageBox(NULL, _T("ERROR: Wait for multiple objects failed!!!"), _T("TradeYM"), MB_OK); } else if(dwRet >= WAIT_OBJECT_0 && dwRet <= (WAIT_OBJECT_0 + m_dwCount - 1)) { RemoveThread(dwRet - WAIT_OBJECT_0); } else if(dwRet == (WAIT_OBJECT_0 + m_dwCount)) { if(::PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)) { if(msg.message == WM_USER) AddThread(_T(""), SW_SHOWNORMAL); } } else { ::MessageBeep((UINT)-1); } } return nRet; }
ThreadEntry* ThreadTree::FindThreadOrNew(int pid, int tid) { auto it = thread_tree_.find(tid); if (it == thread_tree_.end()) { AddThread(pid, tid, "unknown"); it = thread_tree_.find(tid); } else { if (pid != it->second.get()->pid) { // TODO: b/22185053. LOG(DEBUG) << "unexpected (pid, tid) pair: expected (" << it->second.get()->pid << ", " << tid << "), actual (" << pid << ", " << tid << ")"; } } return it->second.get(); }
void sprawl::threading::ThreadManager::Run(uint64_t thisThreadFlags) { m_running = true; for(auto& threadData : m_threads) { threadData.thread->Start(); } AddThread(thisThreadFlags, "Main Thread"); m_mainThreadMailbox = &m_threads.Back().data->mailbox; m_mainThreadQueue = &m_flagGroups.Get(m_threads.Back().data->flags)->taskQueue; m_mailmanThread.Start(); eventLoop_(m_threads.Back().data); }
//-------------------------------------------------------------------------------- bool CChangeNotificationSubSystem::AddWatchPath(LPCTSTR pPath, bool bWatchSubDir, DWORD nFilter) { CSingleLock lock(&m_mutPaths, false); if(! lock.Lock()) return false; if(! PreAddWatchPath(pPath)) return false; int nIndex = m_sWatchedPaths.Add(pPath); AddThread((CThreadObject*) new CChangeNotificationThread(this, nIndex, bWatchSubDir, nFilter)); return true; }
TaskPool::TaskPool(int minThread, int maxThread) { m_hPendingWindowsSem = CreateSemaphore(NULL, 0, 50, NULL); m_hStopThread = CreateEvent(NULL, FALSE, FALSE, NULL); m_hQueueMutex = CreateMutex(NULL, FALSE, NULL); m_nThreadCount = 0; m_dwThreadTimeout = 1000*600; // 10 minutes m_nMinThreadCount = minThread; m_nMaxThreadCount = maxThread; for(int i=0; i<m_nMinThreadCount; i++) AddThread(); }
void TaskPool::SetThreadCount(LONG count) { LONG delta = count - m_nThreadCount; if (delta > 0) { for(LONG i=0; i<delta; i++) AddThread(); } else if (delta < 0) { for(LONG i=delta; i<0; i++) DelThread(); } }
/* readonly attribute nsIExceptionManager currentExceptionManager; */ NS_IMETHODIMP nsExceptionService::GetCurrentExceptionManager(nsIExceptionManager * *aCurrentScriptManager) { CHECK_SERVICE_USE_OK(); nsExceptionManager *mgr = (nsExceptionManager *)PR_GetThreadPrivate(tlsIndex); if (mgr == nsnull) { // Stick the new exception object in with no reference count. mgr = new nsExceptionManager(this); if (mgr == nsnull) return NS_ERROR_OUT_OF_MEMORY; PR_SetThreadPrivate(tlsIndex, mgr); // The reference count is held in the thread-list AddThread(mgr); } *aCurrentScriptManager = mgr; NS_ADDREF(*aCurrentScriptManager); return NS_OK; }
uint32_t GetImageInfo(struct VirtualMachine* pVM, struct UserFileStruct* pFile, struct DecodeStruct* pInfo, struct ImageInfo* pImageInfo) { uint8_t JPEG_id[] = { 0xff, 0xd8 }; if(pFile->available_size >=2 && memcmp(pVM->pGlobalMemory + pFile->pBuf, JPEG_id, sizeof(JPEG_id)) == 0){ // image is jpeg format if(AddThread(pVM, GetJPEGInfo, pInfo) != VM_OK){ assert(false); return VM_DECODER_CANT_CREATE_THREAD; } return VM_DECODER_OK; }else{ // assert(false); return VM_DECODER_NOT_ENOUGH_DATA; } return VM_DECODER_OK; }
inline void ThreadPool::Add(Task* t) { assert(t != NULL); queue.Push(t); if (queue.Size() > GetIdleThreadCount()) // may be need add new thread { int need1 = maxThread - GetThreadCount(); int need2 = queue.Size() - GetIdleThreadCount(); int count = (need1 > need2) ? need2 : need1; AddThread(count); } else // may be need delete idle timeout thread { while (RemoveOneIdleTimeoutThread()) { } } RemoveStopedThreads(); }
status_t Team::AddThread(const ThreadInfo& threadInfo, Thread** _thread) { Thread* thread = new(std::nothrow) Thread(this, threadInfo.ThreadID()); if (thread == NULL) return B_NO_MEMORY; status_t error = thread->Init(); if (error != B_OK) { delete thread; return error; } thread->SetName(threadInfo.Name()); AddThread(thread); if (_thread != NULL) *_thread = thread; return B_OK; }
void MtgCalculator::BeeReturned(int Ident, const MtgCashFlow& a) { Q_D(MtgCalculator); RETURN_WHEN_RUNNING(false, ) d->m_AggregatedRes += a; Q_ASSERT(d->m_Loans.contains(Ident)); { auto tempLoan = std::get<1>(d->m_Loans.value<Mortgage>(Ident)); tempLoan.SetCashFlows(a); SetLoan(tempLoan, Ident); } TemplAsyncCalculator<MtgCalculatorThread, MtgCashFlow>::BeeReturned(Ident, a); if (!ContinueCalculation()) return; MtgCalculatorThread* CurrentThread; const auto loansKeys = d->m_Loans.keys(); for (auto SingleLoan = loansKeys.constBegin(); SingleLoan != loansKeys.constEnd(); ++SingleLoan) { if (d->BeesSent.contains(*SingleLoan)) continue; CurrentThread = AddThread(*SingleLoan); CurrentThread->SetLoan(std::get<1>(d->m_Loans.value<Mortgage>(*SingleLoan))); if (d->TempProperties.contains(*SingleLoan)) { const auto CurrProps = d->TempProperties.value(*SingleLoan); for (auto j = CurrProps->constBegin(); j != CurrProps->constEnd(); ++j) { CurrentThread->SetLoanProperty(j.key(), j.value()); } } CurrentThread->SetCPR(d->m_CPRass); CurrentThread->SetCDR(d->m_CDRass); CurrentThread->SetLS(d->m_LSass); CurrentThread->SetRecoveryLag(d->m_RecoveryLag); CurrentThread->SetDelinquency(d->m_Delinquency); CurrentThread->SetDelinquencyLag(d->m_DelinquencyLag); CurrentThread->SetOverrideAssumptions(d->m_OverrideAssumptions); CurrentThread->SetStartDate(d->StartDate); CurrentThread->SetDownloadScenario(d->m_DownloadScenario); CurrentThread->start(); return; } }
/* uint32_t DecodeImage(uint32_t op_id, uint8_t* pSrc, uint32_t size, struct void* pStruct) op_id - id of operation to perform from enum DecoderOps pSrc - pointer to compressed file size - size of available compressed file pStruct - pointer to ImageInfo or DecodeInfo struct depends on operation Return Value VM_DECODER_OK - success VM_DECODER_DECODE_FAILED - some error appears, maybe file corrupted or system haven't enough memory for decoder VM_DECODER_REACHED_MAX_THREADS - number of threads currently running by VM is reached their limit, wait a bit */ uint32_t SYSCALL SysDecodeImage(struct VirtualMachine* pVM) { uint32_t id = pVM->Registers.r[0]; switch(id){ case VM_DECODER_GET_INFO: { struct UserFileStruct* pFile; struct ImageInfo* pImageInfo; uint32_t file_addr = pVM->Registers.r[1]; uint32_t struct_addr = pVM->Registers.r[2]; // check input structs if(((uint64_t)file_addr + sizeof(struct UserFileStruct)) > pVM->GlobalMemorySize){ assert(false); return VM_DATA_ACCESS_VIOLATION; } if(((uint64_t)struct_addr + sizeof(struct ImageInfo)) > pVM->GlobalMemorySize){ assert(false); return VM_DATA_ACCESS_VIOLATION; } // check buffers pFile = (struct UserFileStruct*)(pVM->pGlobalMemory + file_addr); if(((uint64_t)pFile->pBuf + pFile->buf_size) > pVM->GlobalMemorySize){ assert(false); return VM_DATA_ACCESS_VIOLATION; } struct DecodeStruct* pInfo; pInfo = (struct DecodeStruct*)vm_malloc(sizeof(DecodeStruct)); if(pInfo == NULL){ assert(false); return VM_NOT_ENOUGH_MEMORY; } pImageInfo = (struct ImageInfo*)(pVM->pGlobalMemory + struct_addr); memset(pInfo, 0, sizeof(struct DecodeStruct)); pInfo->pVM = pVM; pInfo->pFile = pFile; pInfo->pUser = (struct UserDecodeStruct*)pImageInfo; pInfo->pSrc = pVM->pGlobalMemory + pFile->pBuf; pInfo->src_size = pFile->buf_size; pVM->Registers.r[0] = GetImageInfo(pVM, pFile, pInfo, pImageInfo); } break; case VM_DECODE_JPEG: { struct UserFileStruct* pFile; struct UserDecodeStruct* pUserInfo; uint32_t file_addr = pVM->Registers.r[1]; uint32_t addr = pVM->Registers.r[2]; // check input structs if(((uint64_t)file_addr + sizeof(UserFileStruct)) > pVM->GlobalMemorySize){ assert(false); return VM_DATA_ACCESS_VIOLATION; } if(((uint64_t)addr + sizeof(UserDecodeStruct)) > pVM->GlobalMemorySize){ assert(false); return VM_DATA_ACCESS_VIOLATION; } // check buffers pFile = (struct UserFileStruct*)(pVM->pGlobalMemory + file_addr); if(((uint64_t)pFile->pBuf + pFile->buf_size) > pVM->GlobalMemorySize){ assert(false); return VM_DATA_ACCESS_VIOLATION; } pUserInfo = (struct UserDecodeStruct*)(pVM->pGlobalMemory + addr); if(((uint64_t)pUserInfo->pDst + pUserInfo->dst_size) > pVM->GlobalMemorySize){ assert(false); return VM_DATA_ACCESS_VIOLATION; } struct DecodeStruct* pInfo = (struct DecodeStruct*)vm_malloc(sizeof(DecodeStruct)); if(pInfo == NULL){ assert(false); return VM_NOT_ENOUGH_MEMORY; } memset(pInfo, 0, sizeof(struct DecodeStruct)); pInfo->pVM = pVM; pInfo->pFile = pFile; pInfo->pUser = pUserInfo; pInfo->pSrc = pVM->pGlobalMemory + pFile->pBuf; pInfo->pDst = pVM->pGlobalMemory + pUserInfo->pDst; pInfo->src_size = pFile->buf_size; if(AddThread(pVM, DecodeJPEG, pInfo) != VM_OK){ assert(false); pVM->Registers.r[0] = VM_DECODER_CANT_CREATE_THREAD; } pVM->Registers.r[0] = VM_DECODER_OK; } break; default: assert(false); return VM_INVALID_SYSCALL; } return VM_OK; }
// SELECTS NEXT RUNNING THREAD void schedule(){ // IF RUNNING THREAD IS NOT FINISHED // PUTS THE THREAD IN ONE OF THE TWO // ABLE QUEUES if(runningThread->state != FINISHED){ DecreaseCredits(runningThread); if(runningThread->state == ABLE){ if (runningThread->credReal == 0){ expiredThreads = AddThread(expiredThreads, runningThread); } else{ activeThreads = AddThread(activeThreads, runningThread); } } else{ if(runningThread->state == BLOCKED){ if(mutexBlock){ //if it was blocked while locking a mutex //reset the flag and it was added to another queue //in the pilock function mutexBlock = 0; } else{ blockedThreads = AddThread(blockedThreads, runningThread); } } } } else{ // IF THE THREAD IS FINISHED, // FREE THE TCB MEMORY free(runningThread); } // SELECTS NEXT THREAD TO RUN runningThread = activeThreads; if (runningThread == NULL){ SwapQueues(&activeThreads, &expiredThreads); activeThreads = RestoreCredits(activeThreads); runningThread = activeThreads; } activeThreads = activeThreads->next; runningThread->next = NULL; runningThread->prev = NULL; if(activeThreads) activeThreads->prev = NULL; runningThread->state = EXECUTION; setcontext(&runningThread->context); }
bool CODebugger::run(unsigned int msec) { DEBUG_EVENT deDebugEvent; //调试事件信息 bool bResult = true; // 等待调试事件 if(m_bActive && WaitForDebugEvent(&deDebugEvent, msec)) { //处理调试事件 switch(deDebugEvent.dwDebugEventCode) { //调试异常事件 case EXCEPTION_DEBUG_EVENT: { bResult = OnDebugException(deDebugEvent); break; } //创建线程 case CREATE_THREAD_DEBUG_EVENT: { AddThread(deDebugEvent.dwThreadId, deDebugEvent.u.CreateThread.hThread, (DWORD)deDebugEvent.u.CreateThread.lpStartAddress, (DWORD)deDebugEvent.u.CreateThread.lpThreadLocalBase); // call overloady D_CreateThread(&deDebugEvent); break; } //创建进程 case CREATE_PROCESS_DEBUG_EVENT: { //m_hProcess = deDebugEvent.u.CreateProcessInfo.hProcess; //m_hThread = deDebugEvent.u.CreateProcessInfo.hThread; //将主线程添加到线程链表 DEBUGGER_THREAD* pDebuggerThread = AddThread(deDebugEvent.dwThreadId,deDebugEvent.u.CreateProcessInfo.hThread,0,0); pDebuggerThread->m_bIsMainThread = true; // call overloady D_CreateProcess(&deDebugEvent); // 关闭进程文件句柄 if(deDebugEvent.u.CreateProcessInfo.hFile) { CloseHandle(deDebugEvent.u.CreateProcessInfo.hFile); } break; } //结束线程 case EXIT_THREAD_DEBUG_EVENT: { RemoveThread(deDebugEvent.dwThreadId); // call overloady D_ExitThread(&deDebugEvent); break; } //结束进程 case EXIT_PROCESS_DEBUG_EVENT: { if(exitfunc != NULL) { (*exitfunc)(&deDebugEvent); } // call overloady D_ExitProcess(&deDebugEvent); break; } //加载DLL case LOAD_DLL_DEBUG_EVENT: { break; } //卸载DLL case UNLOAD_DLL_DEBUG_EVENT: break; //输出调试字符串 case OUTPUT_DEBUG_STRING_EVENT: { // call overloady D_OutputDebugString(&deDebugEvent); break; } default: { bResult = false; } } DWORD dwContinueStatus; dwContinueStatus = bResult?DBG_CONTINUE:DBG_EXCEPTION_NOT_HANDLED; ContinueDebugEvent(deDebugEvent.dwProcessId, deDebugEvent.dwThreadId,dwContinueStatus); } else { return false; } return true; }
/* * AccLoadProg - create a new process for debugging */ trap_retval ReqProg_load( void ) { char *parm; char *src; char *dst; char *endsrc; char exe_name[PATH_MAX]; char ch; BOOL rc; int len; MYCONTEXT con; thread_info *ti; HANDLE handle; prog_load_req *acc; prog_load_ret *ret; header_info hi; WORD stack; WORD version; DWORD pid; DWORD pid_started; DWORD cr_flags; char *buff = NULL; size_t nBuffRequired = 0; char *dll_name; char *service_name; char *dll_destination; char *service_parm; acc = GetInPtr( 0 ); ret = GetOutPtr( 0 ); parm = GetInPtr( sizeof( *acc ) ); /* * reset status variables */ LastExceptionCode = -1; DebugString = NULL; DebugeeEnded = FALSE; RemoveAllThreads(); FreeLibList(); DidWaitForDebugEvent = FALSE; DebugeePid = 0; DebugeeTid = 0; SupportingExactBreakpoints = 0; /* * check if pid is specified */ ParseServiceStuff( parm, &dll_name, &service_name, &dll_destination, &service_parm ); pid = 0; src = parm; /* // Just to be really safe! */ nBuffRequired = GetTotalSize() + PATH_MAX + 16; if( NULL == ( buff = malloc( nBuffRequired ) ) ) { ret->err = ERROR_NOT_ENOUGH_MEMORY; return( sizeof( *ret ) ); } if( *src == '#' ) { src++; pid = strtoul( src, &endsrc, 16 ); if( pid == 0 ) { pid = -1; } strcpy( buff, endsrc ); } else { while( isdigit( *src ) ) { src++; } if( *src == 0 && src != parm ) { pid = atoi( parm ); } } /* * get program to debug. If the user has specified a pid, then * skip directly to doing a DebugActiveProcess */ IsWOW = FALSE; #if !defined( MD_x64 ) IsDOS = FALSE; #endif if( pid == 0 ) { if( FindFilePath( parm, exe_name, ExtensionList ) != 0 ) { ret->err = ERROR_FILE_NOT_FOUND; goto error_exit; } /* * Get type of application */ handle = CreateFile( (LPTSTR)exe_name, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, 0 ); if( handle == INVALID_HANDLE_VALUE ) { ret->err = GetLastError(); goto error_exit; } GetFullPathName( exe_name, MAX_PATH, CurrEXEName, NULL ); /* * get the parm list */ if( strchr( CurrEXEName, ' ' ) != NULL ) { strcpy( buff, "\"" ); strcat( buff, CurrEXEName ); strcat( buff, "\"" ); } else { strcpy( buff, CurrEXEName ); } dst = &buff[strlen( buff )]; src = parm; while( *src != 0 ) { ++src; } // parm layout // <--parameters-->0<--program_name-->0<--arguments-->0 // for( len = GetTotalSize() - sizeof( *acc ) - (src - parm) - 1; len > 0; --len ) { ch = *src; if( ch == 0 ) { ch = ' '; } *dst = ch; ++dst; ++src; } *dst = 0; cr_flags = DEBUG_ONLY_THIS_PROCESS; if( !GetEXEHeader( handle, &hi, &stack ) ) { ret->err = GetLastError(); CloseHandle( handle ); goto error_exit; } if( hi.sig == EXE_PE ) { if( IS_PE64( hi.u.peh ) ) { DebugeeSubsystem = PE64( hi.u.peh ).subsystem; } else { DebugeeSubsystem = PE32( hi.u.peh ).subsystem; #if defined( MD_x64 ) IsWOW = TRUE; #endif } if( DebugeeSubsystem == SS_WINDOWS_CHAR ) { cr_flags |= CREATE_NEW_CONSOLE; } #if !defined( MD_x64 ) } else if( hi.sig == EXE_NE ) { IsWOW = TRUE; /* * find out the pid of WOW, if it is already running. */ pVDMEnumProcessWOW( EnumWOWProcessFunc, (LPARAM)&pid ); if( pid != 0 ) { version = LOWORD( GetVersion() ); if( LOBYTE( version ) == 3 && HIBYTE( version ) < 50 ) { int kill = MessageBox( NULL, TRP_NT_wow_warning, TRP_The_WATCOM_Debugger, MB_APPLMODAL + MB_YESNO ); if( kill == IDYES ) { DWORD axs = PROCESS_TERMINATE+STANDARD_RIGHTS_REQUIRED; HANDLE hprocess = OpenProcess( axs, FALSE, pid ); if( hprocess != 0 && TerminateProcess( hprocess, 0 ) ) { CloseHandle( hprocess ); pid = 0; } } } else { cr_flags |= CREATE_SEPARATE_WOW_VDM; pid = 0; // always start a new VDM. } } if( pid != 0 ) { ret->err = GetLastError(); CloseHandle( handle ); goto error_exit; } } else { IsDOS = TRUE; #endif } CloseHandle( handle ); } /* * start the debugee */ pid_started = pid; if( *dll_name ) { strcat( buff, LOAD_PROG_STR_DELIM ); strcat( buff, LOAD_PROG_STR_DLLNAME ); strcat( buff, dll_name ); } if( *service_name ) { strcat( buff, LOAD_PROG_STR_DELIM ); strcat( buff, LOAD_PROG_STR_SERVICE ); strcat( buff, service_name ); } if( *dll_destination ) { strcat( buff, LOAD_PROG_STR_DELIM ); strcat( buff, LOAD_PROG_STR_COPYDIR ); strcat( buff, dll_destination ); } if( *service_parm ) { strcat( buff, LOAD_PROG_STR_DELIM ); strcat( buff, LOAD_PROG_STR_SERVICEPARM ); strcat( buff, service_parm ); } ret->err = StartControlThread( buff, &pid_started, cr_flags ); if( ret->err != 0 ) { goto error_exit; } /* * CREATE_PROCESS_DEBUG_EVENT will always be the first debug event. * If it is not, then something is horribly wrong. */ rc = MyWaitForDebugEvent(); if( !rc || ( DebugEvent.dwDebugEventCode != CREATE_PROCESS_DEBUG_EVENT ) || ( DebugEvent.dwProcessId != pid_started ) ) { ret->err = GetLastError(); goto error_exit; } ProcessInfo.pid = DebugEvent.dwProcessId; ProcessInfo.process_handle = DebugEvent.u.CreateProcessInfo.hProcess; ProcessInfo.base_addr = DebugEvent.u.CreateProcessInfo.lpBaseOfImage; AddProcess( &hi ); AddThread( DebugEvent.dwThreadId, DebugEvent.u.CreateProcessInfo.hThread, DebugEvent.u.CreateProcessInfo.lpStartAddress ); DebugeePid = DebugEvent.dwProcessId; DebugeeTid = DebugEvent.dwThreadId; LastDebugEventTid = DebugEvent.dwThreadId; #if defined( MD_x86 ) #ifdef WOW if( IsWOW ) { ret->flags = LD_FLAG_IS_PROT; ret->err = 0; ret->task_id = DebugeePid; /* * we use our own CS and DS as the Flat CS and DS, for lack * of anything better */ FlatDS = GetDS(); FlatCS = GetCS(); if( !executeUntilVDMStart() ) { ret->err = GetLastError(); goto error_exit; } if( pid ) { addAllWOWModules(); } else { addKERNEL(); } /* * we save the starting CS:IP of the WOW app, since we will use * it to force execution of code later */ ti = FindThread( DebugeeTid ); MyGetThreadContext( ti, &con ); WOWAppInfo.segment = ( WORD ) con.SegCs; WOWAppInfo.offset = ( WORD ) con.Eip; con.SegSs = con.SegDs; // Wow lies about the stack segment. Reset it con.Esp = stack; MySetThreadContext( ti, &con ); } else if( IsDOS ) { // TODO! Clean up this code ret->flags = 0; //LD_FLAG_IS_PROT; ret->err = 0; ret->task_id = DebugeePid; /* * we use our own CS and DS as the Flat CS and DS, for lack * of anything better */ FlatDS = GetDS(); FlatCS = GetCS(); if( !executeUntilVDMStart() ) { ret->err = GetLastError(); goto error_exit; } #if 0 if( pid ) { addAllWOWModules(); } else { addKERNEL(); } #endif /* * we save the starting CS:IP of the WOW app, since we will use * it to force execution of code later */ ti = FindThread( DebugeeTid ); MyGetThreadContext( ti, &con ); WOWAppInfo.segment = ( WORD )con.SegCs; WOWAppInfo.offset = ( WORD )con.Eip; con.SegSs = con.SegDs; // Wow lies about the stack segment. Reset it con.Esp = stack; MySetThreadContext( ti, &con ); } else { #else { #endif #else { #endif LPVOID base; if( pid == 0 ) { base = (LPVOID)DebugEvent.u.CreateProcessInfo.lpStartAddress; } else { base = 0; } ret->flags = LD_FLAG_IS_PROT; ret->err = 0; ret->task_id = DebugeePid; if( executeUntilStart( pid != 0 ) ) { LPVOID old; /* * make the application load our DLL, so that we can have it * run code out of it. One small note: this will not work right * if the app does not load our DLL at the same address the * debugger loaded it at!!! */ ti = FindThread( DebugeeTid ); MyGetThreadContext( ti, &con ); old = (LPVOID)AdjustIP( &con, 0 ); if( base != 0 ) { SetIP( &con, base ); } MySetThreadContext( ti, &con ); SetIP( &con, old ); MySetThreadContext( ti, &con ); } ti = FindThread( DebugeeTid ); MyGetThreadContext( ti, &con ); #if defined( MD_x86 ) FlatCS = con.SegCs; FlatDS = con.SegDs; #endif ret->flags |= LD_FLAG_IS_BIG; } ret->flags |= LD_FLAG_HAVE_RUNTIME_DLLS; if( pid != 0 ) { ret->flags |= LD_FLAG_IS_STARTED; } ret->mod_handle = 0; error_exit: if( buff ) { free( buff ); buff = NULL; } return( sizeof( *ret ) ); } trap_retval ReqProg_kill( void ) { prog_kill_ret *ret; ret = GetOutPtr( 0 ); ret->err = 0; DelProcess( TRUE ); StopControlThread(); return( sizeof( *ret ) ); }
bool Pdb::RunToException() { DR_LOG("RunToException"); LLOG("RUN TO EXCEPTION"); TimeStop ts; bool disasfocus = disas.HasFocus(); bool locked = false; bool frestored = false; invalidpage.Clear(); mempage.Clear(); int opn = 0; for(;;) { if(terminated) { if(locked) Unlock(); return false; } opn++; DR_LOG("WaitForDebugEvent"); if(WaitForDebugEvent(&event, 0)) { DR_LOG("WaitForDebugEvent ended"); debug_threadid = event.dwThreadId; opn = 0; running = false; switch(event.dwDebugEventCode) { case EXCEPTION_DEBUG_EVENT: { DR_LOG("EXCEPTION_DEBUG_EVENT"); LLOG("Exception: " << FormatIntHex(event.u.Exception.ExceptionRecord.ExceptionCode) << " at: " << FormatIntHex(event.u.Exception.ExceptionRecord.ExceptionAddress) << " first: " << event.u.Exception.dwFirstChance); SaveForeground(); const EXCEPTION_RECORD& x = event.u.Exception.ExceptionRecord; if(findarg(x.ExceptionCode, EXCEPTION_BREAKPOINT, EXCEPTION_SINGLE_STEP, STATUS_WX86_BREAKPOINT, STATUS_WX86_SINGLE_STEP) < 0) { LLOG("Non-debug EXCEPTION"); if(event.u.Exception.dwFirstChance) { LLOG("First chance " << FormatIntHex(x.ExceptionCode)); break; } String desc = Format("Exception: [* %lX] at [* %16llX]&", (int64)x.ExceptionCode, (int64)x.ExceptionAddress); for(int i = 0; i < __countof(ex_desc); i++) if(ex_desc[i].code == x.ExceptionCode) desc << "[* " << DeQtf(ex_desc[i].text) << "]&"; if(x.ExceptionCode == EXCEPTION_ACCESS_VIOLATION) { desc << (x.ExceptionInformation[0] ? "[*@3 writing]" : "[*@4 reading]"); desc << Format(" at [* %08llX]", (int64)x.ExceptionInformation[1]); } ToForeground(); PromptOK(desc); } #ifdef CPU_64 if(!win64 && x.ExceptionCode == EXCEPTION_BREAKPOINT && !break_running) // Ignore x64 breakpoint in wow64 break; #endif if(break_running) debug_threadid = mainThreadId; break_running = false; ToForeground(); if(disasfocus) disas.SetFocus(); if(locked) Unlock(); if(refreshmodules) LoadModuleInfo(); LLOG("event.dwThreadId = " << event.dwThreadId); bool isbreakpoint = findarg(x.ExceptionCode, EXCEPTION_BREAKPOINT, STATUS_WX86_BREAKPOINT) >= 0; for(int i = 0; i < threads.GetCount(); i++) { Thread& t = threads[i]; (Context&)t = ReadContext(threads[i].hThread); if(event.dwThreadId == threads.GetKey(i)) { LLOG("Setting current context"); if(isbreakpoint #ifdef CPU_64 && bp_set.Find((win64 ? t.context64.Rip : t.context32.Eip) - 1) >= 0 #else && bp_set.Find(t.context32.Eip - 1) >= 0 #endif ) // We have stopped at breakpoint, need to move address back #ifdef CPU_64 if(win64) t.context64.Rip--; else #endif t.context32.Eip--; context = t; } } RemoveBp(); return true; } case CREATE_THREAD_DEBUG_EVENT: DR_LOG("CREATE_THREAD_DEBUG_EVENT"); LLOG("Create thread: " << event.dwThreadId); AddThread(event.dwThreadId, event.u.CreateThread.hThread); break; case EXIT_THREAD_DEBUG_EVENT: DR_LOG("EXIT_THREAD_DEBUG_EVENT"); LLOG("Exit thread: " << event.dwThreadId); RemoveThread(event.dwThreadId); break; case CREATE_PROCESS_DEBUG_EVENT: DR_LOG("CREATE_PROCESS_DEBUG_EVENT"); LLOG("Create process: " << event.dwProcessId); processid = event.dwProcessId; AddThread(event.dwThreadId, event.u.CreateProcessInfo.hThread); CloseHandle(event.u.CreateProcessInfo.hFile); CloseHandle(event.u.CreateProcessInfo.hProcess); break; case EXIT_PROCESS_DEBUG_EVENT: DR_LOG("EXIT_PROCESS_DEBUG_EVENT"); LLOG("Exit process: " << event.dwProcessId); if(locked) Unlock(); terminated = true; return false; case LOAD_DLL_DEBUG_EVENT: { DR_LOG("LOAD_DLL_DEBUG_EVENT"); LLOG("Load dll: " << event.u.LoadDll.lpBaseOfDll); CloseHandle(event.u.LoadDll.hFile); refreshmodules = true; break; } case UNLOAD_DLL_DEBUG_EVENT: DR_LOG("UNLOAD_DLL_DEBUG_EVENT"); LLOG("UnLoad dll: " << event.u.UnloadDll.lpBaseOfDll); refreshmodules = true; break; case RIP_EVENT: DR_LOG("RIP_EVENT"); LLOG("RIP!"); Exclamation("Process being debugged died unexpectedly!"); terminated = true; if(locked) Unlock(); return false; } DR_LOG("ContinueDebugEvent"); ContinueDebugEvent(event.dwProcessId, event.dwThreadId, DBG_EXCEPTION_NOT_HANDLED); running = true; } if(ts.Elapsed() > 200) { DR_LOG("ts.Elpsed() > 200"); if(!lock) { Lock(); locked = true; } if(!frestored) { RestoreForeground(); frestored = true; } } if(lock) { DR_LOG("GuiSleep"); GuiSleep(opn < 1000 ? 0 : 100); Ctrl::ProcessEvents(); } else { DR_LOG("Sleep"); Sleep(opn < 1000 ? 0 : 100); } } }