I've just hacked winedbg 'display' handling. It now allows for temporary disabling of displays and restricting them to one function. Look for yourselves, comments welcome. :)
Patch follows, -- Michal Miroslaw
index: programs/winedbg/Makefile.in =================================================================== RCS file: /home/wine/wine/programs/winedbg/Makefile.in,v retrieving revision 1.2 diff -u -r1.2 Makefile.in --- programs/winedbg/Makefile.in 15 Dec 2002 01:19:53 -0000 1.2 +++ programs/winedbg/Makefile.in 16 Apr 2003 03:04:56 -0000 @@ -31,6 +31,8 @@
@MAKE_PROG_RULES@
+DEFS += -DYYERROR_VERBOSE + y.tab.c y.tab.h: dbg.y $(YACC) -d -t $(SRCDIR)/dbg.y
Index: programs/winedbg/dbg.y =================================================================== RCS file: /home/wine/wine/programs/winedbg/dbg.y,v retrieving revision 1.9 diff -u -r1.9 dbg.y --- programs/winedbg/dbg.y 1 Apr 2003 00:12:50 -0000 1.9 +++ programs/winedbg/dbg.y 16 Apr 2003 03:04:56 -0000 @@ -52,8 +52,6 @@
%token tCONT tPASS tSTEP tLIST tNEXT tQUIT tHELP tBACKTRACE tINFO tWALK tUP tDOWN %token tENABLE tDISABLE tBREAK tWATCH tDELETE tSET tMODE tPRINT tEXAM tABORT tVM86 -%token tCLASS tMAPS tMODULE tSTACK tSEGMENTS tSYMBOL tREGS tWND tLOCAL tEXCEPTION -%token tPROCESS tTHREAD tEOL tEOF %token tCLASS tMAPS tMODULE tSTACK tSEGMENTS tSYMBOL tREGS tWND tQUEUE tLOCAL tEXCEPTION %token tPROCESS tTHREAD tMODREF tEOL tEOF %token tFRAME tSHARE tCOND tDISPLAY tUNDISPLAY tDISASSEMBLE @@ -137,13 +135,6 @@ | tSHOW tDIR tEOL { DEBUG_ShowDir(); } | tDIR pathname tEOL { DEBUG_AddPath( $2 ); } | tDIR tEOL { DEBUG_NukePath(); } - | tDISPLAY tEOL { DEBUG_InfoDisplay(); } - | tDISPLAY expr tEOL { DEBUG_AddDisplay($2, 1, 0); } - | tDISPLAY tFORMAT expr tEOL{ DEBUG_AddDisplay($3, $2 >> 8, $2 & 0xff); } - | tDELETE tDISPLAY tNUM tEOL{ DEBUG_DelDisplay( $3 ); } - | tDELETE tDISPLAY tEOL { DEBUG_DelDisplay( -1 ); } - | tUNDISPLAY tNUM tEOL { DEBUG_DelDisplay( $2 ); } - | tUNDISPLAY tEOL { DEBUG_DelDisplay( -1 ); } | tCOND tNUM tEOL { DEBUG_AddBPCondition($2, NULL); } | tCOND tNUM expr tEOL { DEBUG_AddBPCondition($2, $3); } | tSOURCE pathname tEOL { DEBUG_Parser($2); } @@ -154,6 +145,7 @@ | tDETACH tEOL { return DEBUG_Detach(); /* FIXME: we shouldn't return, but since we cannot simply clean the symbol table, exit debugger for now */ } | list_command | disassemble_command + | display_command | set_command | x_command | print_command @@ -163,6 +155,22 @@ | walk_command | run_command | noprocess_state + ; + +display_command: + | tDISPLAY tEOL { DEBUG_InfoDisplay(); } + | tDISPLAY expr tEOL { DEBUG_AddDisplay($2, 1, 0, FALSE); } + | tDISPLAY tFORMAT expr tEOL{ DEBUG_AddDisplay($3, $2 >> 8, $2 & 0xff, FALSE); } + | tDISPLAY tLOCAL expr tEOL { DEBUG_AddDisplay($3, 1, 0, TRUE); } + | tDISPLAY tLOCAL tFORMAT expr tEOL { DEBUG_AddDisplay($4, $3 >> 8, $3 & 0xff, TRUE); } + | tDISPLAY tDELETE tNUM tEOL{ DEBUG_DelDisplay( $3 ); } + | tDISPLAY tDELETE tEOL { DEBUG_DelDisplay( -1 ); } + | tDISPLAY tENABLE tNUM tEOL{ DEBUG_EnableDisplay( $3, TRUE ); } + | tDISPLAY tDISABLE tNUM tEOL { DEBUG_EnableDisplay( $3, FALSE ); } + | tDELETE tDISPLAY tNUM tEOL{ DEBUG_DelDisplay( $3 ); } + | tDELETE tDISPLAY tEOL { DEBUG_DelDisplay( -1 ); } + | tUNDISPLAY tNUM tEOL { DEBUG_DelDisplay( $2 ); } + | tUNDISPLAY tEOL { DEBUG_DelDisplay( -1 ); } ;
set_command: Index: programs/winedbg/debug.l =================================================================== RCS file: /home/wine/wine/programs/winedbg/debug.l,v retrieving revision 1.3 diff -u -r1.3 debug.l --- programs/winedbg/debug.l 30 Jan 2003 00:24:18 -0000 1.3 +++ programs/winedbg/debug.l 16 Apr 2003 03:04:56 -0000 @@ -58,6 +58,7 @@ %s WALK_CMD %s SHOW_CMD %s MODE_CMD +%s DISP_CMD %s NOCMD
%x ASTRING_EXPECTED @@ -86,12 +87,12 @@ "0x"{HEXDIGIT}+ { sscanf(yytext, "%x", &yylval.integer); return tNUM; } {DIGIT}+ { sscanf(yytext, "%d", &yylval.integer); return tNUM; }
-<FORMAT_EXPECTED>"/"{DIGIT}+{FORMAT} { char* last; +<DISP_CMD,FORMAT_EXPECTED>"/"{DIGIT}+{FORMAT} { char* last; yylval.integer = strtol( yytext+1, &last, 0 ) << 8; yylval.integer |= *last; return tFORMAT; }
-<FORMAT_EXPECTED>"/"{FORMAT} { yylval.integer = (1 << 8) | yytext[1]; return tFORMAT; } +<DISP_CMD,FORMAT_EXPECTED>"/"{FORMAT} { yylval.integer = (1 << 8) | yytext[1]; return tFORMAT; }
{STRING} { yylval.string = DEBUG_MakeSymbol(yytext); return tSTRING; } <ASTRING_EXPECTED>[^\n]+ { char* p = yytext; while (*p == ' ' || *p == '\t') p++; @@ -105,7 +106,7 @@ <INITIAL>enable|enabl|enab|ena { BEGIN(NOCMD); return tENABLE;} <INITIAL>disable|disabl|disab|disa|dis { BEGIN(NOCMD); return tDISABLE; } <INITIAL>disassemble|disassembl|disassemb|disassem|disasse|disass|disas { BEGIN(NOCMD); return tDISASSEMBLE; } -<INITIAL,INFO_CMD,DEL_CMD>display|displa|displ|disp { BEGIN(FORMAT_EXPECTED); return tDISPLAY; } +<INITIAL,INFO_CMD,DEL_CMD>display|displa|displ|disp { BEGIN(DISP_CMD); return tDISPLAY; } <INITIAL>undisplay|undispla|undispl|undisp|undis|undi|und { BEGIN(NOCMD); return tUNDISPLAY; } <INITIAL>delete|delet|dele|del { BEGIN(DEL_CMD); return tDELETE; } <INITIAL,NOPROCESS>quit|qui|qu|q { BEGIN(NOCMD); return tQUIT; } @@ -155,6 +156,11 @@ <INFO_CMD,WALK_CMD>window|windo|wind|win|wnd { return tWND; } <HELP_CMD>info|inf|in { return tINFO; } <MODE_CMD>vm86 { return tVM86; } +<DISP_CMD>local { BEGIN(FORMAT_EXPECTED); return tLOCAL; } +<DISP_CMD>delete|delet|dele|del { BEGIN(NOCMD); return tDELETE; } +<DISP_CMD>enable|enabl|enab|ena|en { BEGIN(NOCMD); return tENABLE; } +<DISP_CMD>disable|disabl|disab|disa|dis { BEGIN(NOCMD); return tDISABLE; } +
<INITIAL,SHOW_CMD>directories|directorie|directori|director|directo|direct|direc|direc|dir { BEGIN(PATH_EXPECTED); return tDIR; } Index: programs/winedbg/debugger.h =================================================================== RCS file: /home/wine/wine/programs/winedbg/debugger.h,v retrieving revision 1.9 diff -u -r1.9 debugger.h --- programs/winedbg/debugger.h 1 Apr 2003 00:02:36 -0000 1.9 +++ programs/winedbg/debugger.h 16 Apr 2003 03:04:56 -0000 @@ -327,10 +327,11 @@ extern int DEBUG_ReadLine(const char* pfx, char* buffer, int size);
/* debugger/display.c */ -extern int DEBUG_DoDisplay(void); -extern int DEBUG_AddDisplay(struct expr * exp, int count, char format); -extern int DEBUG_DelDisplay(int displaynum); -extern int DEBUG_InfoDisplay(void); +int DEBUG_DoDisplay(void); +int DEBUG_AddDisplay(struct expr * exp, int count, char format, int local_frame); +int DEBUG_DelDisplay(int displaynum); +int DEBUG_InfoDisplay(void); +int DEBUG_EnableDisplay(int displaynum, int enable);
/* debugger/expr.c */ extern void DEBUG_FreeExprMem(void); @@ -386,6 +387,7 @@ struct datatype * type); extern BOOL DEBUG_Normalize(struct name_hash * nh ); void DEBUG_InfoSymbols(const char* str); +const char *DEBUG_GetSymbolName(const struct name_hash *);
/* debugger/info.c */ extern void DEBUG_PrintBasic( const DBG_VALUE* value, int count, char format ); Index: programs/winedbg/display.c =================================================================== RCS file: /home/wine/wine/programs/winedbg/display.c,v retrieving revision 1.1 diff -u -r1.1 display.c --- programs/winedbg/display.c 13 Sep 2002 17:54:28 -0000 1.1 +++ programs/winedbg/display.c 16 Apr 2003 03:04:56 -0000 @@ -2,6 +2,7 @@ * File display.c - display handling for Wine internal debugger. * * Copyright (C) 1997, Eric Youngdale. + * Improved a bit by Michał Mirosław. * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -27,130 +28,172 @@
#include <stdarg.h>
-#define MAX_DISPLAY 25 +#define DISPTAB_DELTA 8 /* needs to be power of 2, search for MARK to see why :) */
-struct display -{ - struct expr * exp; - int count; - char format; +struct display { + struct expr *exp; + int count; + char format; + char enabled; + struct name_hash *frame_name; };
-static struct display displaypoints[MAX_DISPLAY]; +static struct display *displaypoints = NULL; +static unsigned int maxdisplays = 0, ndisplays = 0;
-int -DEBUG_AddDisplay(struct expr * exp, int count, char format) +static struct name_hash *DEBUG_GetCurrentFrameName(void) { - int i; + struct name_hash *name; + unsigned int eip, ebp;
- /* - * First find a slot where we can store this display. - */ - for(i=0; i < MAX_DISPLAY; i++ ) - { - if( displaypoints[i].exp == NULL ) - { - displaypoints[i].exp = DEBUG_CloneExpr(exp); - displaypoints[i].count = count; - displaypoints[i].format = format; - break; - } - } - - return TRUE; -} - -int -DEBUG_InfoDisplay(void) -{ - int i; - - /* - * First find a slot where we can store this display. - */ - for(i=0; i < MAX_DISPLAY; i++ ) - { - if( displaypoints[i].exp != NULL ) - { - DEBUG_Printf(DBG_CHN_MESG, "%d : ", i+1); - DEBUG_DisplayExpr(displaypoints[i].exp); - DEBUG_Printf(DBG_CHN_MESG, "\n"); - } - } - - return TRUE; -} - -int -DEBUG_DoDisplay(void) -{ - DBG_VALUE value; - int i; - - /* - * First find a slot where we can store this display. - */ - for(i=0; i < MAX_DISPLAY; i++ ) - { - if( displaypoints[i].exp != NULL ) - { - value = DEBUG_EvalExpr(displaypoints[i].exp); - if( value.type == NULL ) - { - DEBUG_Printf(DBG_CHN_MESG, "Unable to evaluate expression "); - DEBUG_DisplayExpr(displaypoints[i].exp); - DEBUG_Printf(DBG_CHN_MESG, "\nDisabling...\n"); - DEBUG_DelDisplay(i); - } - else - { - DEBUG_Printf(DBG_CHN_MESG, "%d : ", i + 1); - DEBUG_DisplayExpr(displaypoints[i].exp); - DEBUG_Printf(DBG_CHN_MESG, " = "); - if( displaypoints[i].format == 'i' ) - { - DEBUG_ExamineMemory( &value, - displaypoints[i].count, - displaypoints[i].format); - } - else - { - DEBUG_Print( &value, - displaypoints[i].count, - displaypoints[i].format, 0); + if (DEBUG_GetCurrentFrame(&name, &eip, &ebp)) + return name; + return NULL; +} + +int DEBUG_AddDisplay(struct expr *exp, int count, char format, int in_frame) +{ + int i; + + for (i = 0; i < ndisplays; i++) + if (displaypoints[i].exp == NULL) + break; + + if (i == maxdisplays) /* no space left - expand */ + displaypoints = DBG_realloc(displaypoints, + (maxdisplays += DISPTAB_DELTA) * sizeof(*displaypoints)); + + if (i == ndisplays) + ++ndisplays; + + displaypoints[i].exp = DEBUG_CloneExpr(exp); + displaypoints[i].count = count; + displaypoints[i].format = format; + displaypoints[i].enabled = TRUE; + displaypoints[i].frame_name = + (in_frame ? DEBUG_GetCurrentFrameName() : NULL); + + return TRUE; +} + +int DEBUG_InfoDisplay(void) +{ + int i; + + for (i = 0; i < ndisplays; i++) { + if (displaypoints[i].exp == NULL) + continue; + + if (displaypoints[i].frame_name) + DEBUG_Printf(DBG_CHN_MESG, "%d in %s%s : ", i + 1, + DEBUG_GetSymbolName(displaypoints[i].frame_name), + (displaypoints[i].enabled ? + (displaypoints[i].frame_name != DEBUG_GetCurrentFrameName() ? + " (out of scope)" : "") + : " (disabled)") + ); + else + DEBUG_Printf(DBG_CHN_MESG, "%d%s : ", i + 1, + (displaypoints[i].enabled ? "" : " (disabled)")); + DEBUG_DisplayExpr(displaypoints[i].exp); + DEBUG_Printf(DBG_CHN_MESG, "\n"); + } + + return TRUE; +} + +void DEBUG_PrintOneDisplay(int i) +{ + DBG_VALUE value; + + if (displaypoints[i].enabled) { + value = DEBUG_EvalExpr(displaypoints[i].exp); + if (value.type == NULL) { + DEBUG_Printf(DBG_CHN_MESG, "Unable to evaluate expression "); + DEBUG_DisplayExpr(displaypoints[i].exp); + DEBUG_Printf(DBG_CHN_MESG, "\nDisabling display %d ...\n", i + 1); + displaypoints[i].enabled = FALSE; + return; } - } } - }
- return TRUE; + DEBUG_Printf(DBG_CHN_MESG, "%d : ", i + 1); + DEBUG_DisplayExpr(displaypoints[i].exp); + DEBUG_Printf(DBG_CHN_MESG, " = "); + if (!displaypoints[i].enabled) + DEBUG_Printf(DBG_CHN_MESG, "(disabled)\n"); + else + if (displaypoints[i].format == 'i') + DEBUG_ExamineMemory(&value, displaypoints[i].count, displaypoints[i].format); + else + DEBUG_Print(&value, displaypoints[i].count, displaypoints[i].format, 0); }
-int -DEBUG_DelDisplay(int displaynum) -{ - int i; - - if( displaynum >= MAX_DISPLAY || displaynum == 0 || displaynum < -1 ) - { - DEBUG_Printf(DBG_CHN_MESG, "Invalid display number\n"); - return TRUE; - } - if( displaynum == -1 ) - { - for(i=0; i < MAX_DISPLAY; i++ ) - { - if( displaypoints[i].exp != NULL ) - { - DEBUG_FreeExpr(displaypoints[i].exp); - displaypoints[i].exp = NULL; - } - } - } - else if( displaypoints[displaynum - 1].exp != NULL ) - { - DEBUG_FreeExpr(displaypoints[displaynum - 1].exp); - displaypoints[displaynum - 1].exp = NULL; - } - return TRUE; +int DEBUG_DoDisplay(void) +{ + int i; + struct name_hash *cur_frame_name = DEBUG_GetCurrentFrameName(); + + for (i = 0; i < ndisplays; i++) { + if (displaypoints[i].exp == NULL || !displaypoints[i].enabled) + continue; + if (displaypoints[i].frame_name + && displaypoints[i].frame_name != cur_frame_name) + continue; + DEBUG_PrintOneDisplay(i); + } + + return TRUE; +} + +int DEBUG_DelDisplay(int displaynum) +{ + int i; + + if (displaynum > ndisplays || displaynum == 0 || displaynum < -1 + || displaypoints[displaynum - 1].exp == NULL) { + DEBUG_Printf(DBG_CHN_MESG, "Invalid display number\n"); + return TRUE; + } + + if (displaynum == -1) { + for (i = 0; i < ndisplays; i++) { + if (displaypoints[i].exp != NULL) { + DEBUG_FreeExpr(displaypoints[i].exp); + displaypoints[i].exp = NULL; + } + } + displaypoints = DBG_realloc(displaypoints, + (maxdisplays = DISPTAB_DELTA) * sizeof(*displaypoints)); + ndisplays = 0; + } else if (displaypoints[--displaynum].exp != NULL) { + DEBUG_FreeExpr(displaypoints[displaynum].exp); + displaypoints[displaynum].exp = NULL; + while (displaynum == ndisplays - 1 + && displaypoints[displaynum].exp == NULL) + --ndisplays, --displaynum; + if (maxdisplays - ndisplays >= 2 * DISPTAB_DELTA) { + maxdisplays = (ndisplays + DISPTAB_DELTA - 1) & ~(DISPTAB_DELTA - 1); /* MARK */ + displaypoints = DBG_realloc(displaypoints, + maxdisplays * sizeof(*displaypoints)); + } + } + return TRUE; } + +int DEBUG_EnableDisplay(int displaynum, int enable) +{ + --displaynum; + if (displaynum >= ndisplays || displaynum < 0 || displaypoints[displaynum].exp == NULL) { + DEBUG_Printf(DBG_CHN_MESG, "Invalid display number\n"); + return TRUE; + } + + displaypoints[displaynum].enabled = enable; + if (!displaypoints[displaynum].frame_name + || displaypoints[displaynum].frame_name == DEBUG_GetCurrentFrameName()) + DEBUG_PrintOneDisplay(displaynum); + + return TRUE; +} + Index: programs/winedbg/hash.c =================================================================== RCS file: /home/wine/wine/programs/winedbg/hash.c,v retrieving revision 1.7 diff -u -r1.7 hash.c --- programs/winedbg/hash.c 19 Feb 2003 03:41:48 -0000 1.7 +++ programs/winedbg/hash.c 16 Apr 2003 03:04:57 -0000 @@ -1314,6 +1314,11 @@ return TRUE; }
+const char *DEBUG_GetSymbolName(const struct name_hash * sym) +{ + return sym->name; +} + #ifdef HAVE_REGEX_H
static int cmp_sym_by_name(const void * p1, const void * p2) Index: programs/winedbg/info.c =================================================================== RCS file: /home/wine/wine/programs/winedbg/info.c,v retrieving revision 1.5 diff -u -r1.5 info.c --- programs/winedbg/info.c 14 Feb 2003 19:22:48 -0000 1.5 +++ programs/winedbg/info.c 16 Apr 2003 03:04:57 -0000 @@ -214,6 +214,8 @@ " stepi [N] nexti [N]", " x <addr> print <expr>", " display <expr> undisplay <disnum>", +" display local <expr> display delete <disnum>", +" display enable <disnum> display disable <disnum>", " delete display <disnum> pass", " bt frame <n>", " up down",