diff --git a/programs/winedbg/dbg.y b/programs/winedbg/dbg.y index 482e80ae0a8..b1b6ffbfe53 100644 --- a/programs/winedbg/dbg.y +++ b/programs/winedbg/dbg.y @@ -52,8 +52,6 @@ int yyerror(const char *); %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 @@ -124,9 +122,6 @@ command: | tABORT tEOL { abort(); } | tMODE tNUM tEOL { mode_command($2); } | tMODE tVM86 tEOL { DEBUG_CurrThread->dbg_mode = MODE_VM86; } - | tENABLE tNUM tEOL { DEBUG_EnableBreakpoint( $2, TRUE ); } - | tDISABLE tNUM tEOL { DEBUG_EnableBreakpoint( $2, FALSE ); } - | tDELETE tBREAK tNUM tEOL { DEBUG_DelBreakpoint( $3 ); } | tBACKTRACE tEOL { DEBUG_BackTrace(DEBUG_CurrTid, TRUE); } | tBACKTRACE tNUM tEOL { DEBUG_BackTrace($2, TRUE); } | tUP tEOL { DEBUG_SetFrame( curr_frame + 1 ); } @@ -137,13 +132,6 @@ command: | 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); } @@ -157,7 +145,8 @@ command: | set_command | x_command | print_command - | break_command + | break_commands + | display_commands | watch_command | info_command | walk_command @@ -165,6 +154,20 @@ command: | noprocess_state ; +display_commands: + | 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); } + | tLOCAL tDISPLAY expr tEOL { DEBUG_AddDisplay($3, 1, 0, TRUE); } + | tLOCAL tDISPLAY tFORMAT expr tEOL { DEBUG_AddDisplay($4, $3 >> 8, $3 & 0xff, TRUE); } + | tENABLE tDISPLAY tNUM tEOL{ DEBUG_EnableDisplay( $3, TRUE ); } + | tDISABLE tDISPLAY 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: tSET lval_addr '=' expr_value tEOL { DEBUG_WriteMemory(&$2, $4); } | tSET '+' tIDENTIFIER tEOL { DEBUG_DbgChannel(TRUE, NULL, $3); } @@ -210,12 +213,18 @@ print_command: | tPRINT tFORMAT expr_addr tEOL { DEBUG_Print( &$3, $2 >> 8, $2 & 0xff, 0 ); } ; -break_command: +break_commands: tBREAK '*' expr_addr tEOL{ DEBUG_AddBreakpointFromValue( &$3 ); } | tBREAK identifier tEOL { DEBUG_AddBreakpointFromId($2, -1); } | tBREAK identifier ':' tNUM tEOL { DEBUG_AddBreakpointFromId($2, $4); } | tBREAK tNUM tEOL { DEBUG_AddBreakpointFromLineno($2); } | tBREAK tEOL { DEBUG_AddBreakpointFromLineno(-1); } + | tENABLE tNUM tEOL { DEBUG_EnableBreakpoint( $2, TRUE ); } + | tENABLE tBREAK tNUM tEOL { DEBUG_EnableBreakpoint( $3, TRUE ); } + | tDISABLE tNUM tEOL { DEBUG_EnableBreakpoint( $2, FALSE ); } + | tDISABLE tBREAK tNUM tEOL { DEBUG_EnableBreakpoint( $3, FALSE ); } + | tDELETE tNUM tEOL { DEBUG_DelBreakpoint( $2 ); } + | tDELETE tBREAK tNUM tEOL { DEBUG_DelBreakpoint( $3 ); } ; watch_command: diff --git a/programs/winedbg/debug.l b/programs/winedbg/debug.l index 792c0825f0e..6c8a59252fd 100644 --- a/programs/winedbg/debug.l +++ b/programs/winedbg/debug.l @@ -57,7 +57,8 @@ STRING \"[^\n"]+\" %s PATH_EXPECTED %s INFO_CMD %s HELP_CMD -%s DEL_CMD +%s BD_CMD +%s LOCAL_CMD %s WALK_CMD %s SHOW_CMD %s MODE_CMD @@ -105,12 +106,14 @@ STRING \"[^\n"]+\" down|dow|do { BEGIN(NOCMD); return tDOWN; } frame|fram|fra|fr { BEGIN(NOCMD); return tFRAME; } list|lis|li|l { BEGIN(PATH_EXPECTED); return tLIST; } -enable|enabl|enab|ena { BEGIN(NOCMD); return tENABLE;} -disable|disabl|disab|disa|dis { BEGIN(NOCMD); return tDISABLE; } +enable|enabl|enab|ena { BEGIN(BD_CMD); return tENABLE;} +disable|disabl|disab|disa|dis { BEGIN(BD_CMD); return tDISABLE; } disassemble|disassembl|disassemb|disassem|disasse|disass|disas { BEGIN(NOCMD); return tDISASSEMBLE; } -display|displa|displ|disp { BEGIN(FORMAT_EXPECTED); return tDISPLAY; } +locally|local { BEGIN(LOCAL_CMD); return tLOCAL; } +display|displa|displ|disp { BEGIN(FORMAT_EXPECTED); return tDISPLAY; } +display|displa|displ|disp|dis|di|d { BEGIN(NOCMD); return tDISPLAY; } undisplay|undispla|undispl|undisp|undis|undi|und { BEGIN(NOCMD); return tUNDISPLAY; } -delete|delet|dele|del { BEGIN(DEL_CMD); return tDELETE; } +delete|delet|dele|del { BEGIN(BD_CMD); return tDELETE; } quit|qui|qu|q { BEGIN(NOCMD); return tQUIT; } set|se { BEGIN(NOCMD); return tSET; } walk|w { BEGIN(WALK_CMD); return tWALK; } @@ -137,7 +140,7 @@ STRING \"[^\n"]+\" source|sourc|sour|src { BEGIN(PATH_EXPECTED); return tSOURCE; } symbolfile|symbols|symbol|sf { BEGIN(PATH_EXPECTED); return tSYMBOLFILE; } -break|brea|bre|br|b { BEGIN(NOCMD); return tBREAK; } +break|brea|bre|br|b { BEGIN(NOCMD); return tBREAK; } watch|watc|wat { BEGIN(NOCMD); return tWATCH; } whatis|whati|what { BEGIN(NOCMD); return tWHATIS; } run|ru|r { BEGIN(ASTRING_EXPECTED); return tRUN;} diff --git a/programs/winedbg/debugger.h b/programs/winedbg/debugger.h index ef5b9c760f0..6dd3e3c31c9 100644 --- a/programs/winedbg/debugger.h +++ b/programs/winedbg/debugger.h @@ -331,9 +331,10 @@ 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_AddDisplay(struct expr * exp, int count, char format, int local_frame); extern int DEBUG_DelDisplay(int displaynum); extern int DEBUG_InfoDisplay(void); +extern int DEBUG_EnableDisplay(int displaynum, int enable); /* debugger/expr.c */ extern void DEBUG_FreeExprMem(void); @@ -389,6 +390,7 @@ extern int DEBUG_SetLocalSymbolType(struct wine_locals * sym, 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 ); diff --git a/programs/winedbg/display.c b/programs/winedbg/display.c index 3219e4eb7a4..504d545e222 100644 --- a/programs/winedbg/display.c +++ b/programs/winedbg/display.c @@ -2,6 +2,7 @@ * File display.c - display handling for Wine internal debugger. * * Copyright (C) 1997, Eric Youngdale. + * Copyright (C) 2003, Michal Miroslaw * * 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,171 @@ #include -#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 *function_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_GetCurrentFrameFunctionName(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; + if (DEBUG_GetCurrentFrame(&name, &eip, &ebp)) + return name; + return NULL; } -int -DEBUG_InfoDisplay(void) +int DEBUG_AddDisplay(struct expr *exp, int count, char format, int in_frame) { - int i; + 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"); - } - } + for (i = 0; i < ndisplays; i++) + if (displaypoints[i].exp == NULL) + break; - return TRUE; + 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].function_name = + (in_frame ? DEBUG_GetCurrentFrameFunctionName() : NULL); + + return TRUE; } -int -DEBUG_DoDisplay(void) +int DEBUG_InfoDisplay(void) { - DBG_VALUE value; - int i; + 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); + for (i = 0; i < ndisplays; i++) { + if (displaypoints[i].exp == NULL) + continue; + + if (displaypoints[i].function_name) + DEBUG_Printf(DBG_CHN_MESG, "%d in %s%s : ", i + 1, + DEBUG_GetSymbolName(displaypoints[i].function_name), + (displaypoints[i].enabled ? + (displaypoints[i].function_name != DEBUG_GetCurrentFrameFunctionName() ? + " (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; } - else - { - DEBUG_Print( &value, - displaypoints[i].count, - displaypoints[i].format, 0); - } - } } - } - 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 DEBUG_DoDisplay(void) { - int i; + int i; + struct name_hash *cur_function_name = DEBUG_GetCurrentFrameFunctionName(); - 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; - } + for (i = 0; i < ndisplays; i++) { + if (displaypoints[i].exp == NULL || !displaypoints[i].enabled) + continue; + if (displaypoints[i].function_name + && displaypoints[i].function_name != cur_function_name) + continue; + DEBUG_PrintOneDisplay(i); } - } - else if( displaypoints[displaynum - 1].exp != NULL ) - { - DEBUG_FreeExpr(displaypoints[displaynum - 1].exp); - displaypoints[displaynum - 1].exp = NULL; - } - return TRUE; + + 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].function_name + || displaypoints[displaynum].function_name == DEBUG_GetCurrentFrameFunctionName()) + DEBUG_PrintOneDisplay(displaynum); + + return TRUE; } diff --git a/programs/winedbg/hash.c b/programs/winedbg/hash.c index a37a4d6dab1..52ec5d5048b 100644 --- a/programs/winedbg/hash.c +++ b/programs/winedbg/hash.c @@ -1305,6 +1305,11 @@ int DEBUG_SetLocalSymbolType(struct wine_locals * sym, struct datatype * type) 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) diff --git a/programs/winedbg/info.c b/programs/winedbg/info.c index 277cce49bc3..fb673c38726 100644 --- a/programs/winedbg/info.c +++ b/programs/winedbg/info.c @@ -218,15 +218,16 @@ void DEBUG_Help(void) " stepi [N] nexti [N]", " x print ", " display undisplay ", -" delete display pass", +" local display delete display ", +" enable display disable display ", " bt frame ", " up down", " list disassemble [][,]", " show dir dir ", " set = set * = ", -" mode [16,32,vm86] walk [wnd,class,module,maps,", -" whatis process,thread,exception]", -" info (see 'help info' for options)", +" mode [16,32,vm86] pass", +" whatis walk [wnd,class,module,maps,", +" info (see 'help info' for options) process,thread,exception]", "The 'x' command accepts repeat counts and formats (including 'i') in the", "same way that gdb does.\n", @@ -234,8 +235,8 @@ void DEBUG_Help(void) " The following are examples of legal expressions:", " $eax $eax+0x3 0x1000 ($eip + 256) *$eax *($esp + 3)", " Also, a nm format symbol table can be read from a file using the", -" symbolfile command. Symbols can also be defined individually with", -" the define command.", +" symbolfile command.", /* Symbols can also be defined individually with", +" the define command.", */ "", NULL };