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",