Commit 926f6618 authored by Eric Pouech's avatar Eric Pouech Committed by Alexandre Julliard

- fixed breakpoint enabled/disabled state management

- fixed recursion in type printing - now all type-id are stored with the base address of the module which defines the type (struct dbg_type takes care of this pairing) - fixed a couple of bugs in display handling - fixed strings print and examination
parent 07a80512
...@@ -1683,19 +1683,21 @@ set $BreakAllThreadsStartup = 1 ...@@ -1683,19 +1683,21 @@ set $BreakAllThreadsStartup = 1
<tbody> <tbody>
<row> <row>
<entry> <entry>
<msgtext> <command>info&nbsp;display</command>
<simplelist type="inline">
<member><command>display</command></member>
<member>
<command>info&nbsp;display</command>
</member>
</simplelist>
</msgtext>
</entry> </entry>
<entry>lists the active displays</entry> <entry>lists the active displays</entry>
</row> </row>
<row> <row>
<entry> <entry>
<command>display</command>
</entry>
<entry>
print the active displays' values (as done each
time the debugger stops)
</entry>
</row>
<row>
<entry>
<command>display&nbsp;&lt;expr&gt;</command> <command>display&nbsp;&lt;expr&gt;</command>
</entry> </entry>
<entry> <entry>
......
...@@ -59,8 +59,7 @@ void break_set_xpoints(BOOL set) ...@@ -59,8 +59,7 @@ void break_set_xpoints(BOOL set)
for (i = 0; i < dbg_curr_process->next_bp; i++) for (i = 0; i < dbg_curr_process->next_bp; i++)
{ {
if (!bp[i].refcount && !bp[i].enabled) if (!bp[i].refcount || !bp[i].enabled) continue;
continue;
if (bp[i].xpoint_type == be_xpoint_break) if (bp[i].xpoint_type == be_xpoint_break)
size = 0; size = 0;
...@@ -78,8 +77,9 @@ void break_set_xpoints(BOOL set) ...@@ -78,8 +77,9 @@ void break_set_xpoints(BOOL set)
bp[i].info, size); bp[i].info, size);
if (!ret) if (!ret)
{ {
dbg_printf("Invalid address (%p) for breakpoint %d, disabling it\n", dbg_printf("Invalid address (");
addr, i); print_address(&bp[i].addr, FALSE);
dbg_printf(") for breakpoint %d, disabling it\n", i);
bp[i].enabled = FALSE; bp[i].enabled = FALSE;
} }
} }
...@@ -375,10 +375,9 @@ void break_add_watch(const struct dbg_lvalue* lvalue, BOOL is_write) ...@@ -375,10 +375,9 @@ void break_add_watch(const struct dbg_lvalue* lvalue, BOOL is_write)
&lvalue->addr); &lvalue->addr);
if (num == -1) return; if (num == -1) return;
if (lvalue->typeid != dbg_itype_none) if (lvalue->type.id != dbg_itype_none)
{ {
if (types_get_info((DWORD)memory_to_linear_addr(&lvalue->addr), if (types_get_info(&lvalue->type, TI_GET_LENGTH, &l))
lvalue->typeid, TI_GET_LENGTH, &l))
{ {
switch (l) switch (l)
{ {
...@@ -679,7 +678,7 @@ static BOOL should_stop(int bpnum) ...@@ -679,7 +678,7 @@ static BOOL should_stop(int bpnum)
{ {
struct dbg_lvalue lvalue = expr_eval(bp->condition); struct dbg_lvalue lvalue = expr_eval(bp->condition);
if (lvalue.typeid == dbg_itype_none) if (lvalue.type.id == dbg_itype_none)
{ {
/* /*
* Something wrong - unable to evaluate this expression. * Something wrong - unable to evaluate this expression.
......
...@@ -133,7 +133,7 @@ command: ...@@ -133,7 +133,7 @@ command:
| tSOURCE pathname { parser($2); } | tSOURCE pathname { parser($2); }
| tSYMBOLFILE pathname { symbol_read_symtable($2, 0); } | tSYMBOLFILE pathname { symbol_read_symtable($2, 0); }
| tSYMBOLFILE pathname expr_rvalue { symbol_read_symtable($2, $3); } | tSYMBOLFILE pathname expr_rvalue { symbol_read_symtable($2, $3); }
| tWHATIS expr_lvalue { types_print_type((DWORD)memory_to_linear_addr(&$2.addr), $2.typeid, FALSE); dbg_printf("\n"); } | tWHATIS expr_lvalue { types_print_type(&$2.type, FALSE); dbg_printf("\n"); }
| tATTACH tNUM { dbg_attach_debuggee($2, FALSE, TRUE); } | tATTACH tNUM { dbg_attach_debuggee($2, FALSE, TRUE); }
| tDETACH { dbg_detach_debuggee(); } | tDETACH { dbg_detach_debuggee(); }
| run_command | run_command
...@@ -202,8 +202,8 @@ set_command: ...@@ -202,8 +202,8 @@ set_command:
; ;
x_command: x_command:
tEXAM expr_lvalue { memory_examine(&$2, 1, 'x'); } tEXAM expr_rvalue { memory_examine((void*)$2, 1, 'x'); }
| tEXAM tFORMAT expr_lvalue { memory_examine(&$3, $2 >> 8, $2 & 0xff); } | tEXAM tFORMAT expr_rvalue { memory_examine((void*)$3, $2 >> 8, $2 & 0xff); }
; ;
print_command: print_command:
...@@ -231,7 +231,7 @@ watch_command: ...@@ -231,7 +231,7 @@ watch_command:
; ;
display_command: display_command:
tDISPLAY { display_info(); } tDISPLAY { display_print(); }
| tDISPLAY expr { display_add($2, 1, 0, FALSE); } | tDISPLAY expr { display_add($2, 1, 0, FALSE); }
| tDISPLAY tFORMAT expr { display_add($3, $2 >> 8, $2 & 0xff, FALSE); } | tDISPLAY tFORMAT expr { display_add($3, $2 >> 8, $2 & 0xff, FALSE); }
| tLOCAL tDISPLAY expr { display_add($3, 1, 0, TRUE); } | tLOCAL tDISPLAY expr { display_add($3, 1, 0, TRUE); }
...@@ -280,27 +280,27 @@ noprocess_state: ...@@ -280,27 +280,27 @@ noprocess_state:
; ;
type_expr: type_expr:
tCHAR { $$.type = type_expr_type_id; $$.deref_count = 0; $$.u.typeid = dbg_itype_char; } tCHAR { $$.type = type_expr_type_id; $$.deref_count = 0; $$.u.type.module = 0; $$.u.type.id = dbg_itype_char; }
| tINT { $$.type = type_expr_type_id; $$.deref_count = 0; $$.u.typeid = dbg_itype_signed_int; } | tINT { $$.type = type_expr_type_id; $$.deref_count = 0; $$.u.type.module = 0; $$.u.type.id = dbg_itype_signed_int; }
| tLONG tINT { $$.type = type_expr_type_id; $$.deref_count = 0; $$.u.typeid = dbg_itype_signed_long_int; } | tLONG tINT { $$.type = type_expr_type_id; $$.deref_count = 0; $$.u.type.module = 0; $$.u.type.id = dbg_itype_signed_long_int; }
| tLONG { $$.type = type_expr_type_id; $$.deref_count = 0; $$.u.typeid = dbg_itype_signed_long_int; } | tLONG { $$.type = type_expr_type_id; $$.deref_count = 0; $$.u.type.module = 0; $$.u.type.id = dbg_itype_signed_long_int; }
| tUNSIGNED tINT { $$.type = type_expr_type_id; $$.deref_count = 0; $$.u.typeid = dbg_itype_unsigned_int; } | tUNSIGNED tINT { $$.type = type_expr_type_id; $$.deref_count = 0; $$.u.type.module = 0; $$.u.type.id = dbg_itype_unsigned_int; }
| tUNSIGNED { $$.type = type_expr_type_id; $$.deref_count = 0; $$.u.typeid = dbg_itype_unsigned_int; } | tUNSIGNED { $$.type = type_expr_type_id; $$.deref_count = 0; $$.u.type.module = 0; $$.u.type.id = dbg_itype_unsigned_int; }
| tLONG tUNSIGNED tINT { $$.type = type_expr_type_id; $$.deref_count = 0; $$.u.typeid = dbg_itype_unsigned_long_int; } | tLONG tUNSIGNED tINT { $$.type = type_expr_type_id; $$.deref_count = 0; $$.u.type.module = 0; $$.u.type.id = dbg_itype_unsigned_long_int; }
| tLONG tUNSIGNED { $$.type = type_expr_type_id; $$.deref_count = 0; $$.u.typeid = dbg_itype_unsigned_long_int; } | tLONG tUNSIGNED { $$.type = type_expr_type_id; $$.deref_count = 0; $$.u.type.module = 0; $$.u.type.id = dbg_itype_unsigned_long_int; }
| tSHORT tINT { $$.type = type_expr_type_id; $$.deref_count = 0; $$.u.typeid = dbg_itype_signed_short_int; } | tSHORT tINT { $$.type = type_expr_type_id; $$.deref_count = 0; $$.u.type.module = 0; $$.u.type.id = dbg_itype_signed_short_int; }
| tSHORT { $$.type = type_expr_type_id; $$.deref_count = 0; $$.u.typeid = dbg_itype_signed_short_int; } | tSHORT { $$.type = type_expr_type_id; $$.deref_count = 0; $$.u.type.module = 0; $$.u.type.id = dbg_itype_signed_short_int; }
| tSHORT tUNSIGNED tINT { $$.type = type_expr_type_id; $$.deref_count = 0; $$.u.typeid = dbg_itype_unsigned_short_int; } | tSHORT tUNSIGNED tINT { $$.type = type_expr_type_id; $$.deref_count = 0; $$.u.type.module = 0; $$.u.type.id = dbg_itype_unsigned_short_int; }
| tSHORT tUNSIGNED { $$.type = type_expr_type_id; $$.deref_count = 0; $$.u.typeid = dbg_itype_unsigned_short_int; } | tSHORT tUNSIGNED { $$.type = type_expr_type_id; $$.deref_count = 0; $$.u.type.module = 0; $$.u.type.id = dbg_itype_unsigned_short_int; }
| tSIGNED tCHAR { $$.type = type_expr_type_id; $$.deref_count = 0; $$.u.typeid = dbg_itype_signed_char_int; } | tSIGNED tCHAR { $$.type = type_expr_type_id; $$.deref_count = 0; $$.u.type.module = 0; $$.u.type.id = dbg_itype_signed_char_int; }
| tUNSIGNED tCHAR { $$.type = type_expr_type_id; $$.deref_count = 0; $$.u.typeid = dbg_itype_unsigned_char_int; } | tUNSIGNED tCHAR { $$.type = type_expr_type_id; $$.deref_count = 0; $$.u.type.module = 0; $$.u.type.id = dbg_itype_unsigned_char_int; }
| tLONG tLONG tUNSIGNED tINT{ $$.type = type_expr_type_id; $$.deref_count = 0; $$.u.typeid = dbg_itype_unsigned_longlong_int; } | tLONG tLONG tUNSIGNED tINT{ $$.type = type_expr_type_id; $$.deref_count = 0; $$.u.type.module = 0; $$.u.type.id = dbg_itype_unsigned_longlong_int; }
| tLONG tLONG tUNSIGNED { $$.type = type_expr_type_id; $$.deref_count = 0; $$.u.typeid = dbg_itype_unsigned_longlong_int; } | tLONG tLONG tUNSIGNED { $$.type = type_expr_type_id; $$.deref_count = 0; $$.u.type.module = 0; $$.u.type.id = dbg_itype_unsigned_longlong_int; }
| tLONG tLONG tINT { $$.type = type_expr_type_id; $$.deref_count = 0; $$.u.typeid = dbg_itype_signed_longlong_int; } | tLONG tLONG tINT { $$.type = type_expr_type_id; $$.deref_count = 0; $$.u.type.module = 0; $$.u.type.id = dbg_itype_signed_longlong_int; }
| tLONG tLONG { $$.type = type_expr_type_id; $$.deref_count = 0; $$.u.typeid = dbg_itype_signed_longlong_int; } | tLONG tLONG { $$.type = type_expr_type_id; $$.deref_count = 0; $$.u.type.module = 0; $$.u.type.id = dbg_itype_signed_longlong_int; }
| tFLOAT { $$.type = type_expr_type_id; $$.deref_count = 0; $$.u.typeid = dbg_itype_short_real; } | tFLOAT { $$.type = type_expr_type_id; $$.deref_count = 0; $$.u.type.module = 0; $$.u.type.id = dbg_itype_short_real; }
| tDOUBLE { $$.type = type_expr_type_id; $$.deref_count = 0; $$.u.typeid = dbg_itype_real; } | tDOUBLE { $$.type = type_expr_type_id; $$.deref_count = 0; $$.u.type.module = 0; $$.u.type.id = dbg_itype_real; }
| tLONG tDOUBLE { $$.type = type_expr_type_id; $$.deref_count = 0; $$.u.typeid = dbg_itype_long_real; } | tLONG tDOUBLE { $$.type = type_expr_type_id; $$.deref_count = 0; $$.u.type.module = 0; $$.u.type.id = dbg_itype_long_real; }
| type_expr '*' { $$ = $1; $$.deref_count++; } | type_expr '*' { $$ = $1; $$.deref_count++; }
| tCLASS identifier { $$.type = type_expr_udt_class; $$.deref_count = 0; $$.u.name = lexeme_alloc($2); } | tCLASS identifier { $$.type = type_expr_udt_class; $$.deref_count = 0; $$.u.name = lexeme_alloc($2); }
| tSTRUCT identifier { $$.type = type_expr_udt_struct; $$.deref_count = 0; $$.u.name = lexeme_alloc($2); } | tSTRUCT identifier { $$.type = type_expr_udt_struct; $$.deref_count = 0; $$.u.name = lexeme_alloc($2); }
......
...@@ -82,6 +82,18 @@ enum dbg_internal_types ...@@ -82,6 +82,18 @@ enum dbg_internal_types
dbg_itype_none = 0xffffffff dbg_itype_none = 0xffffffff
}; };
/* type description (in the following order):
* - if 'id' is dbg_itype_none (whatever 'module' value), the type isn't known
* - if 'module' is 0, it's an internal type (id is one of dbg_itype...)
* - if 'module' is non 0, then 'id' is a type ID referring to module (loaded in
* dbghelp) which (linear) contains address 'module'.
*/
struct dbg_type
{
unsigned long id;
DWORD module;
};
struct dbg_lvalue /* structure to hold left-values... */ struct dbg_lvalue /* structure to hold left-values... */
{ {
int cookie; /* DLV_??? */ int cookie; /* DLV_??? */
...@@ -91,7 +103,7 @@ struct dbg_lvalue /* structure to hold left-values... */ ...@@ -91,7 +103,7 @@ struct dbg_lvalue /* structure to hold left-values... */
# define DLV_TARGET 0xF00D # define DLV_TARGET 0xF00D
# define DLV_HOST 0x50DA # define DLV_HOST 0x50DA
ADDRESS addr; ADDRESS addr;
unsigned long typeid; struct dbg_type type;
}; };
enum dbg_exec_mode enum dbg_exec_mode
...@@ -202,7 +214,7 @@ struct dbg_internal_var ...@@ -202,7 +214,7 @@ struct dbg_internal_var
DWORD val; DWORD val;
const char* name; const char* name;
LPDWORD pval; LPDWORD pval;
unsigned long typeid; unsigned long typeid; /* always internal type */
}; };
enum sym_get_lval {sglv_found, sglv_unknown, sglv_aborted}; enum sym_get_lval {sglv_found, sglv_unknown, sglv_aborted};
...@@ -222,7 +234,7 @@ struct type_expr_t ...@@ -222,7 +234,7 @@ struct type_expr_t
unsigned deref_count; unsigned deref_count;
union union
{ {
unsigned long typeid; struct dbg_type type;
const char* name; const char* name;
} u; } u;
}; };
...@@ -293,15 +305,15 @@ extern void info_win32_segments(DWORD start, int length); ...@@ -293,15 +305,15 @@ extern void info_win32_segments(DWORD start, int length);
extern void info_wine_dbg_channel(BOOL add, const char* chnl, const char* name); extern void info_wine_dbg_channel(BOOL add, const char* chnl, const char* name);
/* memory.c */ /* memory.c */
extern BOOL memory_read_value(const struct dbg_lvalue* val, DWORD size, void* result); extern BOOL memory_read_value(const struct dbg_lvalue* lvalue, DWORD size, void* result);
extern BOOL memory_write_value(const struct dbg_lvalue* val, DWORD size, void* value); extern BOOL memory_write_value(const struct dbg_lvalue* val, DWORD size, void* value);
extern void memory_examine(const struct dbg_lvalue* addr, int count, char format); extern void memory_examine(void* linear, int count, char format);
extern void memory_report_invalid_addr(const void* addr); extern void memory_report_invalid_addr(const void* addr);
extern void* memory_to_linear_addr(const ADDRESS* address); extern void* memory_to_linear_addr(const ADDRESS* address);
extern BOOL memory_get_current_pc(ADDRESS* address); extern BOOL memory_get_current_pc(ADDRESS* address);
extern BOOL memory_get_current_stack(ADDRESS* address); extern BOOL memory_get_current_stack(ADDRESS* address);
extern BOOL memory_get_current_frame(ADDRESS* address); extern BOOL memory_get_current_frame(ADDRESS* address);
extern BOOL memory_get_string(HANDLE hp, void* addr, unsigned cookie, BOOL unicode, char* buffer, int size); extern BOOL memory_get_string(HANDLE hp, void* addr, BOOL in_debuggee, BOOL unicode, char* buffer, int size);
extern BOOL memory_get_string_indirect(HANDLE hp, void* addr, BOOL unicode, char* buffer, int size); extern BOOL memory_get_string_indirect(HANDLE hp, void* addr, BOOL unicode, char* buffer, int size);
extern void memory_disassemble(const struct dbg_lvalue*, const struct dbg_lvalue*, int offset); extern void memory_disassemble(const struct dbg_lvalue*, const struct dbg_lvalue*, int offset);
extern BOOL memory_disasm_one_insn(ADDRESS* addr); extern BOOL memory_disasm_one_insn(ADDRESS* addr);
...@@ -333,16 +345,15 @@ extern int symbol_info_locals(void); ...@@ -333,16 +345,15 @@ extern int symbol_info_locals(void);
/* types.c */ /* types.c */
extern void print_value(const struct dbg_lvalue* addr, char format, int level); extern void print_value(const struct dbg_lvalue* addr, char format, int level);
extern int types_print_type(DWORD linear, DWORD typeid, BOOL details); extern int types_print_type(const struct dbg_type*, BOOL details);
extern int print_types(void); extern int print_types(void);
extern long int types_extract_as_integer(const struct dbg_lvalue*); extern long int types_extract_as_integer(const struct dbg_lvalue*);
extern BOOL types_deref(const struct dbg_lvalue* value, struct dbg_lvalue* result); extern BOOL types_deref(const struct dbg_lvalue* value, struct dbg_lvalue* result);
extern BOOL types_udt_find_element(struct dbg_lvalue* value, const char* name, long int* tmpbuf); extern BOOL types_udt_find_element(struct dbg_lvalue* value, const char* name, long int* tmpbuf);
extern BOOL types_array_index(const struct dbg_lvalue* value, int index, struct dbg_lvalue* result); extern BOOL types_array_index(const struct dbg_lvalue* value, int index, struct dbg_lvalue* result);
extern BOOL types_get_info(unsigned long, unsigned long, extern BOOL types_get_info(const struct dbg_type*, IMAGEHLP_SYMBOL_TYPE_INFO, void*);
IMAGEHLP_SYMBOL_TYPE_INFO, void*); extern struct dbg_type types_find_pointer(const struct dbg_type* type);
extern unsigned long types_find_pointer(unsigned long linear, unsigned long typeid); extern struct dbg_type types_find_type(unsigned long linear, const char* name, enum SymTagEnum tag);
extern unsigned long types_find_type(unsigned long linear, const char* name, enum SymTagEnum tag);
/* winedbg.c */ /* winedbg.c */
extern void dbg_outputA(const char* buffer, int len); extern void dbg_outputA(const char* buffer, int len);
......
...@@ -43,10 +43,18 @@ struct display ...@@ -43,10 +43,18 @@ struct display
static struct display *displaypoints = NULL; static struct display *displaypoints = NULL;
static unsigned int maxdisplays = 0, ndisplays = 0; static unsigned int maxdisplays = 0, ndisplays = 0;
#define OFFSET_OF(_f,_s) ((unsigned)(&(((_s*)NULL)->_f)))
static inline BOOL cmp_symbol(const SYMBOL_INFO* si1, const SYMBOL_INFO* si2) static inline BOOL cmp_symbol(const SYMBOL_INFO* si1, const SYMBOL_INFO* si2)
{ {
if (si1->NameLen != si2->NameLen) return FALSE; /* FIXME: !memcmp(si1, si2, sizeof(SYMBOL_INFO) + si1->NameLen)
return !memcmp(si1, si2, sizeof(SYMBOL_INFO) + si1->NameLen); * is wrong because sizeof(SYMBOL_INFO) can be aligned on 4-byte boundary
* Note: we also need to zero out the structures before calling
* stack_get_frame, so that un-touched fields by stack_get_frame
* get the same value!!
*/
return !memcmp(si1, si2, OFFSET_OF(Name, SYMBOL_INFO)) &&
!memcmp(si1->Name, si2->Name, si1->NameLen);
} }
int display_add(struct expr *exp, int count, char format, int in_frame) int display_add(struct expr *exp, int count, char format, int in_frame)
...@@ -74,6 +82,7 @@ int display_add(struct expr *exp, int count, char format, int in_frame) ...@@ -74,6 +82,7 @@ int display_add(struct expr *exp, int count, char format, int in_frame)
if (in_frame) if (in_frame)
{ {
displaypoints[i].func = (SYMBOL_INFO*)displaypoints[i].func_buffer; displaypoints[i].func = (SYMBOL_INFO*)displaypoints[i].func_buffer;
memset(displaypoints[i].func, 0, sizeof(SYMBOL_INFO));
displaypoints[i].func->SizeOfStruct = sizeof(SYMBOL_INFO); displaypoints[i].func->SizeOfStruct = sizeof(SYMBOL_INFO);
displaypoints[i].func->MaxNameLen = sizeof(displaypoints[i].func_buffer) - displaypoints[i].func->MaxNameLen = sizeof(displaypoints[i].func_buffer) -
sizeof(*displaypoints[i].func); sizeof(*displaypoints[i].func);
...@@ -97,6 +106,7 @@ int display_info(void) ...@@ -97,6 +106,7 @@ int display_info(void)
const char* info; const char* info;
func = (SYMBOL_INFO*)buffer; func = (SYMBOL_INFO*)buffer;
memset(func, 0, sizeof(SYMBOL_INFO));
func->SizeOfStruct = sizeof(SYMBOL_INFO); func->SizeOfStruct = sizeof(SYMBOL_INFO);
func->MaxNameLen = sizeof(buffer) - sizeof(*func); func->MaxNameLen = sizeof(buffer) - sizeof(*func);
if (!stack_get_frame(func, NULL)) return FALSE; if (!stack_get_frame(func, NULL)) return FALSE;
...@@ -105,6 +115,9 @@ int display_info(void) ...@@ -105,6 +115,9 @@ int display_info(void)
{ {
if (displaypoints[i].exp == NULL) continue; if (displaypoints[i].exp == NULL) continue;
dbg_printf("%d: ", i + 1);
expr_print(displaypoints[i].exp);
if (displaypoints[i].enabled) if (displaypoints[i].enabled)
{ {
if (displaypoints[i].func && !cmp_symbol(displaypoints[i].func, func)) if (displaypoints[i].func && !cmp_symbol(displaypoints[i].func, func))
...@@ -114,10 +127,9 @@ int display_info(void) ...@@ -114,10 +127,9 @@ int display_info(void)
} }
else else
info = " (disabled)"; info = " (disabled)";
dbg_printf("%d in %s%s: ", if (displaypoints[i].func)
i + 1, func ? displaypoints[i].func->Name : "", info); dbg_printf(" in %s", displaypoints[i].func->Name);
expr_print(displaypoints[i].exp); dbg_printf("%s\n", info);
dbg_printf("\n");
} }
return TRUE; return TRUE;
} }
...@@ -129,7 +141,7 @@ static void print_one_display(int i) ...@@ -129,7 +141,7 @@ static void print_one_display(int i)
if (displaypoints[i].enabled) if (displaypoints[i].enabled)
{ {
lvalue = expr_eval(displaypoints[i].exp); lvalue = expr_eval(displaypoints[i].exp);
if (lvalue.typeid == dbg_itype_none) if (lvalue.type.id == dbg_itype_none)
{ {
dbg_printf("Unable to evaluate expression "); dbg_printf("Unable to evaluate expression ");
expr_print(displaypoints[i].exp); expr_print(displaypoints[i].exp);
...@@ -146,7 +158,8 @@ static void print_one_display(int i) ...@@ -146,7 +158,8 @@ static void print_one_display(int i)
dbg_printf("(disabled)\n"); dbg_printf("(disabled)\n");
else else
if (displaypoints[i].format == 'i') if (displaypoints[i].format == 'i')
memory_examine(&lvalue, displaypoints[i].count, displaypoints[i].format); memory_examine((void*)types_extract_as_integer(&lvalue),
displaypoints[i].count, displaypoints[i].format);
else else
print_value(&lvalue, displaypoints[i].format, 0); print_value(&lvalue, displaypoints[i].format, 0);
} }
...@@ -158,6 +171,7 @@ int display_print(void) ...@@ -158,6 +171,7 @@ int display_print(void)
SYMBOL_INFO* func; SYMBOL_INFO* func;
func = (SYMBOL_INFO*)buffer; func = (SYMBOL_INFO*)buffer;
memset(func, 0, sizeof(SYMBOL_INFO));
func->SizeOfStruct = sizeof(SYMBOL_INFO); func->SizeOfStruct = sizeof(SYMBOL_INFO);
func->MaxNameLen = sizeof(buffer) - sizeof(*func); func->MaxNameLen = sizeof(buffer) - sizeof(*func);
if (!stack_get_frame(func, NULL)) return FALSE; if (!stack_get_frame(func, NULL)) return FALSE;
...@@ -226,6 +240,7 @@ int display_enable(int displaynum, int enable) ...@@ -226,6 +240,7 @@ int display_enable(int displaynum, int enable)
SYMBOL_INFO* func; SYMBOL_INFO* func;
func = (SYMBOL_INFO*)buffer; func = (SYMBOL_INFO*)buffer;
memset(func, 0, sizeof(SYMBOL_INFO));
func->SizeOfStruct = sizeof(SYMBOL_INFO); func->SizeOfStruct = sizeof(SYMBOL_INFO);
func->MaxNameLen = sizeof(buffer) - sizeof(*func); func->MaxNameLen = sizeof(buffer) - sizeof(*func);
if (!stack_get_frame(func, NULL)) return FALSE; if (!stack_get_frame(func, NULL)) return FALSE;
......
...@@ -468,7 +468,7 @@ static void handle_debug_event(struct gdb_context* gdbctx, DEBUG_EVENT* de) ...@@ -468,7 +468,7 @@ static void handle_debug_event(struct gdb_context* gdbctx, DEBUG_EVENT* de)
case OUTPUT_DEBUG_STRING_EVENT: case OUTPUT_DEBUG_STRING_EVENT:
assert(dbg_curr_thread); assert(dbg_curr_thread);
memory_get_string(gdbctx->process->handle, memory_get_string(gdbctx->process->handle,
de->u.DebugString.lpDebugStringData, DLV_TARGET, de->u.DebugString.lpDebugStringData, TRUE,
de->u.DebugString.fUnicode, buffer, sizeof(buffer)); de->u.DebugString.fUnicode, buffer, sizeof(buffer));
if (gdbctx->trace & GDBPXY_TRC_WIN32_EVENT) if (gdbctx->trace & GDBPXY_TRC_WIN32_EVENT)
fprintf(stderr, "%08lx:%08lx: output debug string (%s)\n", fprintf(stderr, "%08lx:%08lx: output debug string (%s)\n",
......
...@@ -42,27 +42,24 @@ static IMAGEHLP_STACK_FRAME* frames = NULL; ...@@ -42,27 +42,24 @@ static IMAGEHLP_STACK_FRAME* frames = NULL;
*/ */
void stack_info(void) void stack_info(void)
{ {
struct dbg_lvalue lvalue; ADDRESS addr;
lvalue.typeid = dbg_itype_none;
lvalue.cookie = DLV_TARGET;
/* FIXME: we assume stack grows the same way as on i386 */ /* FIXME: we assume stack grows the same way as on i386 */
if (!memory_get_current_stack(&lvalue.addr)) if (!memory_get_current_stack(&addr))
dbg_printf("Bad segment (%d)\n", lvalue.addr.Segment); dbg_printf("Bad segment (%d)\n", addr.Segment);
dbg_printf("Stack dump:\n"); dbg_printf("Stack dump:\n");
switch (lvalue.addr.Mode) switch (addr.Mode)
{ {
case AddrModeFlat: /* 32-bit mode */ case AddrModeFlat: /* 32-bit mode */
case AddrMode1632: /* 32-bit mode */ case AddrMode1632: /* 32-bit mode */
memory_examine(&lvalue, 24, 'x'); memory_examine(memory_to_linear_addr(&addr), 24, 'x');
break; break;
case AddrModeReal: /* 16-bit mode */ case AddrModeReal: /* 16-bit mode */
case AddrMode1616: case AddrMode1616:
memory_examine(&lvalue, 24, 'w'); memory_examine(memory_to_linear_addr(&addr), 24, 'w');
break; break;
} }
dbg_printf("\n");
} }
int stack_set_frame(int newframe) int stack_set_frame(int newframe)
......
...@@ -38,19 +38,24 @@ static BOOL symbol_get_debug_start(DWORD mod_base, DWORD typeid, DWORD* start) ...@@ -38,19 +38,24 @@ static BOOL symbol_get_debug_start(DWORD mod_base, DWORD typeid, DWORD* start)
char buffer[sizeof(TI_FINDCHILDREN_PARAMS) + 256 * sizeof(DWORD)]; char buffer[sizeof(TI_FINDCHILDREN_PARAMS) + 256 * sizeof(DWORD)];
TI_FINDCHILDREN_PARAMS* fcp = (TI_FINDCHILDREN_PARAMS*)buffer; TI_FINDCHILDREN_PARAMS* fcp = (TI_FINDCHILDREN_PARAMS*)buffer;
int i; int i;
struct dbg_type type;
if (!types_get_info(mod_base, typeid, TI_GET_CHILDRENCOUNT, &count)) return FALSE; type.module = mod_base;
type.id = typeid;
if (!types_get_info(&type, TI_GET_CHILDRENCOUNT, &count)) return FALSE;
fcp->Start = 0; fcp->Start = 0;
while (count) while (count)
{ {
fcp->Count = min(count, 256); fcp->Count = min(count, 256);
if (types_get_info(mod_base, typeid, TI_FINDCHILDREN, fcp)) if (types_get_info(&type, TI_FINDCHILDREN, fcp))
{ {
for (i = 0; i < min(fcp->Count, count); i++) for (i = 0; i < min(fcp->Count, count); i++)
{ {
types_get_info(mod_base, fcp->ChildId[i], TI_GET_SYMTAG, &tag); type.id = fcp->ChildId[i];
types_get_info(&type, TI_GET_SYMTAG, &tag);
if (tag != SymTagFuncDebugStart) continue; if (tag != SymTagFuncDebugStart) continue;
return types_get_info(mod_base, fcp->ChildId[i], TI_GET_ADDRESS, start); return types_get_info(&type, TI_GET_ADDRESS, start);
} }
count -= min(count, 256); count -= min(count, 256);
fcp->Start += 256; fcp->Start += 256;
...@@ -107,7 +112,11 @@ static BOOL CALLBACK sgv_cb(SYMBOL_INFO* sym, ULONG size, void* ctx) ...@@ -107,7 +112,11 @@ static BOOL CALLBACK sgv_cb(SYMBOL_INFO* sym, ULONG size, void* ctx)
else if (sym->Flags & SYMFLAG_FRAMEREL) else if (sym->Flags & SYMFLAG_FRAMEREL)
{ {
ULONG offset; ULONG offset;
types_get_info(sym->ModBase, sym->TypeIndex, TI_GET_OFFSET, &offset); struct dbg_type type;
type.module = sym->ModBase;
type.id = sym->TypeIndex;
types_get_info(&type, TI_GET_OFFSET, &offset);
addr = sgv->ihsf.FrameOffset + offset; addr = sgv->ihsf.FrameOffset + offset;
} }
else if (sym->Flags & SYMFLAG_THUNK) else if (sym->Flags & SYMFLAG_THUNK)
...@@ -175,11 +184,13 @@ static BOOL CALLBACK sgv_cb(SYMBOL_INFO* sym, ULONG size, void* ctx) ...@@ -175,11 +184,13 @@ static BOOL CALLBACK sgv_cb(SYMBOL_INFO* sym, ULONG size, void* ctx)
memmove(&sgv->syms[insp + 1], &sgv->syms[insp], memmove(&sgv->syms[insp + 1], &sgv->syms[insp],
sizeof(sgv->syms[0]) * sgv->num_thunks); sizeof(sgv->syms[0]) * sgv->num_thunks);
} }
sgv->syms[insp].lvalue.cookie = cookie;
sgv->syms[insp].lvalue.addr.Mode = AddrModeFlat; sgv->syms[insp].lvalue.addr.Mode = AddrModeFlat;
sgv->syms[insp].lvalue.addr.Offset = addr; sgv->syms[insp].lvalue.addr.Offset = addr;
types_get_info(sym->ModBase, sym->TypeIndex, TI_GET_TYPE, sgv->syms[insp].lvalue.type.module = sym->ModBase;
&sgv->syms[insp].lvalue.typeid); sgv->syms[insp].lvalue.type.id = sym->TypeIndex;
sgv->syms[insp].lvalue.cookie = cookie; types_get_info(&sgv->syms[insp].lvalue.type, TI_GET_TYPE,
&sgv->syms[insp].lvalue.type.id);
sgv->syms[insp].flags = sym->Flags; sgv->syms[insp].flags = sym->Flags;
sgv->num++; sgv->num++;
...@@ -314,8 +325,9 @@ enum sym_get_lval symbol_get_lvalue(const char* name, const int lineno, ...@@ -314,8 +325,9 @@ enum sym_get_lval symbol_get_lvalue(const char* name, const int lineno,
} }
else else
{ {
dbg_printf("More than one symbol named %s, picking the first one\n", name); /* FIXME: could display the list of non-picked up symbols */
i = 0; if (sgv.num > 1)
dbg_printf("More than one symbol named %s, picking the first one\n", name);
} }
*rtn = sgv.syms[i].lvalue; *rtn = sgv.syms[i].lvalue;
return sglv_found; return sglv_found;
...@@ -390,6 +402,7 @@ enum dbg_line_status symbol_get_function_line_status(const ADDRESS* addr) ...@@ -390,6 +402,7 @@ enum dbg_line_status symbol_get_function_line_status(const ADDRESS* addr)
DWORD lin = (DWORD)memory_to_linear_addr(addr); DWORD lin = (DWORD)memory_to_linear_addr(addr);
char buffer[sizeof(SYMBOL_INFO) + 256]; char buffer[sizeof(SYMBOL_INFO) + 256];
SYMBOL_INFO* sym = (SYMBOL_INFO*)buffer; SYMBOL_INFO* sym = (SYMBOL_INFO*)buffer;
struct dbg_type type;
il.SizeOfStruct = sizeof(il); il.SizeOfStruct = sizeof(il);
sym->SizeOfStruct = sizeof(SYMBOL_INFO); sym->SizeOfStruct = sizeof(SYMBOL_INFO);
...@@ -419,7 +432,9 @@ enum dbg_line_status symbol_get_function_line_status(const ADDRESS* addr) ...@@ -419,7 +432,9 @@ enum dbg_line_status symbol_get_function_line_status(const ADDRESS* addr)
if (symbol_get_debug_start(sym->ModBase, sym->TypeIndex, &start) && lin < start) if (symbol_get_debug_start(sym->ModBase, sym->TypeIndex, &start) && lin < start)
return dbg_not_on_a_line_number; return dbg_not_on_a_line_number;
if (!types_get_info(sym->ModBase, sym->TypeIndex, TI_GET_LENGTH, &size) || size == 0) type.module = sym->ModBase;
type.id = sym->TypeIndex;
if (!types_get_info(&type, TI_GET_LENGTH, &size) || size == 0)
size = 0x100000; size = 0x100000;
if (il.FileName && il.FileName[0] && disp < size) if (il.FileName && il.FileName[0] && disp < size)
return (disp == 0) ? dbg_on_a_line_number : dbg_not_on_a_line_number; return (disp == 0) ? dbg_on_a_line_number : dbg_not_on_a_line_number;
...@@ -492,14 +507,16 @@ BOOL symbol_get_line(const char* filename, const char* name, IMAGEHLP_LINE* line ...@@ -492,14 +507,16 @@ BOOL symbol_get_line(const char* filename, const char* name, IMAGEHLP_LINE* line
static BOOL CALLBACK info_locals_cb(SYMBOL_INFO* sym, ULONG size, void* ctx) static BOOL CALLBACK info_locals_cb(SYMBOL_INFO* sym, ULONG size, void* ctx)
{ {
DWORD tid; ULONG v, val;
ULONG v, val; const char* explain = NULL;
const char* explain = NULL; char buf[128];
char buf[128]; struct dbg_type type;
dbg_printf("\t"); dbg_printf("\t");
types_get_info(sym->ModBase, sym->TypeIndex, TI_GET_TYPE, &tid); type.module = sym->ModBase;
types_print_type(sym->ModBase, tid, FALSE); type.id = sym->TypeIndex;
types_get_info(&type, TI_GET_TYPE, &type.id);
types_print_type(&type, FALSE);
if (sym->Flags & SYMFLAG_LOCAL) explain = "local"; if (sym->Flags & SYMFLAG_LOCAL) explain = "local";
else if (sym->Flags & SYMFLAG_PARAMETER) explain = "parameter"; else if (sym->Flags & SYMFLAG_PARAMETER) explain = "parameter";
...@@ -527,7 +544,8 @@ static BOOL CALLBACK info_locals_cb(SYMBOL_INFO* sym, ULONG size, void* ctx) ...@@ -527,7 +544,8 @@ static BOOL CALLBACK info_locals_cb(SYMBOL_INFO* sym, ULONG size, void* ctx)
} }
else if (sym->Flags & SYMFLAG_FRAMEREL) else if (sym->Flags & SYMFLAG_FRAMEREL)
{ {
types_get_info(sym->ModBase, sym->TypeIndex, TI_GET_OFFSET, &v); type.id = sym->TypeIndex;
types_get_info(&type, TI_GET_OFFSET, &v);
v += ((IMAGEHLP_STACK_FRAME*)ctx)->FrameOffset; v += ((IMAGEHLP_STACK_FRAME*)ctx)->FrameOffset;
dbg_read_memory_verbose((void*)v, &val, sizeof(val)); dbg_read_memory_verbose((void*)v, &val, sizeof(val));
...@@ -556,13 +574,13 @@ int symbol_info_locals(void) ...@@ -556,13 +574,13 @@ int symbol_info_locals(void)
static BOOL CALLBACK symbols_info_cb(SYMBOL_INFO* sym, ULONG size, void* ctx) static BOOL CALLBACK symbols_info_cb(SYMBOL_INFO* sym, ULONG size, void* ctx)
{ {
DWORD type; struct dbg_type type;
dbg_printf("%08lx: %s (", sym->Address, sym->Name); dbg_printf("%08lx: %s (", sym->Address, sym->Name);
if (sym->TypeIndex != dbg_itype_none && sym->TypeIndex != 0 && if (sym->TypeIndex != dbg_itype_none && sym->TypeIndex != 0 &&
types_get_info(sym->ModBase, sym->TypeIndex, TI_GET_TYPE, &type)) types_get_info(&type, TI_GET_TYPE, &type.id))
{ {
types_print_type(sym->ModBase, type, FALSE); types_print_type(&type, FALSE);
} }
dbg_printf(")\n"); dbg_printf(")\n");
return TRUE; return TRUE;
......
...@@ -45,6 +45,9 @@ ...@@ -45,6 +45,9 @@
* + make the output as close as possible to what gdb does * + make the output as close as possible to what gdb does
* - symbol management: * - symbol management:
* + symbol table loading is broken * + symbol table loading is broken
* + in symbol_get_lvalue, we don't do any scoping (as C does) between local and
* global vars (we may need this to force some display for example). A solution
* would be always to return arrays with: local vars, global vars, thunks
* - type management: * - type management:
* + some bits of internal types are missing (like type casts and the address * + some bits of internal types are missing (like type casts and the address
* operator) * operator)
...@@ -55,7 +58,10 @@ ...@@ -55,7 +58,10 @@
* o bitfield size is on a 4-bytes * o bitfield size is on a 4-bytes
* + some bits of internal types are missing (like type casts and the address * + some bits of internal types are missing (like type casts and the address
* operator) * operator)
* - execution * - execution:
* + display: we shouldn't need to tell whether a display is local or not. This
* should be automatically guessed by checking whether the variables that are
* references are local or not
* + set a better fix for gdb (proxy mode) than the step-mode hack * + set a better fix for gdb (proxy mode) than the step-mode hack
* + implement function call in debuggee * + implement function call in debuggee
* + trampoline management is broken when getting 16 <=> 32 thunk destination * + trampoline management is broken when getting 16 <=> 32 thunk destination
...@@ -339,6 +345,8 @@ struct dbg_thread* dbg_add_thread(struct dbg_process* p, DWORD tid, ...@@ -339,6 +345,8 @@ struct dbg_thread* dbg_add_thread(struct dbg_process* p, DWORD tid,
t->wait_for_first_exception = 0; t->wait_for_first_exception = 0;
t->exec_mode = dbg_exec_cont; t->exec_mode = dbg_exec_cont;
t->exec_count = 0; t->exec_count = 0;
t->step_over_bp.enabled = FALSE;
t->step_over_bp.refcount = 0;
snprintf(t->name, sizeof(t->name), "0x%08lx", tid); snprintf(t->name, sizeof(t->name), "0x%08lx", tid);
...@@ -354,8 +362,8 @@ static void dbg_init_current_thread(void* start) ...@@ -354,8 +362,8 @@ static void dbg_init_current_thread(void* start)
{ {
if (start) if (start)
{ {
if (dbg_curr_thread->process->threads && if (dbg_curr_process->threads &&
!dbg_curr_thread->process->threads->next && /* first thread ? */ !dbg_curr_process->threads->next && /* first thread ? */
DBG_IVAR(BreakAllThreadsStartup)) DBG_IVAR(BreakAllThreadsStartup))
{ {
ADDRESS addr; ADDRESS addr;
...@@ -562,8 +570,7 @@ static DWORD dbg_handle_exception(EXCEPTION_RECORD* rec, BOOL first_chance, ...@@ -562,8 +570,7 @@ static DWORD dbg_handle_exception(EXCEPTION_RECORD* rec, BOOL first_chance,
else else
pThread = dbg_get_thread(dbg_curr_process, pThreadName->dwThreadID); pThread = dbg_get_thread(dbg_curr_process, pThreadName->dwThreadID);
if (ReadProcessMemory(dbg_curr_thread->process->handle, pThreadName->szName, if (dbg_read_memory(pThreadName->szName, pThread->name, 9))
pThread->name, 9, NULL))
dbg_printf("Thread ID=0x%lx renamed using MS VC6 extension (name==\"%s\")\n", dbg_printf("Thread ID=0x%lx renamed using MS VC6 extension (name==\"%s\")\n",
pThread->tid, pThread->name); pThread->tid, pThread->name);
return DBG_CONTINUE; return DBG_CONTINUE;
...@@ -636,11 +643,11 @@ static DWORD dbg_handle_exception(EXCEPTION_RECORD* rec, BOOL first_chance, ...@@ -636,11 +643,11 @@ static DWORD dbg_handle_exception(EXCEPTION_RECORD* rec, BOOL first_chance,
case EXCEPTION_WINE_STUB: case EXCEPTION_WINE_STUB:
{ {
char dll[32], name[64]; char dll[32], name[64];
memory_get_string(dbg_curr_thread->process->handle, memory_get_string(dbg_curr_process->handle,
(void*)rec->ExceptionInformation[0], DLV_TARGET, FALSE, (void*)rec->ExceptionInformation[0], TRUE, FALSE,
dll, sizeof(dll)); dll, sizeof(dll));
memory_get_string(dbg_curr_thread->process->handle, memory_get_string(dbg_curr_process->handle,
(void*)rec->ExceptionInformation[1], DLV_TARGET, FALSE, (void*)rec->ExceptionInformation[1], TRUE, FALSE,
name, sizeof(name)); name, sizeof(name));
dbg_printf("unimplemented function %s.%s called", dll, name); dbg_printf("unimplemented function %s.%s called", dll, name);
} }
...@@ -854,7 +861,7 @@ static unsigned dbg_handle_debug_event(DEBUG_EVENT* de) ...@@ -854,7 +861,7 @@ static unsigned dbg_handle_debug_event(DEBUG_EVENT* de)
WINE_ERR("Unknown thread\n"); WINE_ERR("Unknown thread\n");
break; break;
} }
memory_get_string_indirect(dbg_curr_thread->process->handle, memory_get_string_indirect(dbg_curr_process->handle,
de->u.LoadDll.lpImageName, de->u.LoadDll.lpImageName,
de->u.LoadDll.fUnicode, de->u.LoadDll.fUnicode,
buffer, sizeof(buffer)); buffer, sizeof(buffer));
...@@ -894,8 +901,8 @@ static unsigned dbg_handle_debug_event(DEBUG_EVENT* de) ...@@ -894,8 +901,8 @@ static unsigned dbg_handle_debug_event(DEBUG_EVENT* de)
break; break;
} }
memory_get_string(dbg_curr_thread->process->handle, memory_get_string(dbg_curr_process->handle,
de->u.DebugString.lpDebugStringData, DLV_TARGET, de->u.DebugString.lpDebugStringData, TRUE,
de->u.DebugString.fUnicode, buffer, sizeof(buffer)); de->u.DebugString.fUnicode, buffer, sizeof(buffer));
WINE_TRACE("%08lx:%08lx: output debug string (%s)\n", WINE_TRACE("%08lx:%08lx: output debug string (%s)\n",
de->dwProcessId, de->dwThreadId, buffer); de->dwProcessId, de->dwThreadId, buffer);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment