void dbg_del_process(struct dbg_process* p) { int i; while (p->threads) dbg_del_thread(p->threads); for (i = 0; i < p->num_delayed_bp; i++) if (p->delayed_bp[i].is_symbol) HeapFree(GetProcessHeap(), 0, p->delayed_bp[i].u.symbol.name); HeapFree(GetProcessHeap(), 0, p->delayed_bp); if (p->prev) p->prev->next = p->next; if (p->next) p->next->prev = p->prev; if (p == dbg_process_list) dbg_process_list = p->next; if (p == dbg_curr_process) dbg_curr_process = NULL; HeapFree(GetProcessHeap(), 0, (char*)p->imageName); HeapFree(GetProcessHeap(), 0, p); }
void dbg_del_process(struct dbg_process* p) { struct dbg_thread* t; struct dbg_thread* t2; int i; LIST_FOR_EACH_ENTRY_SAFE(t, t2, &p->threads, struct dbg_thread, entry) dbg_del_thread(t); for (i = 0; i < p->num_delayed_bp; i++) if (p->delayed_bp[i].is_symbol) HeapFree(GetProcessHeap(), 0, p->delayed_bp[i].u.symbol.name); HeapFree(GetProcessHeap(), 0, p->delayed_bp); source_nuke_path(p); source_free_files(p); list_remove(&p->entry); if (p == dbg_curr_process) dbg_curr_process = NULL; HeapFree(GetProcessHeap(), 0, (char*)p->imageName); HeapFree(GetProcessHeap(), 0, p); }
static unsigned dbg_handle_debug_event(DEBUG_EVENT* de) { union { char bufferA[256]; WCHAR buffer[256]; } u; DWORD cont = DBG_CONTINUE; dbg_curr_pid = de->dwProcessId; dbg_curr_tid = de->dwThreadId; if ((dbg_curr_process = dbg_get_process(de->dwProcessId)) != NULL) dbg_curr_thread = dbg_get_thread(dbg_curr_process, de->dwThreadId); else dbg_curr_thread = NULL; switch (de->dwDebugEventCode) { case EXCEPTION_DEBUG_EVENT: if (!dbg_curr_thread) { WINE_ERR("%04x:%04x: not a registered process or thread (perhaps a 16 bit one ?)\n", de->dwProcessId, de->dwThreadId); break; } WINE_TRACE("%04x:%04x: exception code=%08x\n", de->dwProcessId, de->dwThreadId, de->u.Exception.ExceptionRecord.ExceptionCode); if (dbg_curr_process->continue_on_first_exception) { dbg_curr_process->continue_on_first_exception = FALSE; if (!DBG_IVAR(BreakOnAttach)) break; } if (dbg_fetch_context()) { cont = dbg_handle_exception(&de->u.Exception.ExceptionRecord, de->u.Exception.dwFirstChance); if (cont && dbg_curr_thread) { SetThreadContext(dbg_curr_thread->handle, &dbg_context); } } break; case CREATE_PROCESS_DEBUG_EVENT: dbg_curr_process = dbg_add_process(&be_process_active_io, de->dwProcessId, de->u.CreateProcessInfo.hProcess); if (dbg_curr_process == NULL) { WINE_ERR("Couldn't create process\n"); break; } fetch_module_name(de->u.CreateProcessInfo.lpImageName, de->u.CreateProcessInfo.fUnicode, de->u.CreateProcessInfo.lpBaseOfImage, u.buffer, sizeof(u.buffer) / sizeof(WCHAR), TRUE); WINE_TRACE("%04x:%04x: create process '%s'/%p @%p (%u<%u>)\n", de->dwProcessId, de->dwThreadId, wine_dbgstr_w(u.buffer), de->u.CreateProcessInfo.lpImageName, de->u.CreateProcessInfo.lpStartAddress, de->u.CreateProcessInfo.dwDebugInfoFileOffset, de->u.CreateProcessInfo.nDebugInfoSize); dbg_set_process_name(dbg_curr_process, u.buffer); if (!dbg_init(dbg_curr_process->handle, u.buffer, FALSE)) dbg_printf("Couldn't initiate DbgHelp\n"); if (!dbg_load_module(dbg_curr_process->handle, de->u.CreateProcessInfo.hFile, u.buffer, (DWORD_PTR)de->u.CreateProcessInfo.lpBaseOfImage, 0)) dbg_printf("couldn't load main module (%u)\n", GetLastError()); WINE_TRACE("%04x:%04x: create thread I @%p\n", de->dwProcessId, de->dwThreadId, de->u.CreateProcessInfo.lpStartAddress); dbg_curr_thread = dbg_add_thread(dbg_curr_process, de->dwThreadId, de->u.CreateProcessInfo.hThread, de->u.CreateProcessInfo.lpThreadLocalBase); if (!dbg_curr_thread) { WINE_ERR("Couldn't create thread\n"); break; } dbg_init_current_process(); dbg_init_current_thread(de->u.CreateProcessInfo.lpStartAddress); break; case EXIT_PROCESS_DEBUG_EVENT: WINE_TRACE("%04x:%04x: exit process (%d)\n", de->dwProcessId, de->dwThreadId, de->u.ExitProcess.dwExitCode); if (dbg_curr_process == NULL) { WINE_ERR("Unknown process\n"); break; } tgt_process_active_close_process(dbg_curr_process, FALSE); dbg_printf("Process of pid=%04x has terminated\n", de->dwProcessId); break; case CREATE_THREAD_DEBUG_EVENT: WINE_TRACE("%04x:%04x: create thread D @%p\n", de->dwProcessId, de->dwThreadId, de->u.CreateThread.lpStartAddress); if (dbg_curr_process == NULL) { WINE_ERR("Unknown process\n"); break; } if (dbg_get_thread(dbg_curr_process, de->dwThreadId) != NULL) { WINE_TRACE("Thread already listed, skipping\n"); break; } dbg_curr_thread = dbg_add_thread(dbg_curr_process, de->dwThreadId, de->u.CreateThread.hThread, de->u.CreateThread.lpThreadLocalBase); if (!dbg_curr_thread) { WINE_ERR("Couldn't create thread\n"); break; } dbg_init_current_thread(de->u.CreateThread.lpStartAddress); break; case EXIT_THREAD_DEBUG_EVENT: WINE_TRACE("%04x:%04x: exit thread (%d)\n", de->dwProcessId, de->dwThreadId, de->u.ExitThread.dwExitCode); if (dbg_curr_thread == NULL) { WINE_ERR("Unknown thread\n"); break; } /* FIXME: remove break point set on thread startup */ dbg_del_thread(dbg_curr_thread); break; case LOAD_DLL_DEBUG_EVENT: if (dbg_curr_thread == NULL) { WINE_ERR("Unknown thread\n"); break; } fetch_module_name(de->u.LoadDll.lpImageName, de->u.LoadDll.fUnicode, de->u.LoadDll.lpBaseOfDll, u.buffer, sizeof(u.buffer) / sizeof(WCHAR), FALSE); WINE_TRACE("%04x:%04x: loads DLL %s @%p (%u<%u>)\n", de->dwProcessId, de->dwThreadId, wine_dbgstr_w(u.buffer), de->u.LoadDll.lpBaseOfDll, de->u.LoadDll.dwDebugInfoFileOffset, de->u.LoadDll.nDebugInfoSize); dbg_load_module(dbg_curr_process->handle, de->u.LoadDll.hFile, u.buffer, (DWORD_PTR)de->u.LoadDll.lpBaseOfDll, 0); break_set_xpoints(FALSE); break_check_delayed_bp(); break_set_xpoints(TRUE); if (DBG_IVAR(BreakOnDllLoad)) { dbg_printf("Stopping on DLL %s loading at 0x%08lx\n", dbg_W2A(u.buffer, -1), (unsigned long)de->u.LoadDll.lpBaseOfDll); if (dbg_fetch_context()) cont = 0; } break; case UNLOAD_DLL_DEBUG_EVENT: WINE_TRACE("%04x:%04x: unload DLL @%p\n", de->dwProcessId, de->dwThreadId, de->u.UnloadDll.lpBaseOfDll); break_delete_xpoints_from_module((unsigned long)de->u.UnloadDll.lpBaseOfDll); SymUnloadModule(dbg_curr_process->handle, (unsigned long)de->u.UnloadDll.lpBaseOfDll); break; case OUTPUT_DEBUG_STRING_EVENT: if (dbg_curr_thread == NULL) { WINE_ERR("Unknown thread\n"); break; } memory_get_string(dbg_curr_process, de->u.DebugString.lpDebugStringData, TRUE, de->u.DebugString.fUnicode, u.bufferA, sizeof(u.bufferA)); WINE_TRACE("%04x:%04x: output debug string (%s)\n", de->dwProcessId, de->dwThreadId, u.bufferA); break; case RIP_EVENT: WINE_TRACE("%04x:%04x: rip error=%u type=%u\n", de->dwProcessId, de->dwThreadId, de->u.RipInfo.dwError, de->u.RipInfo.dwType); break; default: WINE_TRACE("%04x:%04x: unknown event (%x)\n", de->dwProcessId, de->dwThreadId, de->dwDebugEventCode); } if (!cont) return TRUE; /* stop execution */ ContinueDebugEvent(de->dwProcessId, de->dwThreadId, cont); return FALSE; /* continue execution */ }