this patch extends the existing set command to turn on/off debug channels. Forms of use are: set warn+win turns on warn stream on win channel set -gdi turns off all streams on gdi channel it also reimplements the 'info maps' command. but it requires a working version of VirtualQueryEx (which isn't in the cvs tree yet) [so it won't work on vanilla wine]. I have a hack for VirtualQueryEx for Linux, but Alexandre will never accept it (but if someone needs it, I can provide it) A+
Name: dbg_chn ChangeLog: added ability to turn on/off debug channels reimplemented the info maps command License: X11 GenDate: 2002/06/01 19:06:37 UTC ModifiedFiles: debugger/dbg.y debugger/debugger.h debugger/info.c AddedFiles: =================================================================== RCS file: /home/cvs/cvsroot/wine/wine/debugger/dbg.y,v retrieving revision 1.56 diff -u -u -r1.56 dbg.y --- debugger/dbg.y 1 Jun 2002 02:55:49 -0000 1.56 +++ debugger/dbg.y 1 Jun 2002 03:24:54 -0000 @@ -173,7 +173,12 @@ | noprocess_state ; -set_command: tSET lval_addr '=' expr_value tEOL { DEBUG_WriteMemory(&$2,$4); DEBUG_FreeExprMem(); } +set_command: + tSET lval_addr '=' expr_value tEOL { DEBUG_WriteMemory(&$2,$4); DEBUG_FreeExprMem(); } + | tSET '+' tIDENTIFIER tEOL {DEBUG_DbgChannel(TRUE, NULL, $3);} + | tSET '-' tIDENTIFIER tEOL {DEBUG_DbgChannel(FALSE, NULL, $3);} + | tSET tIDENTIFIER '+' tIDENTIFIER tEOL {DEBUG_DbgChannel(TRUE, $2, $4);} + | tSET tIDENTIFIER '-' tIDENTIFIER tEOL {DEBUG_DbgChannel(FALSE, $2, $4);} ; pathname: Index: debugger/debugger.h =================================================================== RCS file: /home/cvs/cvsroot/wine/wine/debugger/debugger.h,v retrieving revision 1.33 diff -u -u -r1.33 debugger.h --- debugger/debugger.h 31 May 2002 23:06:46 -0000 1.33 +++ debugger/debugger.h 1 Jun 2002 03:24:54 -0000 @@ -404,6 +404,7 @@ extern void DEBUG_InfoVirtual(void); extern void DEBUG_InfoWindow(HWND hWnd); extern void DEBUG_WalkWindows(HWND hWnd, int indent); +extern void DEBUG_DbgChannel(BOOL add, const char* chnl, const char* name); /* debugger/memory.c */ extern int DEBUG_ReadMemory( const DBG_VALUE* value ); Index: debugger/info.c =================================================================== RCS file: /home/cvs/cvsroot/wine/wine/debugger/info.c,v retrieving revision 1.25 diff -u -u -r1.25 info.c --- debugger/info.c 31 May 2002 23:06:47 -0000 1.25 +++ debugger/info.c 1 Jun 2002 08:55:38 -0000 @@ -575,5 +575,109 @@ void DEBUG_InfoVirtual(void) { - DEBUG_Printf(DBG_CHN_MESG, "No longer providing virtual mapping information\n"); + MEMORY_BASIC_INFORMATION mbi; + char* addr = 0; + char* state; + char* type; + char prot[3+1]; + + if (DEBUG_CurrProcess == NULL) + return; + + DEBUG_Printf(DBG_CHN_MESG, "Address Size State Type RWX\n"); + + while (VirtualQueryEx(DEBUG_CurrProcess->handle, addr, &mbi, sizeof(mbi)) >= sizeof(mbi)) + { + switch (mbi.State) + { + case MEM_COMMIT: state = "commit "; break; + case MEM_FREE: state = "free "; break; + case MEM_RESERVE: state = "reserve"; break; + default: state = "??? "; break; + } + if (mbi.State != MEM_FREE) + { + switch (mbi.Type) + { + case MEM_IMAGE: type = "image "; break; + case MEM_MAPPED: type = "mapped "; break; + case MEM_PRIVATE: type = "private"; break; + case 0: type = " "; break; + default: type = "??? "; break; + } + memset(prot, ' ' , sizeof(prot)-1); + prot[sizeof(prot)-1] = '\0'; + if (mbi.AllocationProtect & (PAGE_READONLY|PAGE_READWRITE|PAGE_EXECUTE_READ|PAGE_EXECUTE_READWRITE)) + prot[0] = 'R'; + if (mbi.AllocationProtect & (PAGE_READWRITE|PAGE_EXECUTE_READWRITE)) + prot[1] = 'W'; + if (mbi.AllocationProtect & (PAGE_WRITECOPY|PAGE_EXECUTE_WRITECOPY)) + prot[1] = 'C'; + if (mbi.AllocationProtect & (PAGE_EXECUTE|PAGE_EXECUTE_READ|PAGE_EXECUTE_READWRITE)) + prot[2] = 'X'; + } + else + { + type = ""; + prot[0] = '\0'; + } + DEBUG_Printf(DBG_CHN_MESG, "%08lx %08lx %s %s %s\n", + (DWORD)addr, mbi.RegionSize, state, type, prot); + if (addr + mbi.RegionSize < addr) /* wrap around ? */ + break; + addr += mbi.RegionSize; + } } + +struct dll_option_layout +{ + void* next; + void* prev; + char* const* channels; + int nb_channels; +}; + +void DEBUG_DbgChannel(BOOL turn_on, const char* chnl, const char* name) +{ + DBG_VALUE val; + struct dll_option_layout dol; + int i; + char* str; + unsigned char buffer[32]; + unsigned char mask; + int done = 0; + BOOL bAll; + void* addr; + + if (!DEBUG_GetSymbolValue("first_dll", -1, &val, FALSE)) + { + DEBUG_Printf(DBG_CHN_MESG, "Can't get first_option symbol"); + return; + } + addr = (void*)DEBUG_ToLinear(&val.addr); + if (!chnl) mask = 15; + else if (!strcmp(chnl, "fixme")) mask = 1; + else if (!strcmp(chnl, "err")) mask = 2; + else if (!strcmp(chnl, "warn")) mask = 4; + else if (!strcmp(chnl, "trace")) mask = 8; + else { DEBUG_Printf(DBG_CHN_MESG, "Unknown channel %s\n", chnl); return; } + + bAll = !strcmp("all", name); + while (addr && DEBUG_READ_MEM(addr, &dol, sizeof(dol))) + { + for (i = 0; i < dol.nb_channels; i++) + { + if (DEBUG_READ_MEM((void*)(dol.channels + i), &str, sizeof(str)) && + DEBUG_READ_MEM(str, buffer, sizeof(buffer)) && + (!strcmp(buffer + 1, name) || bAll)) + { + if (turn_on) buffer[0] |= mask; else buffer[0] &= ~mask; + if (DEBUG_WRITE_MEM(str, buffer, 1)) done++; + } + } + addr = dol.next; + } + if (!done) DEBUG_Printf(DBG_CHN_MESG, "Unable to find debug channel %s\n", name); + else DEBUG_Printf(DBG_CHN_TRACE, "Changed %d channel instances\n", done); +} +