BOOL WindowsDebugger::debuger_pause_execution() { if( this->hProcess == NULL ) return FALSE; return DebugBreakProcess( this->hProcess ); }
/* Send an interrupt request to the inferior process. */ static void win32_request_interrupt (void) { winapi_DebugBreakProcess DebugBreakProcess; winapi_GenerateConsoleCtrlEvent GenerateConsoleCtrlEvent; #ifdef _WIN32_WCE HMODULE dll = GetModuleHandle (_T("COREDLL.DLL")); #else HMODULE dll = GetModuleHandle (_T("KERNEL32.DLL")); #endif GenerateConsoleCtrlEvent = GETPROCADDRESS (dll, GenerateConsoleCtrlEvent); if (GenerateConsoleCtrlEvent != NULL && GenerateConsoleCtrlEvent (CTRL_BREAK_EVENT, current_process_id)) return; /* GenerateConsoleCtrlEvent can fail if process id being debugged is not a process group id. Fallback to XP/Vista 'DebugBreakProcess', which generates a breakpoint exception in the interior process. */ DebugBreakProcess = GETPROCADDRESS (dll, DebugBreakProcess); if (DebugBreakProcess != NULL && DebugBreakProcess (current_process_handle)) return; /* Last resort, suspend all threads manually. */ soft_interrupt_requested = 1; }
void Debugger::breakAtCurrentPosition() { if (!m_hDebuggeeProcess) return; if (!DebugBreakProcess(m_hDebuggeeProcess)) qWarning("DebugBreakProcess failed."); }
ErrorCode Process::interrupt() { BOOL result = DebugBreakProcess(_handle); if (!result) return Platform::TranslateError(); return kSuccess; }
bool CoreEngine::debugBreakProcess(HANDLE hProcess, QString *errorMessage) { const bool rc = DebugBreakProcess(hProcess); if (!rc) *errorMessage = QString::fromLatin1("DebugBreakProcess failed: %1").arg(Utils::winErrorMessage(GetLastError())); return rc; }
HL_API bool hl_debug_breakpoint( int pid ) { # if defined(HL_WIN) return (bool)DebugBreakProcess(OpenPID(pid)); # elif defined(USE_PTRACE) return kill(pid,SIGTRAP) == 0; # else return false; # endif }
BOOL dbg_interrupt_debuggee(void) { if (!dbg_process_list) return FALSE; /* FIXME: since we likely have a single process, signal the first process * in list */ if (dbg_process_list->next) dbg_printf("Ctrl-C: only stopping the first process\n"); else dbg_printf("Ctrl-C: stopping debuggee\n"); dbg_process_list->continue_on_first_exception = FALSE; return DebugBreakProcess(dbg_process_list->handle); }
BOOL dbg_interrupt_debuggee(void) { struct dbg_process* p; if (list_empty(&dbg_process_list)) return FALSE; /* FIXME: since we likely have a single process, signal the first process * in list */ p = LIST_ENTRY(list_head(&dbg_process_list), struct dbg_process, entry); if (list_next(&dbg_process_list, &p->entry)) dbg_printf("Ctrl-C: only stopping the first process\n"); else dbg_printf("Ctrl-C: stopping debuggee\n"); p->continue_on_first_exception = FALSE; return DebugBreakProcess(p->handle); }
/** * Process session request * * This service implements the OS independent API for sending requests to the environment. * This session is Windows specific and so will call the operating system. The NDBG executive * session manager would send requests over PIPE to NDBG executive debugger server instead. * * \param request Session request * \param session Debug session * \param addr Optional data address * \param data Optional data buffer * \param size Optional data buffer size * \ret The number of bytes read or written OR TRUE on success, FALSE on failure depending on request * */ unsigned long DbgProcessRequest (IN dbgProcessReq request, IN dbgSession* session, IN OPT void* addr, IN OUT OPT void* data, IN OPT size_t size) { switch(request) { case DBG_REQ_READ: { unsigned long bytesRead = 0; ReadProcessMemory ((HANDLE)session->process.process,(LPCVOID) addr,data,size, &bytesRead); if (bytesRead==0) DbgDisplayError("Unable to read process memory. Error code: 0x%x", GetLastError()); return bytesRead; } case DBG_REQ_WRITE: { unsigned long bytesRead = 0; WriteProcessMemory ((HANDLE)session->process.process,(LPCVOID) addr,data,size, &bytesRead); if (bytesRead==0) DbgDisplayError("Unable to write process memory. Error code: 0x%x", GetLastError()); return bytesRead; } case DBG_REQ_GETCONTEXT: { CONTEXT context; context.ContextFlags = CONTEXT_ALL; if (! GetThreadContext ((HANDLE)session->process.thread, &context)) return FALSE; DbgContextFromWin32 (&context, (dbgContext*)data); return TRUE; } case DBG_REQ_SETCONTEXT: { return SetThreadContext ((HANDLE)session->process.thread, (LPCONTEXT)data); } case DBG_REQ_CONTINUE: { if (ResumeThread ((HANDLE)session->process.thread) == -1) return FALSE; return TRUE; } case DBG_REQ_BREAK: { return DebugBreakProcess ((HANDLE)session->process.process); } case DBG_REQ_STOP: default: printf ("\nDBG_REQ_STOP Not implemented"); return 0; }; }
bool raise(unsigned long int pid) { bool ok = false; HANDLE inferior = NULL; do { const DWORD rights = PROCESS_QUERY_INFORMATION|PROCESS_SET_INFORMATION |PROCESS_VM_OPERATION|PROCESS_VM_WRITE|PROCESS_VM_READ |PROCESS_DUP_HANDLE|PROCESS_TERMINATE|PROCESS_CREATE_THREAD|PROCESS_SUSPEND_RESUME ; inferior = OpenProcess(rights, FALSE, pid); if (inferior == NULL) { printf("Inferior is NULL\n"); break; } if (!DebugBreakProcess(inferior)) { printf("DebugBreakProcess failed: %s\n", GetLastError()); break; } ok = true; } while (false); if (inferior != NULL) CloseHandle(inferior); return ok; }
// Open the process and break into it bool winDebugBreakProcess(unsigned long pid, QString *errorMessage) { bool ok = false; HANDLE inferior = NULL; do { const DWORD rights = PROCESS_QUERY_INFORMATION|PROCESS_SET_INFORMATION |PROCESS_VM_OPERATION|PROCESS_VM_WRITE|PROCESS_VM_READ |PROCESS_DUP_HANDLE|PROCESS_TERMINATE|PROCESS_CREATE_THREAD|PROCESS_SUSPEND_RESUME ; inferior = OpenProcess(rights, FALSE, pid); if (inferior == NULL) { *errorMessage = QString::fromLatin1("Cannot open process %1: %2"). arg(pid).arg(Utils::winErrorMessage(GetLastError())); break; } if (!DebugBreakProcess(inferior)) { *errorMessage = QString::fromLatin1("DebugBreakProcess failed: %1").arg(Utils::winErrorMessage(GetLastError())); break; } ok = true; } while (false); if (inferior != NULL) CloseHandle(inferior); return ok; }
void DesktopProcessSignalOperation::interruptProcessSilently(int pid) { #ifdef Q_OS_WIN enum SpecialInterrupt { NoSpecialInterrupt, Win32Interrupt, Win64Interrupt }; bool is64BitSystem = Utils::winIs64BitSystem(); SpecialInterrupt si = NoSpecialInterrupt; if (is64BitSystem) si = Utils::winIs64BitBinary(m_debuggerCommand) ? Win64Interrupt : Win32Interrupt; /* Windows 64 bit has a 32 bit subsystem (WOW64) which makes it possible to run a 32 bit application inside a 64 bit environment. When GDB is used DebugBreakProcess must be called from the same system (32/64 bit) running the inferior. If CDB is used we could in theory break wow64 processes, but the break is actually a wow64 breakpoint. CDB is configured to ignore these breakpoints, because they also appear on module loading. Therefore we need helper executables (win(32/64)interrupt.exe) on Windows 64 bit calling DebugBreakProcess from the correct system. DebugBreak matrix for windows Api = UseDebugBreakApi Win64 = UseWin64InterruptHelper Win32 = UseWin32InterruptHelper N/A = This configuration is not possible | Windows 32bit | Windows 64bit | QtCreator 32bit | QtCreator 32bit | QtCreator 64bit | Inferior 32bit | Inferior 32bit | Inferior 64bit | Inferior 32bit | Inferior 64bit ----------|-----------------|-----------------|-----------------|-----------------|---------------- CDB 32bit | Api | Api | N/A | Win32 | N/A 64bit | N/A | Win64 | Win64 | Api | Api ----------|-----------------|-----------------|-----------------|-----------------|---------------- GDB 32bit | Api | Api | N/A | Win32 | N/A 64bit | N/A | N/A | Win64 | N/A | Api ----------|-----------------|-----------------|-----------------|-----------------|---------------- */ HANDLE inferior = NULL; do { const DWORD rights = PROCESS_QUERY_INFORMATION|PROCESS_SET_INFORMATION |PROCESS_VM_OPERATION|PROCESS_VM_WRITE|PROCESS_VM_READ |PROCESS_DUP_HANDLE|PROCESS_TERMINATE|PROCESS_CREATE_THREAD|PROCESS_SUSPEND_RESUME; inferior = OpenProcess(rights, FALSE, pid); if (inferior == NULL) { appendMsgCannotInterrupt(pid, tr("Cannot open process: %1") + Utils::winErrorMessage(GetLastError())); break; } bool creatorIs64Bit = Utils::winIs64BitBinary(qApp->applicationFilePath()); if (!is64BitSystem || si == NoSpecialInterrupt || si == Win64Interrupt && creatorIs64Bit || si == Win32Interrupt && !creatorIs64Bit) { if (!DebugBreakProcess(inferior)) { appendMsgCannotInterrupt(pid, tr("DebugBreakProcess failed:") + QLatin1Char(' ') + Utils::winErrorMessage(GetLastError())); } } else if (si == Win32Interrupt || si == Win64Interrupt) { QString executable = QCoreApplication::applicationDirPath(); executable += si == Win32Interrupt ? QLatin1String("/win32interrupt.exe") : QLatin1String("/win64interrupt.exe"); if (!QFile::exists(executable)) { appendMsgCannotInterrupt(pid, tr( "%1 does not exist. If you built Qt Creator " "yourself, check out http://qt.gitorious.org/" "qt-creator/binary-artifacts."). arg(QDir::toNativeSeparators(executable))); } switch (QProcess::execute(executable, QStringList(QString::number(pid)))) { case -2: appendMsgCannotInterrupt(pid, tr( "Cannot start %1. Check src\\tools\\win64interrupt\\win64interrupt.c " "for more information.").arg(QDir::toNativeSeparators(executable))); break; case 0: break; default: appendMsgCannotInterrupt(pid, QDir::toNativeSeparators(executable) + QLatin1Char(' ') + tr("could not break the process.")); break; } } } while (false); if (inferior != NULL) CloseHandle(inferior); #else if (pid <= 0) appendMsgCannotInterrupt(pid, tr("Invalid process id.")); else if (kill(pid, SIGINT)) appendMsgCannotInterrupt(pid, QString::fromLocal8Bit(strerror(errno))); #endif // Q_OS_WIN }
void WinDbgThread::pauseProcess() { if (m_state == ProcessRunning) DebugBreakProcess(m_pi.hProcess); }