Made the winedbg an external and WineLib program.
Centralized output handling (preparation for console usage).
Fixed a few debug information reading options (stabs and sym).
Started a framework to hold debugger's internal variables.
diff --git a/debugger/winedbg.c b/debugger/winedbg.c
index be37c11..0bdc6d5 100644
--- a/debugger/winedbg.c
+++ b/debugger/winedbg.c
@@ -7,7 +7,7 @@
#include <stdlib.h>
#include <stdio.h>
-#include <sys/stat.h>
+#include <string.h>
#include "debugger.h"
#include "thread.h"
@@ -16,21 +16,39 @@
#include "winuser.h"
#include "winreg.h"
-#include "debugtools.h"
-#include "options.h"
#ifdef DBG_need_heap
HANDLE dbg_heap = 0;
#endif
-DEFAULT_DEBUG_CHANNEL(winedbg);
-
DBG_PROCESS* DEBUG_CurrProcess = NULL;
DBG_THREAD* DEBUG_CurrThread = NULL;
CONTEXT DEBUG_context;
static DBG_PROCESS* proc = NULL;
-static BOOL bBreakAllThreads = FALSE;
+
+/* build internal vars table */
+#define INTERNAL_VAR(_var,_val) int DBG_IVAR(_var) = _val;
+#include "intvar.h"
+#undef INTERNAL_VAR
+
+int DEBUG_Printf(int chn, const char* format, ...)
+{
+ char buf[1024];
+ va_list valist;
+
+ va_start(valist, format);
+ vsprintf(buf, format, valist);
+ va_end(valist);
+#if 0
+ if (DBG_IVAR(ChannelMask) & chn)
+ WriteFile(GetStdHandle(STD_OUTPUT_HANDLE), buf, strlen(buf), NULL, NULL);
+ if (chn == DBG_CHN_MESG) fwrite(buf, strlen(buf), 1, stderr);
+#else
+ if (DBG_IVAR(ChannelMask) & chn) fwrite(buf, strlen(buf), 1, stderr);
+#endif
+ return strlen(buf);
+}
static BOOL DEBUG_Init(void)
{
@@ -39,10 +57,12 @@
DWORD val;
DWORD count = sizeof(val);
- if (!RegOpenKeyA(HKEY_CURRENT_USER, "Software\\Wine\\WineDbg", &hkey)) {
- if (!RegQueryValueExA(hkey, "BreakAllThreadsStartup", 0, &type, (LPSTR)&val, &count)) {
- bBreakAllThreads = val;
- }
+ if (!RegOpenKey(HKEY_CURRENT_USER, "Software\\Wine\\WineDbg", &hkey)) {
+#define INTERNAL_VAR(_var,_val) \
+ if (!RegQueryValueEx(hkey, #_var, 0, &type, (LPSTR)&val, &count)) \
+ DBG_IVAR(_var) = val;
+#include "intvar.h"
+#undef INTERNAL_VAR
RegCloseKey(hkey);
}
return TRUE;
@@ -51,7 +71,7 @@
static WINE_EXCEPTION_FILTER(wine_dbg)
{
DEBUG_ExternalDebugger();
- fprintf(stderr, "\nwine_dbg: Exception %lx\n", GetExceptionCode());
+ DEBUG_Printf(DBG_CHN_MESG, "\nwine_dbg: Exception %lx\n", GetExceptionCode());
return EXCEPTION_EXECUTE_HANDLER;
}
@@ -88,7 +108,7 @@
static void DEBUG_DelProcess(DBG_PROCESS* p)
{
if (p->threads != NULL) {
- ERR("Shouldn't happen\n");
+ DEBUG_Printf(DBG_CHN_ERR, "Shouldn't happen\n");
while (p->threads) DEBUG_DelThread(p->threads);
}
if (p->prev) p->prev->next = p->next;
@@ -110,42 +130,7 @@
* Initialize the type handling stuff.
*/
DEBUG_InitTypes();
- DEBUG_InitCVDataTypes();
-
- /*
- * In some cases we can read the stabs information directly
- * from the executable. If this is the case, we don't need
- * to bother with trying to read a symbol file, as the stabs
- * also have line number and local variable information.
- * As long as gcc is used for the compiler, stabs will
- * be the default. On SVr4, DWARF could be used, but we
- * don't grok that yet, and in this case we fall back to using
- * the wine.sym file.
- */
- if( DEBUG_ReadExecutableDbgInfo() == FALSE )
- {
- char* symfilename = "wine.sym";
- struct stat statbuf;
- HKEY hWineConf, hkey;
- DWORD count;
- char symbolTableFile[256];
-
- if (-1 == stat(symfilename, &statbuf) )
- symfilename = LIBDIR "wine.sym";
-
- strcpy(symbolTableFile, symfilename);
- if (!RegOpenKeyA(HKEY_LOCAL_MACHINE, "Software\\Wine\\Wine\\Config", &hWineConf)) {
- if (!RegOpenKeyA(hWineConf, "wine", &hkey)) {
- count = sizeof(symbolTableFile);
- RegQueryValueA(hkey, "SymbolTableFile", symbolTableFile, &count);
- RegCloseKey(hkey);
- }
- RegCloseKey(hWineConf);
- }
- DEBUG_ReadSymbolTable(symbolTableFile);
- }
- DEBUG_LoadEntryPoints(NULL);
- DEBUG_ProcessDeferredDebug();
+ DEBUG_InitCVDataTypes();
}
static BOOL DEBUG_ProcessGetString(char* buffer, int size, HANDLE hp, LPSTR addr)
@@ -206,10 +191,9 @@
static void DEBUG_InitCurrThread(void)
{
- if (!Options.debug) return;
-
if (DEBUG_CurrThread->start) {
- if (DEBUG_CurrThread->process->num_threads == 1 || bBreakAllThreads) {
+ if (DEBUG_CurrThread->process->num_threads == 1 ||
+ DBG_IVAR(BreakAllThreadsStartup)) {
DBG_VALUE value;
DEBUG_SetBreakpoints(FALSE);
@@ -239,7 +223,9 @@
BOOL is_debug = FALSE;
BOOL ret;
- if (first_chance && !Options.debug && !force ) return 0; /* pass to app first */
+ /* FIXME: need for a configuration var ? */
+ /* pass to app first ??? */
+ /* if (first_chance && !force) return 0; */
switch (rec->ExceptionCode)
{
@@ -247,83 +233,80 @@
case EXCEPTION_SINGLE_STEP:
is_debug = TRUE;
break;
- case CONTROL_C_EXIT:
- if (!Options.debug) DEBUG_Exit(0);
- break;
}
if (!is_debug)
{
/* print some infos */
- fprintf( stderr, "%s: ",
- first_chance ? "First chance exception" : "Unhandled exception" );
+ DEBUG_Printf( DBG_CHN_MESG, "%s: ",
+ first_chance ? "First chance exception" : "Unhandled exception" );
switch(rec->ExceptionCode)
{
case EXCEPTION_INT_DIVIDE_BY_ZERO:
- fprintf( stderr, "divide by zero" );
+ DEBUG_Printf( DBG_CHN_MESG, "divide by zero" );
break;
case EXCEPTION_INT_OVERFLOW:
- fprintf( stderr, "overflow" );
+ DEBUG_Printf( DBG_CHN_MESG, "overflow" );
break;
case EXCEPTION_ARRAY_BOUNDS_EXCEEDED:
- fprintf( stderr, "array bounds " );
+ DEBUG_Printf( DBG_CHN_MESG, "array bounds " );
break;
case EXCEPTION_ILLEGAL_INSTRUCTION:
- fprintf( stderr, "illegal instruction" );
+ DEBUG_Printf( DBG_CHN_MESG, "illegal instruction" );
break;
case EXCEPTION_STACK_OVERFLOW:
- fprintf( stderr, "stack overflow" );
+ DEBUG_Printf( DBG_CHN_MESG, "stack overflow" );
break;
case EXCEPTION_PRIV_INSTRUCTION:
- fprintf( stderr, "priviledged instruction" );
+ DEBUG_Printf( DBG_CHN_MESG, "priviledged instruction" );
break;
case EXCEPTION_ACCESS_VIOLATION:
if (rec->NumberParameters == 2)
- fprintf( stderr, "page fault on %s access to 0x%08lx",
- rec->ExceptionInformation[0] ? "write" : "read",
- rec->ExceptionInformation[1] );
+ DEBUG_Printf( DBG_CHN_MESG, "page fault on %s access to 0x%08lx",
+ rec->ExceptionInformation[0] ? "write" : "read",
+ rec->ExceptionInformation[1] );
else
- fprintf( stderr, "page fault" );
+ DEBUG_Printf( DBG_CHN_MESG, "page fault" );
break;
case EXCEPTION_DATATYPE_MISALIGNMENT:
- fprintf( stderr, "Alignment" );
+ DEBUG_Printf( DBG_CHN_MESG, "Alignment" );
break;
case CONTROL_C_EXIT:
- fprintf( stderr, "^C" );
+ DEBUG_Printf( DBG_CHN_MESG, "^C" );
break;
case EXCEPTION_CRITICAL_SECTION_WAIT:
- fprintf( stderr, "critical section %08lx wait failed",
- rec->ExceptionInformation[0] );
+ DEBUG_Printf( DBG_CHN_MESG, "critical section %08lx wait failed",
+ rec->ExceptionInformation[0] );
break;
default:
- fprintf( stderr, "%08lx", rec->ExceptionCode );
+ DEBUG_Printf( DBG_CHN_MESG, "%08lx", rec->ExceptionCode );
break;
}
}
-#if 1
- fprintf(stderr, "Entering debugger PC=%lx EFL=%08lx mode=%d count=%d\n",
- DEBUG_context.Eip, DEBUG_context.EFlags,
- DEBUG_CurrThread->dbg_exec_mode, DEBUG_CurrThread->dbg_exec_count);
-#endif
+ DEBUG_Printf(DBG_CHN_TRACE,
+ "Entering debugger PC=%lx EFL=%08lx mode=%d count=%d\n",
+ DEBUG_context.Eip, DEBUG_context.EFlags,
+ DEBUG_CurrThread->dbg_exec_mode, DEBUG_CurrThread->dbg_exec_count);
ret = DEBUG_Main( is_debug, force, rec->ExceptionCode );
-#if 1
- fprintf(stderr, "Exiting debugger PC=%lx EFL=%08lx mode=%d count=%d\n",
- DEBUG_context.Eip, DEBUG_context.EFlags,
- DEBUG_CurrThread->dbg_exec_mode, DEBUG_CurrThread->dbg_exec_count);
-#endif
+
+ DEBUG_Printf(DBG_CHN_TRACE,
+ "Exiting debugger PC=%lx EFL=%08lx mode=%d count=%d\n",
+ DEBUG_context.Eip, DEBUG_context.EFlags,
+ DEBUG_CurrThread->dbg_exec_mode, DEBUG_CurrThread->dbg_exec_count);
return ret;
}
-static DWORD DEBUG_HandleDebugEvent(DEBUG_EVENT* de)
+static BOOL DEBUG_HandleDebugEvent(DEBUG_EVENT* de, LPDWORD cont)
{
char buffer[256];
- DWORD cont;
+ BOOL ret;
__TRY {
- cont = 0L;
+ ret = TRUE;
+ *cont = 0L;
if ((DEBUG_CurrProcess = DEBUG_GetProcess(de->dwProcessId)) != NULL)
DEBUG_CurrThread = DEBUG_GetThread(DEBUG_CurrProcess, de->dwThreadId);
@@ -332,45 +315,47 @@
switch (de->dwDebugEventCode) {
case EXCEPTION_DEBUG_EVENT:
- if (!DEBUG_CurrThread) break;
+ if (!DEBUG_CurrThread) {
+ DEBUG_Printf(DBG_CHN_ERR, "%08lx:%08lx: not a registered process or thread (perhaps a 16 bit one ?)\n",
+ de->dwProcessId, de->dwThreadId);
+ break;
+ }
- TRACE("%08lx:%08lx: exception code=%08lx %d\n",
- de->dwProcessId, de->dwThreadId,
- de->u.Exception.ExceptionRecord.ExceptionCode,
- DEBUG_CurrThread->wait_for_first_exception);
+ DEBUG_Printf(DBG_CHN_TRACE, "%08lx:%08lx: exception code=%08lx %d\n",
+ de->dwProcessId, de->dwThreadId,
+ de->u.Exception.ExceptionRecord.ExceptionCode,
+ DEBUG_CurrThread->wait_for_first_exception);
DEBUG_context.ContextFlags = CONTEXT_CONTROL|CONTEXT_INTEGER|CONTEXT_SEGMENTS|CONTEXT_DEBUG_REGISTERS;
if (!GetThreadContext(DEBUG_CurrThread->handle, &DEBUG_context)) {
- WARN("Can't get thread's context\n");
+ DEBUG_Printf(DBG_CHN_WARN, "Can't get thread's context\n");
break;
}
- TRACE("%p:%p\n", de->u.Exception.ExceptionRecord.ExceptionAddress,
- (void*)DEBUG_context.Eip);
+ DEBUG_Printf(DBG_CHN_TRACE, "%p:%p\n", de->u.Exception.ExceptionRecord.ExceptionAddress,
+ (void*)DEBUG_context.Eip);
- cont = DEBUG_HandleException(&de->u.Exception.ExceptionRecord,
- de->u.Exception.dwFirstChance,
- DEBUG_CurrThread->wait_for_first_exception);
-
- if (DEBUG_CurrThread->wait_for_first_exception) {
+ *cont = DEBUG_HandleException(&de->u.Exception.ExceptionRecord,
+ de->u.Exception.dwFirstChance,
+ DEBUG_CurrThread->wait_for_first_exception);
+ if (DEBUG_CurrThread->dbg_exec_mode == EXEC_KILL) {
+ ret = FALSE;
+ } else {
DEBUG_CurrThread->wait_for_first_exception = 0;
-#ifdef __i386__
- DEBUG_context.Eip--;
-#endif
+ SetThreadContext(DEBUG_CurrThread->handle, &DEBUG_context);
}
- SetThreadContext(DEBUG_CurrThread->handle, &DEBUG_context);
break;
case CREATE_THREAD_DEBUG_EVENT:
- TRACE("%08lx:%08lx: create thread D @%p\n", de->dwProcessId, de->dwThreadId,
- de->u.CreateThread.lpStartAddress);
+ DEBUG_Printf(DBG_CHN_TRACE, "%08lx:%08lx: create thread D @%p\n", de->dwProcessId, de->dwThreadId,
+ de->u.CreateThread.lpStartAddress);
if (DEBUG_CurrProcess == NULL) {
- ERR("Unknown process\n");
+ DEBUG_Printf(DBG_CHN_ERR, "Unknown process\n");
break;
}
if (DEBUG_GetThread(DEBUG_CurrProcess, de->dwThreadId) != NULL) {
- TRACE("Thread already listed, skipping\n");
+ DEBUG_Printf(DBG_CHN_TRACE, "Thread already listed, skipping\n");
break;
}
@@ -380,7 +365,7 @@
de->u.CreateThread.lpStartAddress,
de->u.CreateThread.lpThreadLocalBase);
if (!DEBUG_CurrThread) {
- ERR("Couldn't create thread\n");
+ DEBUG_Printf(DBG_CHN_ERR, "Couldn't create thread\n");
break;
}
DEBUG_InitCurrThread();
@@ -389,27 +374,30 @@
case CREATE_PROCESS_DEBUG_EVENT:
DEBUG_ProcessGetStringIndirect(buffer, sizeof(buffer),
de->u.CreateProcessInfo.hProcess,
- de->u.LoadDll.lpImageName);
+ de->u.CreateProcessInfo.lpImageName);
/* FIXME unicode ? de->u.CreateProcessInfo.fUnicode */
- TRACE("%08lx:%08lx: create process %s @%p\n",
- de->dwProcessId, de->dwThreadId,
- buffer,
- de->u.CreateProcessInfo.lpStartAddress);
+ DEBUG_Printf(DBG_CHN_TRACE, "%08lx:%08lx: create process %s @%p (%ld<%ld>)\n",
+ de->dwProcessId, de->dwThreadId,
+ buffer,
+ de->u.CreateProcessInfo.lpStartAddress,
+ de->u.CreateProcessInfo.dwDebugInfoFileOffset,
+ de->u.CreateProcessInfo.nDebugInfoSize);
if (DEBUG_GetProcess(de->dwProcessId) != NULL) {
- TRACE("Skipping already defined process\n");
+ DEBUG_Printf(DBG_CHN_TRACE, "Skipping already defined process\n");
break;
}
DEBUG_CurrProcess = DEBUG_AddProcess(de->dwProcessId,
de->u.CreateProcessInfo.hProcess);
if (DEBUG_CurrProcess == NULL) {
- ERR("Unknown process\n");
+ DEBUG_Printf(DBG_CHN_ERR, "Unknown process\n");
break;
}
- TRACE("%08lx:%08lx: create thread I @%p\n", de->dwProcessId, de->dwThreadId,
- de->u.CreateProcessInfo.lpStartAddress);
+ DEBUG_Printf(DBG_CHN_TRACE, "%08lx:%08lx: create thread I @%p\n",
+ de->dwProcessId, de->dwThreadId,
+ de->u.CreateProcessInfo.lpStartAddress);
DEBUG_CurrThread = DEBUG_AddThread(DEBUG_CurrProcess,
de->dwThreadId,
@@ -417,25 +405,23 @@
de->u.CreateProcessInfo.lpStartAddress,
de->u.CreateProcessInfo.lpThreadLocalBase);
if (!DEBUG_CurrThread) {
- ERR("Couldn't create thread\n");
+ DEBUG_Printf(DBG_CHN_ERR, "Couldn't create thread\n");
break;
}
DEBUG_InitCurrProcess();
DEBUG_InitCurrThread();
-#ifdef _WE_SUPPORT_THE_STAB_TYPES_USED_BY_MINGW_TOO
/* so far, process name is not set */
- DEBUG_RegisterDebugInfo((DWORD)de->u.CreateProcessInfo.lpBaseOfImage,
- "wine-exec");
-#endif
+ DEBUG_LoadModule32("<Debugged process>", de->u.CreateProcessInfo.hFile,
+ (DWORD)de->u.CreateProcessInfo.lpBaseOfImage);
break;
case EXIT_THREAD_DEBUG_EVENT:
- TRACE("%08lx:%08lx: exit thread (%ld)\n",
- de->dwProcessId, de->dwThreadId, de->u.ExitThread.dwExitCode);
+ DEBUG_Printf(DBG_CHN_TRACE, "%08lx:%08lx: exit thread (%ld)\n",
+ de->dwProcessId, de->dwThreadId, de->u.ExitThread.dwExitCode);
if (DEBUG_CurrThread == NULL) {
- ERR("Unknown thread\n");
+ DEBUG_Printf(DBG_CHN_ERR, "Unknown thread\n");
break;
}
/* FIXME: remove break point set on thread startup */
@@ -443,22 +429,24 @@
break;
case EXIT_PROCESS_DEBUG_EVENT:
- TRACE("%08lx:%08lx: exit process (%ld)\n",
- de->dwProcessId, de->dwThreadId, de->u.ExitProcess.dwExitCode);
+ DEBUG_Printf(DBG_CHN_TRACE, "%08lx:%08lx: exit process (%ld)\n",
+ de->dwProcessId, de->dwThreadId, de->u.ExitProcess.dwExitCode);
if (DEBUG_CurrProcess == NULL) {
- ERR("Unknown process\n");
+ DEBUG_Printf(DBG_CHN_ERR, "Unknown process\n");
break;
}
+ /* just in case */
+ DEBUG_SetBreakpoints(FALSE);
/* kill last thread */
DEBUG_DelThread(DEBUG_CurrProcess->threads);
- /* FIXME: remove break point set on thread startup */
DEBUG_DelProcess(DEBUG_CurrProcess);
+ ret = FALSE;
break;
case LOAD_DLL_DEBUG_EVENT:
if (DEBUG_CurrThread == NULL) {
- ERR("Unknown thread\n");
+ DEBUG_Printf(DBG_CHN_ERR, "Unknown thread\n");
break;
}
DEBUG_ProcessGetStringIndirect(buffer, sizeof(buffer),
@@ -466,20 +454,23 @@
de->u.LoadDll.lpImageName);
/* FIXME unicode: de->u.LoadDll.fUnicode */
- TRACE("%08lx:%08lx: loads DLL %s @%p\n", de->dwProcessId, de->dwThreadId,
- buffer, de->u.LoadDll.lpBaseOfDll);
- CharUpperA(buffer);
- DEBUG_LoadModule32( buffer, (DWORD)de->u.LoadDll.lpBaseOfDll);
+ DEBUG_Printf(DBG_CHN_TRACE, "%08lx:%08lx: loads DLL %s @%p (%ld<%ld>)\n",
+ de->dwProcessId, de->dwThreadId,
+ buffer, de->u.LoadDll.lpBaseOfDll,
+ de->u.LoadDll.dwDebugInfoFileOffset,
+ de->u.LoadDll.nDebugInfoSize);
+ CharUpper(buffer);
+ DEBUG_LoadModule32(buffer, de->u.LoadDll.hFile, (DWORD)de->u.LoadDll.lpBaseOfDll);
break;
case UNLOAD_DLL_DEBUG_EVENT:
- TRACE("%08lx:%08lx: unload DLL @%p\n", de->dwProcessId, de->dwThreadId,
- de->u.UnloadDll.lpBaseOfDll);
+ DEBUG_Printf(DBG_CHN_TRACE, "%08lx:%08lx: unload DLL @%p\n", de->dwProcessId, de->dwThreadId,
+ de->u.UnloadDll.lpBaseOfDll);
break;
case OUTPUT_DEBUG_STRING_EVENT:
if (DEBUG_CurrThread == NULL) {
- ERR("Unknown thread\n");
+ DEBUG_Printf(DBG_CHN_ERR, "Unknown thread\n");
break;
}
@@ -488,111 +479,119 @@
de->u.DebugString.lpDebugStringData);
/* fixme unicode de->u.DebugString.fUnicode ? */
- TRACE("%08lx:%08lx: output debug string (%s)\n",
- de->dwProcessId, de->dwThreadId,
- buffer);
+ DEBUG_Printf(DBG_CHN_TRACE, "%08lx:%08lx: output debug string (%s)\n",
+ de->dwProcessId, de->dwThreadId, buffer);
break;
case RIP_EVENT:
- TRACE("%08lx:%08lx: rip error=%ld type=%ld\n",
- de->dwProcessId, de->dwThreadId, de->u.RipInfo.dwError,
- de->u.RipInfo.dwType);
+ DEBUG_Printf(DBG_CHN_TRACE, "%08lx:%08lx: rip error=%ld type=%ld\n",
+ de->dwProcessId, de->dwThreadId, de->u.RipInfo.dwError,
+ de->u.RipInfo.dwType);
break;
default:
- TRACE("%08lx:%08lx: unknown event (%ld)\n",
- de->dwProcessId, de->dwThreadId, de->dwDebugEventCode);
+ DEBUG_Printf(DBG_CHN_TRACE, "%08lx:%08lx: unknown event (%ld)\n",
+ de->dwProcessId, de->dwThreadId, de->dwDebugEventCode);
}
} __EXCEPT(wine_dbg) {
- cont = 0;
+ *cont = 0;
+ ret = TRUE;
}
__ENDTRY;
- return cont;
+ return ret;
}
static DWORD CALLBACK DEBUG_MainLoop(DWORD pid)
{
DEBUG_EVENT de;
DWORD cont;
+ BOOL ret = TRUE;
+ DEBUG_Printf(DBG_CHN_MESG, " on pid %ld\n", pid);
+
DEBUG_Init();
- while (WaitForDebugEvent(&de, INFINITE)) {
- cont = DEBUG_HandleDebugEvent(&de);
+ while (ret && WaitForDebugEvent(&de, INFINITE)) {
+ ret = DEBUG_HandleDebugEvent(&de, &cont);
ContinueDebugEvent(de.dwProcessId, de.dwThreadId, cont);
}
- TRACE("WineDbg terminated on pid %ld\n", pid);
+ DEBUG_Printf(DBG_CHN_MESG, "WineDbg terminated on pid %ld\n", pid);
- return 0L;
+ ExitProcess(0);
}
-static DWORD CALLBACK DEBUG_StarterFromPID(LPVOID pid)
+int PASCAL WinMain(HINSTANCE hInst, HINSTANCE prev, LPSTR _cmdline, int show)
{
- TRACE("WineDbg started on pid %ld\n", (DWORD)pid);
-
- if (!DebugActiveProcess((DWORD)pid)) {
- TRACE("Can't debug process %ld: %ld\n", (DWORD)pid, GetLastError());
- return 0;
+ char* argv[5];
+ char* cmdline = strdup(_cmdline);
+ char* ptr = cmdline;
+ int instr = FALSE;
+ int argc = 0;
+
+ while ((*ptr == ' ' || *ptr == '\t') && *ptr != 0) ptr++;
+ argv[argc++] = ptr;
+ for (; *ptr; ptr++) {
+ if ((*ptr == ' ' || *ptr == '\t') && !instr) {
+ *ptr++ = 0;
+ while (*ptr == ' ' || *ptr == '\t') ptr++;
+ if (*ptr) argv[argc++] = ptr;
+ if (argc >= sizeof(argv) / sizeof(argv[0])) return 0;
+ } else if (*ptr == '"') {
+ instr = !instr;
+ }
}
- return DEBUG_MainLoop((DWORD)pid);
-}
-void DEBUG_Attach(DWORD pid)
-{
- CreateThread(NULL, 0, DEBUG_StarterFromPID, (LPVOID)pid, 0, NULL);
-}
-
-struct dsfcl {
- HANDLE hEvent;
- LPSTR lpCmdLine;
- int showWindow;
- DWORD error;
-};
-
-static DWORD CALLBACK DEBUG_StarterFromCmdLine(LPVOID p)
-{
- PROCESS_INFORMATION info;
- STARTUPINFOA startup;
- BOOL ok = TRUE;
-
- memset(&startup, 0, sizeof(startup));
- startup.cb = sizeof(startup);
- startup.dwFlags = STARTF_USESHOWWINDOW;
- startup.wShowWindow = ((struct dsfcl*)p)->showWindow;
-
- /* any value >= 32 will do, simulate a correct handle value */
- ((struct dsfcl*)p)->error = 0xFFFFFFFF;
- if (!CreateProcessA(NULL, ((struct dsfcl*)p)->lpCmdLine, NULL, NULL,
- FALSE, DEBUG_PROCESS, NULL, NULL, &startup, &info)) {
- ((struct dsfcl*)p)->error = GetLastError();
- ok = FALSE;
+#if 0
+ /* would require to change .spec with a cuiexe type */
+ /* keep it as a guiexe for now, so that Wine won't touch the Unix stdin,
+ * stdout and stderr streams
+ */
+ if (1 /*DBG_IVAR(UseXterm)*/) {
+ COORD pos;
+
+ /* This is a hack: it forces creation of an xterm, not done by default */
+ pos.x = 0; pos.y = 1;
+ SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE), pos);
}
- SetEvent(((struct dsfcl*)p)->hEvent);
- if (ok) DEBUG_MainLoop(info.dwProcessId);
+#endif
+ DEBUG_Printf(DBG_CHN_MESG, "Starting WineDbg... ");
+ if (argc == 2) {
+ DWORD pid = atoi(argv[0]);
+ HANDLE hEvent = atoi(argv[1]);
+
+ if (pid != 0 && hEvent != 0) {
+ free(cmdline);
+
+ if (!DebugActiveProcess(pid)) {
+ DEBUG_Printf(DBG_CHN_ERR, "Can't attach process %ld: %ld\n",
+ pid, GetLastError());
+ return 0;
+ }
+ SetEvent(hEvent);
+ return DEBUG_MainLoop(pid);
+ }
+ }
+ do {
+ PROCESS_INFORMATION info;
+ STARTUPINFOA startup;
+
+ free(cmdline);
+
+ memset(&startup, 0, sizeof(startup));
+ startup.cb = sizeof(startup);
+ startup.dwFlags = STARTF_USESHOWWINDOW;
+ startup.wShowWindow = SW_SHOWNORMAL;
+
+ if (CreateProcess(NULL, _cmdline, NULL, NULL,
+ FALSE, DEBUG_PROCESS, NULL, NULL, &startup, &info)) {
+ return DEBUG_MainLoop(info.dwProcessId);
+ }
+ DEBUG_Printf(DBG_CHN_MESG, "Couldn't start process '%s'\n", _cmdline);
+ } while (0);
return 0;
}
-DWORD DEBUG_WinExec(LPSTR lpCmdLine, int sw)
-{
- struct dsfcl s;
- BOOL ret;
-
- if ((s.hEvent = CreateEventA(NULL, FALSE, FALSE, NULL))) {
- s.lpCmdLine = lpCmdLine;
- s.showWindow = sw;
- if (CreateThread(NULL, 0, DEBUG_StarterFromCmdLine, (LPVOID)&s, 0, NULL)) {
- WaitForSingleObject(s.hEvent, INFINITE);
- ret = s.error;
- } else {
- ret = 3; /* (dummy) error value for non created thread */
- }
- CloseHandle(s.hEvent);
- } else {
- ret = 1; /* (dummy) error value for non created event */
- }
- return ret;
-}