Fixed the parsing of id1.id2 which could be either access to field id2
of struct id1, or the identifier id2 in dll id1.
Enhanced some error reporting as well as 'info local' display layout.
Minor cosmetic changes.
diff --git a/debugger/dbg.y b/debugger/dbg.y
index 7657285..57c8012 100644
--- a/debugger/dbg.y
+++ b/debugger/dbg.y
@@ -75,7 +75,7 @@
%type <type> type_cast type_expr
%type <value> expr_addr lval_addr
%type <integer> expr_value
-%type <string> pathname
+%type <string> pathname identifier
%type <listing> list_arg
@@ -196,14 +196,14 @@
break_command:
tBREAK '*' expr_addr tEOL{ DEBUG_AddBreakpoint( &$3, NULL ); DEBUG_FreeExprMem(); }
- | tBREAK tIDENTIFIER tEOL { DEBUG_AddBreakpointFromId($2, -1); }
- | tBREAK tIDENTIFIER ':' tNUM tEOL { DEBUG_AddBreakpointFromId($2, $4); }
+ | 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); }
watch_command:
tWATCH '*' expr_addr tEOL { DEBUG_AddWatchpoint( &$3, 1 ); DEBUG_FreeExprMem(); }
- | tWATCH tIDENTIFIER tEOL { DEBUG_AddWatchpointFromId($2); }
+ | tWATCH identifier tEOL { DEBUG_AddWatchpointFromId($2); }
info_command:
tINFO tBREAK tEOL { DEBUG_InfoBreakpoints(); }
@@ -336,6 +336,12 @@
| lvalue '.' tIDENTIFIER { $$ = DEBUG_StructExpr($1, $3); }
| lvalue '[' expr ']' { $$ = DEBUG_BinopExpr(EXP_OP_ARR, $1, $3); }
+identifier:
+ tIDENTIFIER { $$ = $1; }
+ | identifier '.' tIDENTIFIER { char* ptr = DBG_alloc(strlen($1) + 1 + strlen($3)+ 1);
+ sprintf(ptr, "%s.%s", $1, $3); $$ = DEBUG_MakeSymbol(ptr);
+ DBG_free(ptr); }
+
%%
static void issue_prompt(void)
@@ -376,6 +382,9 @@
case DEBUG_STATUS_BAD_TYPE:
DEBUG_Printf(DBG_CHN_MESG, "No type or type mismatch\n");
break;
+ case DEBUG_STATUS_NO_FIELD:
+ DEBUG_Printf(DBG_CHN_MESG, "No such field in structure or union\n");
+ break;
default:
DEBUG_Printf(DBG_CHN_MESG, "Exception %lx\n", GetExceptionCode());
break;
diff --git a/debugger/debug.l b/debugger/debug.l
index 78dd6694..c4ee4d1 100644
--- a/debugger/debug.l
+++ b/debugger/debug.l
@@ -18,7 +18,6 @@
YY_FATAL_ERROR( "read() in flex scanner failed" );
static int dbg_read(char * buf, int size);
-static char * DEBUG_MakeSymbol(char *);
#endif /* DONT_USE_READLINE */
@@ -30,7 +29,7 @@
DIGIT [0-9]
HEXDIGIT [0-9a-fA-F]
FORMAT [ubcdiswx]
-IDENTIFIER [_a-zA-Z\.~][_a-zA-Z0-9\.~@]*
+IDENTIFIER [_a-zA-Z~][_a-zA-Z0-9~@]*
PATHNAME [/_a-zA-Z\.~][/_a-zA-Z0-9\.~@]*
STRING \"[^\n"]+\"
@@ -116,9 +115,9 @@
<INITIAL>show|sho|sh { BEGIN(SHOW_CMD); return tSHOW; }
<INITIAL>symbolfile|symbols|symbol|sf { BEGIN(PATH_EXPECTED); return tSYMBOLFILE; }
-<INITIAL,INFO_CMD,DEL_CMD>break|brea|bre|br|b { BEGIN(PATH_EXPECTED); return tBREAK; }
-<INITIAL>watch|watc|wat { BEGIN(PATH_EXPECTED); return tWATCH; }
-<INITIAL>whatis|whati|what { BEGIN(PATH_EXPECTED); return tWHATIS; }
+<INITIAL,INFO_CMD,DEL_CMD>break|brea|bre|br|b { BEGIN(NOCMD); return tBREAK; }
+<INITIAL>watch|watc|wat { BEGIN(NOCMD); return tWATCH; }
+<INITIAL>whatis|whati|what { BEGIN(NOCMD); return tWHATIS; }
<INITIAL,NOPROCESS>run|ru|r { BEGIN(ASTRING_EXPECTED); return tRUN;}
<NOPROCESS>attach|attac|atta|att { BEGIN(NOCMD); return tATTACH; }
<INFO_CMD>share|shar|sha { return tSHARE; }
@@ -247,7 +246,7 @@
static char *local_symbols[30];
static int next_symbol;
-static char * DEBUG_MakeSymbol(char * symbol)
+char * DEBUG_MakeSymbol(const char * symbol)
{
assert(0 <= next_symbol && next_symbol < (sizeof(local_symbols) / sizeof(local_symbols[0])));
return local_symbols[next_symbol++] = DBG_strdup(symbol);
diff --git a/debugger/debugger.h b/debugger/debugger.h
index 0d2a064..567b949 100644
--- a/debugger/debugger.h
+++ b/debugger/debugger.h
@@ -286,6 +286,7 @@
/* debugger/debug.l */
extern void DEBUG_FlushSymbols(void);
+extern char*DEBUG_MakeSymbol(const char*);
/* debugger/display.c */
extern int DEBUG_DoDisplay(void);
@@ -534,6 +535,7 @@
#define DEBUG_STATUS_NO_SYMBOL (DEBUG_STATUS_OFFSET+1)
#define DEBUG_STATUS_DIV_BY_ZERO (DEBUG_STATUS_OFFSET+2)
#define DEBUG_STATUS_BAD_TYPE (DEBUG_STATUS_OFFSET+3)
+#define DEBUG_STATUS_NO_FIELD (DEBUG_STATUS_OFFSET+4)
extern DBG_INTVAR DEBUG_IntVars[];
diff --git a/debugger/expr.c b/debugger/expr.c
index 2bcac13..45492f1 100644
--- a/debugger/expr.c
+++ b/debugger/expr.c
@@ -333,9 +333,10 @@
break;
case EXPR_TYPE_SYMBOL:
if( !DEBUG_GetSymbolValue(exp->un.symbol.name, -1, &rtn, FALSE) )
- {
- RaiseException(DEBUG_STATUS_NO_SYMBOL, 0, 0, NULL);
- }
+ {
+ DEBUG_Printf(DBG_CHN_MESG, "%s\n", exp->un.symbol.name);
+ RaiseException(DEBUG_STATUS_NO_SYMBOL, 0, 0, NULL);
+ }
break;
case EXPR_TYPE_PSTRUCT:
exp1 = DEBUG_EvalExpr(exp->un.structure.exp1);
@@ -344,24 +345,32 @@
RaiseException(DEBUG_STATUS_BAD_TYPE, 0, 0, NULL);
}
rtn.cookie = DV_TARGET;
- rtn.addr.off = DEBUG_TypeDerefPointer(&exp1, &type1);
- if( type1 == NULL )
+ rtn.addr.off = DEBUG_TypeDerefPointer(&exp1, &rtn.type);
+ if( rtn.type == NULL )
{
RaiseException(DEBUG_STATUS_BAD_TYPE, 0, 0, NULL);
}
- rtn.type = type1;
- DEBUG_FindStructElement(&rtn, exp->un.structure.element_name,
- &exp->un.structure.result);
+ if (!DEBUG_FindStructElement(&rtn, exp->un.structure.element_name,
+ &exp->un.structure.result))
+ {
+ DEBUG_Printf(DBG_CHN_MESG, "%s\n", exp->un.structure.element_name);
+ RaiseException(DEBUG_STATUS_NO_FIELD, 0, 0, NULL);
+ }
+
break;
case EXPR_TYPE_STRUCT:
exp1 = DEBUG_EvalExpr(exp->un.structure.exp1);
if( exp1.type == NULL )
- {
+ {
RaiseException(DEBUG_STATUS_BAD_TYPE, 0, 0, NULL);
- }
+ }
rtn = exp1;
- DEBUG_FindStructElement(&rtn, exp->un.structure.element_name,
- &exp->un.structure.result);
+ if (!DEBUG_FindStructElement(&rtn, exp->un.structure.element_name,
+ &exp->un.structure.result))
+ {
+ DEBUG_Printf(DBG_CHN_MESG, "%s\n", exp->un.structure.element_name);
+ RaiseException(DEBUG_STATUS_NO_FIELD, 0, 0, NULL);
+ }
break;
case EXPR_TYPE_CALL:
/*
diff --git a/debugger/hash.c b/debugger/hash.c
index 86c809a..a76d632 100644
--- a/debugger/hash.c
+++ b/debugger/hash.c
@@ -1214,6 +1214,8 @@
return FALSE;
}
+ DEBUG_Printf(DBG_CHN_MESG, "%s:\n", curr_func->name);
+
for(i=0; i < curr_func->n_locals; i++ )
{
/*
@@ -1234,12 +1236,14 @@
continue;
}
+ DEBUG_PrintTypeCast(curr_func->local_vars[i].type);
+
if( curr_func->local_vars[i].regno != 0 )
{
ptr = (unsigned int *)(((DWORD)&DEBUG_context)
+ reg_ofs[curr_func->local_vars[i].regno - 1]);
- DEBUG_Printf(DBG_CHN_MESG, "%s:%s (optimized into register $%s) == 0x%8.8x\n",
- curr_func->name, curr_func->local_vars[i].name,
+ DEBUG_Printf(DBG_CHN_MESG, " %s (optimized into register $%s) == 0x%8.8x\n",
+ curr_func->local_vars[i].name,
reg_name[curr_func->local_vars[i].regno - 1],
*ptr);
}
@@ -1247,8 +1251,8 @@
{
DEBUG_READ_MEM_VERBOSE((void*)(ebp + curr_func->local_vars[i].offset),
&val, sizeof(val));
- DEBUG_Printf(DBG_CHN_MESG, "%s:%s == 0x%8.8x\n",
- curr_func->name, curr_func->local_vars[i].name, val);
+ DEBUG_Printf(DBG_CHN_MESG, " %s == 0x%8.8x\n",
+ curr_func->local_vars[i].name, val);
}
}
diff --git a/debugger/module.c b/debugger/module.c
index cce20da..dfc43ab 100644
--- a/debugger/module.c
+++ b/debugger/module.c
@@ -282,7 +282,7 @@
if (size < pe_seg.VirtualAddress + pe_seg.SizeOfRawData)
size = pe_seg.VirtualAddress + pe_seg.SizeOfRawData;
}
-
+
/* FIXME: we make the assumption that hModule == base */
wmod = DEBUG_RegisterPEModule((HMODULE)base, base, size, name);
if (wmod) {
@@ -291,9 +291,9 @@
dil = DEBUG_RegisterMSCDebugInfo(wmod, hFile, &pe_header, nth_ofs);
if (dil != DIL_LOADED)
dil = DEBUG_RegisterPEDebugInfo(wmod, hFile, &pe_header, nth_ofs);
+ wmod->dil = dil;
}
- if (wmod) wmod->dil = dil;
DEBUG_ReportDIL(dil, "32bit DLL", name, base);
}
diff --git a/debugger/winedbg.c b/debugger/winedbg.c
index f157c01..2ac92f8 100644
--- a/debugger/winedbg.c
+++ b/debugger/winedbg.c
@@ -297,25 +297,26 @@
if (!is_debug) {
if (!addr.seg)
- DEBUG_Printf(DBG_CHN_MESG, " in 32-bit code (0x%08lx).\n", addr.off);
+ DEBUG_Printf(DBG_CHN_MESG, " in 32-bit code (0x%08lx)", addr.off);
else
switch(DEBUG_GetSelectorType(addr.seg))
{
case MODE_32:
- DEBUG_Printf(DBG_CHN_MESG, " in 32-bit code (%04lx:%08lx).\n", addr.seg, addr.off);
+ DEBUG_Printf(DBG_CHN_MESG, " in 32-bit code (%04lx:%08lx)", addr.seg, addr.off);
break;
case MODE_16:
- DEBUG_Printf(DBG_CHN_MESG, " in 16-bit code (%04lx:%04lx).\n", addr.seg, addr.off);
+ DEBUG_Printf(DBG_CHN_MESG, " in 16-bit code (%04lx:%04lx)", addr.seg, addr.off);
break;
case MODE_VM86:
- DEBUG_Printf(DBG_CHN_MESG, " in vm86 code (%04lx:%04lx).\n", addr.seg, addr.off);
+ DEBUG_Printf(DBG_CHN_MESG, " in vm86 code (%04lx:%04lx)", addr.seg, addr.off);
break;
case MODE_INVALID:
- DEBUG_Printf(DBG_CHN_MESG, "bad CS (%lx)\n", addr.seg);
+ DEBUG_Printf(DBG_CHN_MESG, " bad CS (%lx)", addr.seg);
break;
}
+ DEBUG_Printf(DBG_CHN_MESG, ".\n");
}
-
+
DEBUG_LoadEntryPoints("Loading new modules symbols:\n");
if (!force && is_debug &&
@@ -505,9 +506,9 @@
DEBUG_Printf(DBG_CHN_MESG, "%08lx", rec->ExceptionCode);
break;
}
- DEBUG_Printf(DBG_CHN_MESG, "\n");
}
+#if 0
DEBUG_Printf(DBG_CHN_TRACE,
"Entering debugger PC=%lx EFL=%08lx mode=%d count=%d\n",
#ifdef __i386__
@@ -516,6 +517,7 @@
0L, 0L,
#endif
DEBUG_CurrThread->dbg_exec_mode, DEBUG_CurrThread->dbg_exec_count);
+#endif
if (DEBUG_ExceptionProlog(is_debug, force, rec->ExceptionCode)) {
DEBUG_interactiveP = TRUE;
@@ -530,6 +532,7 @@
}
*cont = DEBUG_ExceptionEpilog();
+#if 0
DEBUG_Printf(DBG_CHN_TRACE,
"Exiting debugger PC=%lx EFL=%08lx mode=%d count=%d\n",
#ifdef __i386__
@@ -538,6 +541,7 @@
0L, 0L,
#endif
DEBUG_CurrThread->dbg_exec_mode, DEBUG_CurrThread->dbg_exec_count);
+#endif
return ret;
}
diff --git a/documentation/debugger.sgml b/documentation/debugger.sgml
index dfd15e5..da1380a3 100644
--- a/documentation/debugger.sgml
+++ b/documentation/debugger.sgml
@@ -1494,11 +1494,9 @@
</listitem>
<listitem>
<para>
- Because of previous rule, fields access from a struct must be written as:
-<screen>
- my_struct . my_field
-</screen>
- (note the spaces after and before the dot).
+ The debugger will try to distinguish this writing with structure operations.
+ Therefore, you can only use the previous writing in operations manipulating
+ symbols ({break|watch}points, type information command...).
</para>
</listitem>
</itemizedlist>