2 * Wine debugger utility routines
4 * Copyright 1993 Eric Youngdale
5 * Copyright 1995 Alexandre Julliard
20 extern char lpstrSpyMessageIndent[]; /* from misc/spy.c */
22 /***********************************************************************
25 void DEBUG_InitWalk(void)
27 fprintf(stderr,"%-24.24s %-6.6s %-17.17s %-8.8s %s\n",
28 "HWND / WNDPTR","hQueue","Class Name", "Style", "WndProc");
29 lpstrSpyMessageIndent[0]='\0';
32 /***********************************************************************
36 void DEBUG_WndWalk(HWND hStart)
44 hStart = GetDesktopHwnd();
46 wndPtr = WIN_FindWndPtr(hStart);
49 { fprintf(stderr, "Invalid window handle: %04x\n", hStart);
52 i = strlen(lpstrSpyMessageIndent);
54 /* 0x10 bytes are always reserved at the end of lpstrSpyMessageIndent */
55 sprintf(lpstrSpyMessageIndent + i,"%04x %08x",hStart, (unsigned) wndPtr);
57 classPtr = CLASS_FindClassPtr(wndPtr->hClass);
59 GlobalGetAtomName(classPtr->atomName ,className, 0x10);
61 strcpy(className,"<BAD>");
63 fprintf(stderr,"%-24.24s %-6.4x %-17.17s %08x %04x:%04x\n",
64 lpstrSpyMessageIndent,
67 (unsigned) wndPtr->dwStyle,
68 HIWORD(wndPtr->lpfnWndProc),
69 LOWORD(wndPtr->lpfnWndProc));
71 lpstrSpyMessageIndent[i] = '\0';
73 if( wndPtr->hwndChild )
77 hStart = wndPtr->hwndChild;
78 wndPtr = WIN_FindWndPtr(hStart);
81 if( iWndIndent < SPY_MAX_INDENTLEVEL - 0x10 )
83 lpstrSpyMessageIndent[iWndIndent - 1] = ' ';
84 lpstrSpyMessageIndent[iWndIndent] = '\0';
89 DEBUG_WndWalk(hStart);
90 hStart = wndPtr->hwndNext;
91 wndPtr = WIN_FindWndPtr(hStart);
95 fprintf(stderr, "%s%s"NPFMT"\n", lpstrSpyMessageIndent,
101 if( iWndIndent < SPY_MAX_INDENTLEVEL - 0x10 )
102 lpstrSpyMessageIndent[iWndIndent] = '\0';
108 /***********************************************************************
112 void DEBUG_WndDump(HWND hWnd)
115 char* lpWndText = NULL;
117 wnd = WIN_FindWndPtr(hWnd);
120 { fprintf(stderr, "Invalid window handle: %04x\n", hWnd);
124 lpWndText = (LPSTR) USER_HEAP_LIN_ADDR( wnd->hText );
126 fprintf( stderr, "next: %12.4x\n"
132 "clientRect: %i,%i - %i,%i\n"
133 "windowRect: %i,%i - %i,%i\n"
134 "hRgnUpdate: %6.4x\n"
135 "hLastPopup: %6.4x\n"
142 "hText: %10.4x (\"%s\")\n"
144 wnd->hwndNext, wnd->hwndChild,wnd->hwndParent,
145 wnd->hwndOwner,wnd->hClass,wnd->hInstance,
146 wnd->rectClient.left, wnd->rectClient.top,
147 wnd->rectClient.right, wnd->rectClient.bottom,
148 wnd->rectWindow.left, wnd->rectWindow.top,
149 wnd->rectWindow.right, wnd->rectWindow.bottom,
150 wnd->hrgnUpdate, wnd->hwndLastActive,
151 (unsigned) wnd->dwStyle, (unsigned) wnd->dwExStyle,
152 wnd->hdce, wnd->hVScroll, wnd->hHScroll,
153 wnd->wIDmenu, wnd->hText, (lpWndText)?lpWndText:"NULL",
157 /***********************************************************************
161 void DEBUG_QueueDump(HQUEUE hQ)
165 if( !hQ || IsBadReadPtr((SEGPTR)MAKELONG( 0, GlobalHandleToSel(hQ)),
166 sizeof(MESSAGEQUEUE)) )
168 fprintf(stderr, "Invalid queue handle: "NPFMT"\n", hQ);
172 pq = (MESSAGEQUEUE*) GlobalLock( hQ );
174 fprintf(stderr,"next: %12.4x Intertask SendMessage:\n"
175 "hTask: %11.4x ----------------------\n"
176 "msgSize: %9.4x hWnd: %10.4x\n"
177 "msgCount: %8.4x msg: %11.4x\n"
178 "msgNext: %9.4x wParam: %8.4x\n"
179 "msgFree: %9.4x lParam: %8.8x\n"
180 "qSize: %11.4x lRet: %10.8x\n"
181 "wWinVer: %9.4x ISMH: %10.4x\n"
182 "paints: %10.4x hSendTask: %5.4x\n"
183 "timers: %10.4x hPrevSend: %5.4x\n"
187 pq->next, pq->hTask, pq->msgSize, pq->hWnd,
188 pq->msgCount, pq->msg, pq->nextMessage, pq->wParam,
189 pq->nextFreeMessage, (unsigned)pq->lParam, pq->queueSize,
190 (unsigned)pq->SendMessageReturn, pq->wWinVersion, pq->InSendMessageHandle,
191 pq->wPaintCount, pq->hSendingTask, pq->wTimerCount,
192 pq->hPrevSendingTask, pq->status, pq->wakeMask, pq->hCurHook);
195 /***********************************************************************
198 * Implementation of the 'print' command.
200 void DEBUG_Print( const DBG_ADDR *addr, int count, char format )
204 fprintf( stderr, "Count other than 1 is meaningless in 'print' command\n" );
208 if (addr->seg && (addr->seg != 0xffffffff))
213 fprintf( stderr, "0x%04lx:", addr->seg );
217 fprintf( stderr, "%ld:", addr->seg );
221 break; /* No segment to print */
227 break; /* Meaningless format */
234 if (addr->seg) fprintf( stderr, "0x%04lx\n", addr->off );
235 else fprintf( stderr, "0x%08lx\n", addr->off );
239 fprintf( stderr, "%ld\n", addr->off );
243 fprintf( stderr, "%d = '%c'\n",
244 (char)(addr->off & 0xff), (char)(addr->off & 0xff) );
251 fprintf( stderr, "Format specifier '%c' is meaningless in 'print' command\n", format );
257 /***********************************************************************
260 * Print an 16- or 32-bit address, with the nearest symbol if any.
262 void DEBUG_PrintAddress( const DBG_ADDR *addr, int addrlen )
264 const char *name = DEBUG_FindNearestSymbol( addr );
266 if (addr->seg) fprintf( stderr, "0x%04lx:", addr->seg );
267 if (addrlen == 16) fprintf( stderr, "0x%04lx", addr->off );
268 else fprintf( stderr, "0x%08lx", addr->off );
269 if (name) fprintf( stderr, " (%s)", name );
273 /***********************************************************************
276 * Implementation of the 'help' command.
278 void DEBUG_Help(void)
281 static const char * helptext[] =
283 "The commands accepted by the Wine debugger are a small subset",
284 "of the commands that gdb would accept. The commands currently",
286 " break [*<addr>] delete break bpnum",
287 " disable bpnum enable bpnum",
291 " mode [16,32] print <expr>",
292 " set <reg> = <expr> set *<addr> = <expr>",
293 " walk [wnd] <expr> dump [wnd, queue] <expr>",
294 " info [reg,stack,break,segments] bt",
295 " symbolfile <filename> define <identifier> <addr>",
298 "The 'x' command accepts repeat counts and formats (including 'i') in the",
299 "same way that gdb does.",
301 " The following are examples of legal expressions:",
302 " $eax $eax+0x3 0x1000 ($eip + 256) *$eax *($esp + 3)",
303 " Also, a nm format symbol table can be read from a file using the",
304 " symbolfile command. Symbols can also be defined individually with",
305 " the define command.",
310 while(helptext[i]) fprintf(stderr,"%s\n", helptext[i++]);
315 /***********************************************************************
318 * Implementation of the 'list' command.
320 void DEBUG_List( DBG_ADDR *addr, int count )
322 static DBG_ADDR lasttime = { 0xffffffff, 0 };
324 if (addr == NULL) addr = &lasttime;
325 DBG_FIX_ADDR_SEG( addr, CS_reg(DEBUG_context) );
328 DEBUG_PrintAddress( addr, dbg_mode );
329 fprintf( stderr, ": " );
330 if (!DBG_CHECK_READ_PTR( addr, 1 )) return;
331 DEBUG_Disasm( addr );
332 fprintf (stderr, "\n");