diff --git a/documentation/debugger.sgml b/documentation/debugger.sgml index 43d97efef19..17e611cc67c 100644 --- a/documentation/debugger.sgml +++ b/documentation/debugger.sgml @@ -1683,17 +1683,19 @@ set $BreakAllThreadsStartup = 1 - - - display - - info display - - - + info display lists the active displays + + + display + + + print the active displays' values (as done each + time the debugger stops) + + display <expr> diff --git a/programs/winedbg/break.c b/programs/winedbg/break.c index c78258b92ba..707ba5f795a 100644 --- a/programs/winedbg/break.c +++ b/programs/winedbg/break.c @@ -59,8 +59,7 @@ void break_set_xpoints(BOOL set) for (i = 0; i < dbg_curr_process->next_bp; i++) { - if (!bp[i].refcount && !bp[i].enabled) - continue; + if (!bp[i].refcount || !bp[i].enabled) continue; if (bp[i].xpoint_type == be_xpoint_break) size = 0; @@ -78,8 +77,9 @@ void break_set_xpoints(BOOL set) bp[i].info, size); if (!ret) { - dbg_printf("Invalid address (%p) for breakpoint %d, disabling it\n", - addr, i); + dbg_printf("Invalid address ("); + print_address(&bp[i].addr, FALSE); + dbg_printf(") for breakpoint %d, disabling it\n", i); bp[i].enabled = FALSE; } } @@ -375,10 +375,9 @@ void break_add_watch(const struct dbg_lvalue* lvalue, BOOL is_write) &lvalue->addr); 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), - lvalue->typeid, TI_GET_LENGTH, &l)) + if (types_get_info(&lvalue->type, TI_GET_LENGTH, &l)) { switch (l) { @@ -679,7 +678,7 @@ static BOOL should_stop(int bpnum) { 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. diff --git a/programs/winedbg/dbg.y b/programs/winedbg/dbg.y index e991508413e..5fab86575ec 100644 --- a/programs/winedbg/dbg.y +++ b/programs/winedbg/dbg.y @@ -133,7 +133,7 @@ command: | tSOURCE pathname { parser($2); } | tSYMBOLFILE pathname { symbol_read_symtable($2, 0); } | 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); } | tDETACH { dbg_detach_debuggee(); } | run_command @@ -202,8 +202,8 @@ set_command: ; x_command: - tEXAM expr_lvalue { memory_examine(&$2, 1, 'x'); } - | tEXAM tFORMAT expr_lvalue { memory_examine(&$3, $2 >> 8, $2 & 0xff); } + tEXAM expr_rvalue { memory_examine((void*)$2, 1, 'x'); } + | tEXAM tFORMAT expr_rvalue { memory_examine((void*)$3, $2 >> 8, $2 & 0xff); } ; print_command: @@ -231,7 +231,7 @@ watch_command: ; display_command: - tDISPLAY { display_info(); } + tDISPLAY { display_print(); } | tDISPLAY expr { display_add($2, 1, 0, FALSE); } | tDISPLAY tFORMAT expr { display_add($3, $2 >> 8, $2 & 0xff, FALSE); } | tLOCAL tDISPLAY expr { display_add($3, 1, 0, TRUE); } @@ -280,27 +280,27 @@ noprocess_state: ; type_expr: - tCHAR { $$.type = type_expr_type_id; $$.deref_count = 0; $$.u.typeid = dbg_itype_char; } - | tINT { $$.type = type_expr_type_id; $$.deref_count = 0; $$.u.typeid = dbg_itype_signed_int; } - | tLONG tINT { $$.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.typeid = dbg_itype_signed_long_int; } - | tUNSIGNED tINT { $$.type = type_expr_type_id; $$.deref_count = 0; $$.u.typeid = dbg_itype_unsigned_int; } - | tUNSIGNED { $$.type = type_expr_type_id; $$.deref_count = 0; $$.u.typeid = dbg_itype_unsigned_int; } - | tLONG tUNSIGNED tINT { $$.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.typeid = dbg_itype_unsigned_long_int; } - | tSHORT tINT { $$.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.typeid = 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 { $$.type = type_expr_type_id; $$.deref_count = 0; $$.u.typeid = dbg_itype_unsigned_short_int; } - | tSIGNED tCHAR { $$.type = type_expr_type_id; $$.deref_count = 0; $$.u.typeid = dbg_itype_signed_char_int; } - | tUNSIGNED tCHAR { $$.type = type_expr_type_id; $$.deref_count = 0; $$.u.typeid = 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 { $$.type = type_expr_type_id; $$.deref_count = 0; $$.u.typeid = 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 { $$.type = type_expr_type_id; $$.deref_count = 0; $$.u.typeid = dbg_itype_signed_longlong_int; } - | tFLOAT { $$.type = type_expr_type_id; $$.deref_count = 0; $$.u.typeid = dbg_itype_short_real; } - | tDOUBLE { $$.type = type_expr_type_id; $$.deref_count = 0; $$.u.typeid = dbg_itype_real; } - | tLONG tDOUBLE { $$.type = type_expr_type_id; $$.deref_count = 0; $$.u.typeid = dbg_itype_long_real; } + 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.type.module = 0; $$.u.type.id = dbg_itype_signed_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.type.module = 0; $$.u.type.id = dbg_itype_signed_long_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.type.module = 0; $$.u.type.id = dbg_itype_unsigned_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.type.module = 0; $$.u.type.id = dbg_itype_unsigned_long_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.type.module = 0; $$.u.type.id = dbg_itype_signed_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.type.module = 0; $$.u.type.id = dbg_itype_unsigned_short_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.type.module = 0; $$.u.type.id = dbg_itype_unsigned_char_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.type.module = 0; $$.u.type.id = dbg_itype_unsigned_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.type.module = 0; $$.u.type.id = dbg_itype_signed_longlong_int; } + | 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.type.module = 0; $$.u.type.id = dbg_itype_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++; } | 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); } diff --git a/programs/winedbg/debugger.h b/programs/winedbg/debugger.h index 23c9c9154d5..d89f1893ec7 100644 --- a/programs/winedbg/debugger.h +++ b/programs/winedbg/debugger.h @@ -82,6 +82,18 @@ enum dbg_internal_types 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... */ { int cookie; /* DLV_??? */ @@ -91,7 +103,7 @@ struct dbg_lvalue /* structure to hold left-values... */ # define DLV_TARGET 0xF00D # define DLV_HOST 0x50DA ADDRESS addr; - unsigned long typeid; + struct dbg_type type; }; enum dbg_exec_mode @@ -202,7 +214,7 @@ struct dbg_internal_var DWORD val; const char* name; LPDWORD pval; - unsigned long typeid; + unsigned long typeid; /* always internal type */ }; enum sym_get_lval {sglv_found, sglv_unknown, sglv_aborted}; @@ -222,7 +234,7 @@ struct type_expr_t unsigned deref_count; union { - unsigned long typeid; + struct dbg_type type; const char* name; } u; }; @@ -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); /* 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 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_to_linear_addr(const ADDRESS* address); extern BOOL memory_get_current_pc(ADDRESS* address); extern BOOL memory_get_current_stack(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 void memory_disassemble(const struct dbg_lvalue*, const struct dbg_lvalue*, int offset); extern BOOL memory_disasm_one_insn(ADDRESS* addr); @@ -333,16 +345,15 @@ extern int symbol_info_locals(void); /* types.c */ 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 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_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_get_info(unsigned long, unsigned long, - IMAGEHLP_SYMBOL_TYPE_INFO, void*); -extern unsigned long types_find_pointer(unsigned long linear, unsigned long typeid); -extern unsigned long types_find_type(unsigned long linear, const char* name, enum SymTagEnum tag); +extern BOOL types_get_info(const struct dbg_type*, IMAGEHLP_SYMBOL_TYPE_INFO, void*); +extern struct dbg_type types_find_pointer(const struct dbg_type* type); +extern struct dbg_type types_find_type(unsigned long linear, const char* name, enum SymTagEnum tag); /* winedbg.c */ extern void dbg_outputA(const char* buffer, int len); diff --git a/programs/winedbg/display.c b/programs/winedbg/display.c index e72f33eb03d..f49a7011d9c 100644 --- a/programs/winedbg/display.c +++ b/programs/winedbg/display.c @@ -43,10 +43,18 @@ struct display static struct display *displaypoints = NULL; 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) { - if (si1->NameLen != si2->NameLen) return FALSE; - return !memcmp(si1, si2, sizeof(SYMBOL_INFO) + si1->NameLen); + /* FIXME: !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) @@ -74,6 +82,7 @@ int display_add(struct expr *exp, int count, char format, int in_frame) if (in_frame) { 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->MaxNameLen = sizeof(displaypoints[i].func_buffer) - sizeof(*displaypoints[i].func); @@ -97,6 +106,7 @@ int display_info(void) const char* info; func = (SYMBOL_INFO*)buffer; + memset(func, 0, sizeof(SYMBOL_INFO)); func->SizeOfStruct = sizeof(SYMBOL_INFO); func->MaxNameLen = sizeof(buffer) - sizeof(*func); if (!stack_get_frame(func, NULL)) return FALSE; @@ -105,6 +115,9 @@ int display_info(void) { if (displaypoints[i].exp == NULL) continue; + dbg_printf("%d: ", i + 1); + expr_print(displaypoints[i].exp); + if (displaypoints[i].enabled) { if (displaypoints[i].func && !cmp_symbol(displaypoints[i].func, func)) @@ -114,10 +127,9 @@ int display_info(void) } else info = " (disabled)"; - dbg_printf("%d in %s%s: ", - i + 1, func ? displaypoints[i].func->Name : "", info); - expr_print(displaypoints[i].exp); - dbg_printf("\n"); + if (displaypoints[i].func) + dbg_printf(" in %s", displaypoints[i].func->Name); + dbg_printf("%s\n", info); } return TRUE; } @@ -129,7 +141,7 @@ static void print_one_display(int i) if (displaypoints[i].enabled) { 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 "); expr_print(displaypoints[i].exp); @@ -146,7 +158,8 @@ static void print_one_display(int i) dbg_printf("(disabled)\n"); else 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 print_value(&lvalue, displaypoints[i].format, 0); } @@ -158,6 +171,7 @@ int display_print(void) SYMBOL_INFO* func; func = (SYMBOL_INFO*)buffer; + memset(func, 0, sizeof(SYMBOL_INFO)); func->SizeOfStruct = sizeof(SYMBOL_INFO); func->MaxNameLen = sizeof(buffer) - sizeof(*func); if (!stack_get_frame(func, NULL)) return FALSE; @@ -226,6 +240,7 @@ int display_enable(int displaynum, int enable) SYMBOL_INFO* func; func = (SYMBOL_INFO*)buffer; + memset(func, 0, sizeof(SYMBOL_INFO)); func->SizeOfStruct = sizeof(SYMBOL_INFO); func->MaxNameLen = sizeof(buffer) - sizeof(*func); if (!stack_get_frame(func, NULL)) return FALSE; diff --git a/programs/winedbg/expr.c b/programs/winedbg/expr.c index 2fcf73348f4..eda0e9be4dd 100644 --- a/programs/winedbg/expr.c +++ b/programs/winedbg/expr.c @@ -282,13 +282,13 @@ struct dbg_lvalue expr_eval(struct expr* exp) struct dbg_lvalue exp2; unsigned int cexp[5]; DWORD scale1, scale2, scale3; - DWORD type1, type2; - DWORD linear1, linear2; + struct dbg_type type1, type2; DWORD tag; const struct dbg_internal_var* div; - - rtn.typeid = dbg_itype_none; + rtn.cookie = 0; + rtn.type.id = dbg_itype_none; + rtn.type.module = 0; rtn.addr.Mode = AddrModeFlat; rtn.addr.Offset = 0; rtn.addr.Segment = 0; @@ -300,30 +300,31 @@ struct dbg_lvalue expr_eval(struct expr* exp) * checking if this is right or not */ rtn = expr_eval(exp->un.cast.expr); - linear1 = (DWORD)memory_to_linear_addr(&rtn.addr); switch (exp->un.cast.cast_to.type) { case type_expr_type_id: - if (exp->un.cast.cast_to.u.typeid == dbg_itype_none) + if (exp->un.cast.cast_to.u.type.id == dbg_itype_none) { dbg_printf("Can't cast to unknown type\n"); RaiseException(DEBUG_STATUS_BAD_TYPE, 0, 0, NULL); } - rtn.typeid = exp->un.cast.cast_to.u.typeid; + rtn.type = exp->un.cast.cast_to.u.type; break; case type_expr_udt_class: case type_expr_udt_struct: case type_expr_udt_union: - rtn.typeid = types_find_type(linear1, exp->un.cast.cast_to.u.name, SymTagUDT); - if (rtn.typeid == dbg_itype_none) + rtn.type = types_find_type((DWORD)memory_to_linear_addr(&rtn.addr), + exp->un.cast.cast_to.u.name, SymTagUDT); + if (rtn.type.id == dbg_itype_none) { dbg_printf("Can't cast to UDT %s\n", exp->un.cast.cast_to.u.name); RaiseException(DEBUG_STATUS_BAD_TYPE, 0, 0, NULL); } break; case type_expr_enumeration: - rtn.typeid = types_find_type(linear1, exp->un.cast.cast_to.u.name, SymTagEnum); - if (rtn.typeid == dbg_itype_none) + rtn.type = types_find_type((DWORD)memory_to_linear_addr(&rtn.addr), + exp->un.cast.cast_to.u.name, SymTagEnum); + if (rtn.type.id == dbg_itype_none) { dbg_printf("Can't cast to enumeration %s\n", exp->un.cast.cast_to.u.name); RaiseException(DEBUG_STATUS_BAD_TYPE, 0, 0, NULL); @@ -335,8 +336,8 @@ struct dbg_lvalue expr_eval(struct expr* exp) } for (i = 0; i < exp->un.cast.cast_to.deref_count; i++) { - rtn.typeid = types_find_pointer(linear1, rtn.typeid); - if (rtn.typeid == dbg_itype_none) + rtn.type = types_find_pointer(&rtn.type); + if (rtn.type.id == dbg_itype_none) { dbg_printf("Cannot find pointer type\n"); RaiseException(DEBUG_STATUS_BAD_TYPE, 0, 0, NULL); @@ -344,18 +345,21 @@ struct dbg_lvalue expr_eval(struct expr* exp) } break; case EXPR_TYPE_STRING: - rtn.typeid = dbg_itype_astring; - rtn.cookie = DLV_HOST; + rtn.cookie = DLV_HOST; + rtn.type.id = dbg_itype_astring; + rtn.type.module = 0; rtn.addr.Offset = (unsigned int)&exp->un.string.str; break; case EXPR_TYPE_U_CONST: - rtn.typeid = dbg_itype_unsigned_int; rtn.cookie = DLV_HOST; + rtn.type.id = dbg_itype_unsigned_int; + rtn.type.module = 0; rtn.addr.Offset = (unsigned int)&exp->un.u_const.value; break; case EXPR_TYPE_S_CONST: - rtn.typeid = dbg_itype_signed_int; rtn.cookie = DLV_HOST; + rtn.type.id = dbg_itype_signed_int; + rtn.type.module = 0; rtn.addr.Offset = (unsigned int)&exp->un.s_const.value; break; case EXPR_TYPE_SYMBOL: @@ -373,8 +377,8 @@ struct dbg_lvalue expr_eval(struct expr* exp) break; case EXPR_TYPE_PSTRUCT: exp1 = expr_eval(exp->un.structure.exp1); - if (exp1.typeid == dbg_itype_none || !types_deref(&exp1, &rtn) || - rtn.typeid == dbg_itype_none) + if (exp1.type.id == dbg_itype_none || !types_deref(&exp1, &rtn) || + rtn.type.id == dbg_itype_none) RaiseException(DEBUG_STATUS_BAD_TYPE, 0, 0, NULL); if (!types_udt_find_element(&rtn, exp->un.structure.element_name, &exp->un.structure.result)) @@ -385,7 +389,7 @@ struct dbg_lvalue expr_eval(struct expr* exp) break; case EXPR_TYPE_STRUCT: exp1 = expr_eval(exp->un.structure.exp1); - if (exp1.typeid == dbg_itype_none) RaiseException(DEBUG_STATUS_BAD_TYPE, 0, 0, NULL); + if (exp1.type.id == dbg_itype_none) RaiseException(DEBUG_STATUS_BAD_TYPE, 0, 0, NULL); rtn = exp1; if (!types_udt_find_element(&rtn, exp->un.structure.element_name, &exp->un.structure.result)) @@ -402,7 +406,7 @@ struct dbg_lvalue expr_eval(struct expr* exp) for (i = 0; i < exp->un.call.nargs; i++) { exp1 = expr_eval(exp->un.call.arg[i]); - if (exp1.typeid == dbg_itype_none) + if (exp1.type.id == dbg_itype_none) RaiseException(DEBUG_STATUS_BAD_TYPE, 0, 0, NULL); cexp[i] = types_extract_as_integer(&exp1); } @@ -458,93 +462,93 @@ struct dbg_lvalue expr_eval(struct expr* exp) */ exp->un.call.result = 0; #endif - linear1 = (DWORD)memory_to_linear_addr(&rtn.addr); - /* get function signature type */ - types_get_info(linear1, rtn.typeid, TI_GET_TYPE, &rtn.typeid); - /* and now, return type */ - types_get_info(linear1, rtn.typeid, TI_GET_TYPE, &rtn.typeid); rtn.cookie = DLV_HOST; - rtn.addr.Mode = AddrModeFlat; + /* get function signature type */ + types_get_info(&rtn.type, TI_GET_TYPE, &rtn.type); + /* and now, return type */ + types_get_info(&rtn.type, TI_GET_TYPE, &rtn.type); rtn.addr.Offset = (unsigned int)&exp->un.call.result; break; case EXPR_TYPE_INTVAR: + rtn.cookie = DLV_HOST; if (!(div = dbg_get_internal_var(exp->un.intvar.name))) RaiseException(DEBUG_STATUS_NO_SYMBOL, 0, 0, NULL); - rtn.cookie = DLV_HOST; - rtn.typeid = div->typeid; + rtn.type.id = div->typeid; + rtn.type.module = 0; rtn.addr.Offset = (unsigned int)div->pval; break; case EXPR_TYPE_BINOP: + rtn.cookie = DLV_HOST; exp1 = expr_eval(exp->un.binop.exp1); exp2 = expr_eval(exp->un.binop.exp2); - rtn.cookie = DLV_HOST; - if (exp1.typeid == dbg_itype_none || exp2.typeid == dbg_itype_none) + if (exp1.type.id == dbg_itype_none || exp2.type.id == dbg_itype_none) RaiseException(DEBUG_STATUS_BAD_TYPE, 0, 0, NULL); - linear1 = (DWORD)memory_to_linear_addr(&exp1.addr); - linear2 = (DWORD)memory_to_linear_addr(&exp2.addr); - rtn.typeid = dbg_itype_signed_int; + rtn.type.id = dbg_itype_signed_int; + rtn.type.module = 0; rtn.addr.Offset = (unsigned int)&exp->un.binop.result; switch (exp->un.binop.binop_type) { case EXP_OP_ADD: - if (!types_get_info(linear1, exp1.typeid, TI_GET_SYMTAG, &tag) || + if (!types_get_info(&exp1.type, TI_GET_SYMTAG, &tag) || tag != SymTagPointerType || - !types_get_info(linear1, exp1.typeid, TI_GET_TYPE, &type1)) - type1 = dbg_itype_none; - if (!types_get_info(linear1, exp2.typeid, TI_GET_SYMTAG, &tag) || + !types_get_info(&exp1.type, TI_GET_TYPE, &type1)) + type1.id = dbg_itype_none; + if (!types_get_info(&exp2.type, TI_GET_SYMTAG, &tag) || tag != SymTagPointerType || - !types_get_info(linear1, exp2.typeid, TI_GET_TYPE, &type2)) - type2 = dbg_itype_none; + !types_get_info(&exp2.type, TI_GET_TYPE, &type2)) + type2.id = dbg_itype_none; scale1 = 1; scale2 = 1; - if (type1 != dbg_itype_none && type2 != dbg_itype_none) + if (type1.id != dbg_itype_none && type2.id != dbg_itype_none) RaiseException(DEBUG_STATUS_BAD_TYPE, 0, 0, NULL); - if (type1 != dbg_itype_none) + if (type1.id != dbg_itype_none) { - types_get_info(linear1, type1, TI_GET_LENGTH, &scale2); - rtn.typeid = exp1.typeid; + types_get_info(&type1, TI_GET_LENGTH, &scale2); + rtn.type = exp1.type; } - else if (type2 != dbg_itype_none) + else if (type2.id != dbg_itype_none) { - types_get_info(linear2, type2, TI_GET_LENGTH, &scale1); - rtn.typeid = exp2.typeid; + types_get_info(&type2, TI_GET_LENGTH, &scale1); + rtn.type = exp2.type; } exp->un.binop.result = (types_extract_as_integer(&exp1) * scale1 + scale2 * types_extract_as_integer(&exp2)); break; case EXP_OP_SUB: - if (!types_get_info(linear1, exp1.typeid, TI_GET_SYMTAG, &tag) || + if (!types_get_info(&exp1.type, TI_GET_SYMTAG, &tag) || tag != SymTagPointerType || - !types_get_info(linear1, exp1.typeid, TI_GET_TYPE, &type1)) - type1 = dbg_itype_none; - if (!types_get_info(linear2, exp2.typeid, TI_GET_SYMTAG, &tag) || + !types_get_info(&exp1.type, TI_GET_TYPE, &type1)) + type1.id = dbg_itype_none; + if (!types_get_info(&exp2.type, TI_GET_SYMTAG, &tag) || tag != SymTagPointerType || - !types_get_info(linear2, exp2.typeid, TI_GET_TYPE, &type2)) - type2 = dbg_itype_none; + !types_get_info(&exp2.type, TI_GET_TYPE, &type2)) + type2.id = dbg_itype_none; scale1 = 1; scale2 = 1; scale3 = 1; - if (type1 != dbg_itype_none && type2 != dbg_itype_none) + if (type1.id != dbg_itype_none && type2.id != dbg_itype_none) { - if (type1 != type2) RaiseException(DEBUG_STATUS_BAD_TYPE, 0, 0, NULL); - types_get_info(linear1, type1, TI_GET_LENGTH, &scale3); + WINE_FIXME("This may fail (if module base address are wrongly calculated)\n"); + if (memcmp(&type1, &type2, sizeof(struct dbg_type))) + RaiseException(DEBUG_STATUS_BAD_TYPE, 0, 0, NULL); + types_get_info(&type1, TI_GET_LENGTH, &scale3); } - else if (type1 != dbg_itype_none) + else if (type1.id != dbg_itype_none) { - types_get_info(linear1, type1, TI_GET_LENGTH, &scale2); - rtn.typeid = exp1.typeid; + types_get_info(&type1, TI_GET_LENGTH, &scale2); + rtn.type = exp1.type; } - else if (type2 != dbg_itype_none) + else if (type2.id != dbg_itype_none) { - types_get_info(linear2, type2, TI_GET_LENGTH, &scale1); - rtn.typeid = exp2.typeid; + types_get_info(&type2, TI_GET_LENGTH, &scale1); + rtn.type = exp2.type; } exp->un.binop.result = (types_extract_as_integer(&exp1) * scale1 - types_extract_as_integer(&exp2) * scale2) / scale3; break; case EXP_OP_SEG: - rtn.cookie = DLV_TARGET; - rtn.typeid = dbg_itype_none; + rtn.type.id = dbg_itype_none; + rtn.type.module = 0; rtn.addr.Mode = AddrMode1632; rtn.addr.Segment = types_extract_as_integer(&exp1); rtn.addr.Offset = types_extract_as_integer(&exp2); @@ -607,11 +611,12 @@ struct dbg_lvalue expr_eval(struct expr* exp) } break; case EXPR_TYPE_UNOP: - exp1 = expr_eval(exp->un.unop.exp1); - if (exp1.typeid == dbg_itype_none) RaiseException(DEBUG_STATUS_BAD_TYPE, 0, 0, NULL); rtn.cookie = DLV_HOST; + exp1 = expr_eval(exp->un.unop.exp1); + if (exp1.type.id == dbg_itype_none) RaiseException(DEBUG_STATUS_BAD_TYPE, 0, 0, NULL); rtn.addr.Offset = (unsigned int)&exp->un.unop.result; - rtn.typeid = dbg_itype_signed_int; + rtn.type.id = dbg_itype_signed_int; + rtn.type.module = 0; switch (exp->un.unop.unop_type) { case EXP_OP_NEG: @@ -624,19 +629,6 @@ struct dbg_lvalue expr_eval(struct expr* exp) exp->un.unop.result = ~types_extract_as_integer(&exp1); break; case EXP_OP_DEREF: - /* FIXME: this is currently buggy. - * there is no way to tell were the deref:ed value is... - * for example: - * x is a pointer to struct s, x being on the stack - * => exp1 is target, result is target - * x is a pointer to struct s, x being optimized into a reg - * => exp1 is host, result is target - * x is a pointer to internal variable x - * => exp1 is host, result is host - * so we force DLV_TARGET, because dereferencing pointers to - * internal variables is very unlikely. a correct fix would be - * rather large. - */ if (!types_deref(&exp1, &rtn)) RaiseException(DEBUG_STATUS_BAD_TYPE, 0, 0, NULL); break; @@ -650,7 +642,7 @@ struct dbg_lvalue expr_eval(struct expr* exp) if (exp1.addr.Mode != AddrModeFlat) RaiseException(DEBUG_STATUS_CANT_DEREF, 0, 0, NULL); exp->un.unop.result = (unsigned int)memory_to_linear_addr(&exp1.addr); - rtn.typeid = types_find_pointer(exp->un.unop.result, exp1.typeid); + rtn.type = types_find_pointer(&exp1.type); break; default: RaiseException(DEBUG_STATUS_INTERNAL_ERROR, 0, 0, NULL); } @@ -661,14 +653,13 @@ struct dbg_lvalue expr_eval(struct expr* exp) break; } - assert(rtn.cookie == DLV_TARGET || rtn.cookie == DLV_HOST); - return rtn; } int expr_print(const struct expr* exp) { - int i; + int i; + struct dbg_type type; switch (exp->type) { @@ -678,7 +669,9 @@ int expr_print(const struct expr* exp) switch (exp->un.cast.cast_to.type) { case type_expr_type_id: - types_print_type(0, exp->un.cast.cast_to.type, FALSE); break; + type.module = 0; + type.id = exp->un.cast.cast_to.type; + types_print_type(&type, FALSE); break; case type_expr_udt_class: dbg_printf("class %s", exp->un.cast.cast_to.u.name); break; case type_expr_udt_struct: diff --git a/programs/winedbg/gdbproxy.c b/programs/winedbg/gdbproxy.c index 0665778ad72..f39861da4ab 100644 --- a/programs/winedbg/gdbproxy.c +++ b/programs/winedbg/gdbproxy.c @@ -468,7 +468,7 @@ static void handle_debug_event(struct gdb_context* gdbctx, DEBUG_EVENT* de) case OUTPUT_DEBUG_STRING_EVENT: assert(dbg_curr_thread); memory_get_string(gdbctx->process->handle, - de->u.DebugString.lpDebugStringData, DLV_TARGET, + de->u.DebugString.lpDebugStringData, TRUE, de->u.DebugString.fUnicode, buffer, sizeof(buffer)); if (gdbctx->trace & GDBPXY_TRC_WIN32_EVENT) fprintf(stderr, "%08lx:%08lx: output debug string (%s)\n", diff --git a/programs/winedbg/memory.c b/programs/winedbg/memory.c index 9976d3d90c3..8d1d16c0c6e 100644 --- a/programs/winedbg/memory.c +++ b/programs/winedbg/memory.c @@ -99,7 +99,6 @@ BOOL memory_read_value(const struct dbg_lvalue* lvalue, DWORD size, void* result } else { - assert(lvalue->addr.Mode == AddrModeFlat); if (!lvalue->addr.Offset) return FALSE; memcpy(result, (void*)lvalue->addr.Offset, size); } @@ -118,7 +117,7 @@ BOOL memory_write_value(const struct dbg_lvalue* lvalue, DWORD size, void* value DWORD linear = (DWORD)memory_to_linear_addr(&lvalue->addr); os = ~size; - types_get_info(linear, lvalue->typeid, TI_GET_LENGTH, &os); + types_get_info(&lvalue->type, TI_GET_LENGTH, &os); assert(size == os); /* FIXME: only works on little endian systems */ @@ -128,7 +127,6 @@ BOOL memory_write_value(const struct dbg_lvalue* lvalue, DWORD size, void* value } else { - assert(lvalue->addr.Mode == AddrModeFlat); memcpy((void*)lvalue->addr.Offset, value, size); } return ret; @@ -139,17 +137,18 @@ BOOL memory_write_value(const struct dbg_lvalue* lvalue, DWORD size, void* value * * Implementation of the 'x' command. */ -void memory_examine(const struct dbg_lvalue* lvalue, int count, char format) +void memory_examine(void* linear, int count, char format) { int i; - ADDRESS x; char buffer[256]; + ADDRESS addr; + + addr.Mode = AddrModeFlat; + addr.Offset = (unsigned long)linear; - x.Mode = AddrModeFlat; - x.Offset = types_extract_as_integer(lvalue); if (format != 'i' && count > 1) { - print_address(&x, FALSE); + print_address(&addr, FALSE); dbg_printf(": "); } @@ -157,32 +156,33 @@ void memory_examine(const struct dbg_lvalue* lvalue, int count, char format) { case 'u': if (count == 1) count = 256; - memory_get_string(dbg_curr_thread->handle, (void*)x.Offset, lvalue->cookie, - TRUE, buffer, min(count, sizeof(buffer))); + memory_get_string(dbg_curr_process->handle, linear, + TRUE, TRUE, buffer, min(count, sizeof(buffer))); dbg_printf("%s\n", buffer); return; case 's': if (count == 1) count = 256; - memory_get_string(dbg_curr_thread->handle, (void*)x.Offset, lvalue->cookie, - FALSE, buffer, min(count, sizeof(buffer))); + memory_get_string(dbg_curr_process->handle, linear, + TRUE, FALSE, buffer, min(count, sizeof(buffer))); dbg_printf("%s\n", buffer); return; case 'i': - while (count-- && memory_disasm_one_insn(&x)); + while (count-- && memory_disasm_one_insn(&addr)); return; case 'g': while (count--) { GUID guid; - if (!dbg_read_memory_verbose((void*)x.Offset, &guid, sizeof(guid))) break; + if (!dbg_read_memory_verbose(linear, &guid, sizeof(guid))) break; dbg_printf("{%08lx-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x}\n", guid.Data1, guid.Data2, guid.Data3, guid.Data4[0], guid.Data4[1], guid.Data4[2], guid.Data4[3], guid.Data4[4], guid.Data4[5], guid.Data4[6], guid.Data4[7]); - x.Offset += sizeof(guid); + linear = (char*)linear + sizeof(guid); + addr.Offset += sizeof(guid); if (count) { - print_address(&x, FALSE); + print_address(&addr, FALSE); dbg_printf(": "); } } @@ -191,13 +191,15 @@ void memory_examine(const struct dbg_lvalue* lvalue, int count, char format) #define DO_DUMP2(_t,_l,_f,_vv) { \ _t _v; \ for (i = 0; i < count; i++) { \ - if (!dbg_read_memory_verbose((void*)x.Offset, &_v, \ + if (!dbg_read_memory_verbose(linear, &_v, \ sizeof(_t))) break; \ dbg_printf(_f, (_vv)); \ - x.Offset += sizeof(_t); \ - if ((i % (_l)) == (_l) - 1) { \ + addr.Offset += sizeof(_t); \ + linear = (char*)linear + sizeof(_t); \ + if ((i % (_l)) == (_l) - 1 && i != count - 1) \ + { \ dbg_printf("\n"); \ - print_address(&x, FALSE); \ + print_address(&addr, FALSE); \ dbg_printf(": "); \ } \ } \ @@ -214,7 +216,7 @@ void memory_examine(const struct dbg_lvalue* lvalue, int count, char format) } } -BOOL memory_get_string(HANDLE hp, void* addr, unsigned cookie, BOOL unicode, +BOOL memory_get_string(HANDLE hp, void* addr, BOOL in_debuggee, BOOL unicode, char* buffer, int size) { DWORD sz; @@ -222,9 +224,8 @@ BOOL memory_get_string(HANDLE hp, void* addr, unsigned cookie, BOOL unicode, buffer[0] = 0; if (!addr) return FALSE; - switch (cookie) + if (in_debuggee) { - case DLV_TARGET: if (!unicode) return ReadProcessMemory(hp, addr, buffer, size, &sz); buffW = HeapAlloc(GetProcessHeap(), 0, size * sizeof(WCHAR)); @@ -232,13 +233,13 @@ BOOL memory_get_string(HANDLE hp, void* addr, unsigned cookie, BOOL unicode, WideCharToMultiByte(CP_ACP, 0, buffW, sz / sizeof(WCHAR), buffer, size, NULL, NULL); HeapFree(GetProcessHeap(), 0, buffW); - return TRUE; - case DLV_HOST: + } + else + { strncpy(buffer, addr, size); buffer[size - 1] = 0; - return TRUE; } - return FALSE; + return TRUE; } BOOL memory_get_string_indirect(HANDLE hp, void* addr, BOOL unicode, char* buffer, int size) @@ -250,7 +251,7 @@ BOOL memory_get_string_indirect(HANDLE hp, void* addr, BOOL unicode, char* buffe if (addr && ReadProcessMemory(hp, addr, &ad, sizeof(ad), &sz) && sz == sizeof(ad) && ad) { - return memory_get_string(hp, ad, DLV_TARGET, unicode, buffer, size); + return memory_get_string(hp, ad, TRUE, unicode, buffer, size); } return FALSE; } @@ -260,20 +261,19 @@ static void print_typed_basic(const struct dbg_lvalue* lvalue) long long int val_int; void* val_ptr; long double val_real; - DWORD tag, size, count, bt, rtype; + DWORD tag, size, count, bt; + struct dbg_type rtype; DWORD linear = (DWORD)memory_to_linear_addr(&lvalue->addr); - assert(lvalue->cookie == DLV_TARGET || lvalue->cookie == DLV_HOST); - - if (lvalue->typeid == dbg_itype_none || - !types_get_info(linear, lvalue->typeid, TI_GET_SYMTAG, &tag)) + if (lvalue->type.id == dbg_itype_none || + !types_get_info(&lvalue->type, TI_GET_SYMTAG, &tag)) return; switch (tag) { case SymTagBaseType: - if (!types_get_info(linear, lvalue->typeid, TI_GET_LENGTH, &size) || - !types_get_info(linear, lvalue->typeid, TI_GET_BASETYPE, &bt)) + if (!types_get_info(&lvalue->type, TI_GET_LENGTH, &size) || + !types_get_info(&lvalue->type, TI_GET_BASETYPE, &bt)) { WINE_ERR("Couldn't get information\n"); RaiseException(DEBUG_STATUS_INTERNAL_ERROR, 0, 0, NULL); @@ -309,20 +309,21 @@ static void print_typed_basic(const struct dbg_lvalue* lvalue) case SymTagPointerType: if (!memory_read_value(lvalue, sizeof(void*), &val_ptr)) return; - if (!types_get_info(linear, lvalue->typeid, TI_GET_TYPE, &rtype) || - rtype == dbg_itype_none) + if (!types_get_info(&lvalue->type, TI_GET_TYPE, &rtype.id) || + rtype.id == dbg_itype_none) { dbg_printf("Internal symbol error: unable to access memory location %p", val_ptr); break; } - - if (types_get_info(linear, rtype, TI_GET_SYMTAG, &tag) && tag == SymTagBaseType && - types_get_info(linear, rtype, TI_GET_BASETYPE, &bt) && bt == btChar && - types_get_info(linear, rtype, TI_GET_LENGTH, &size)) + rtype.module = lvalue->type.module; + if (types_get_info(&rtype, TI_GET_SYMTAG, &tag) && tag == SymTagBaseType && + types_get_info(&rtype, TI_GET_BASETYPE, &bt) && bt == btChar && + types_get_info(&rtype, TI_GET_LENGTH, &size)) { char buffer[1024]; - memory_get_string(dbg_curr_thread->handle, (void*)val_ptr, lvalue->cookie, + memory_get_string(dbg_curr_process->handle, val_ptr, + lvalue->cookie == DLV_TARGET, size == 2, buffer, sizeof(buffer)); dbg_printf("\"%s\"", buffer); } @@ -345,24 +346,27 @@ static void print_typed_basic(const struct dbg_lvalue* lvalue) */ if (!be_cpu->fetch_integer(lvalue, 4, TRUE, &val_int)) return; - if (types_get_info(linear, lvalue->typeid, TI_GET_CHILDRENCOUNT, &count)) + if (types_get_info(&lvalue->type, TI_GET_CHILDRENCOUNT, &count)) { - char buffer[sizeof(TI_FINDCHILDREN_PARAMS) + 256 * sizeof(DWORD)]; - TI_FINDCHILDREN_PARAMS* fcp = (TI_FINDCHILDREN_PARAMS*)buffer; - WCHAR* ptr; - char tmp[256]; - VARIANT variant; - int i; + char buffer[sizeof(TI_FINDCHILDREN_PARAMS) + 256 * sizeof(DWORD)]; + TI_FINDCHILDREN_PARAMS* fcp = (TI_FINDCHILDREN_PARAMS*)buffer; + WCHAR* ptr; + char tmp[256]; + VARIANT variant; + int i; + struct dbg_type type; fcp->Start = 0; while (count) { fcp->Count = min(count, 256); - if (types_get_info(linear, lvalue->typeid, TI_FINDCHILDREN, fcp)) + if (types_get_info(&lvalue->type, TI_FINDCHILDREN, fcp)) { + type.module = linear; for (i = 0; i < min(fcp->Count, count); i++) { - if (!types_get_info(linear, fcp->ChildId[i], TI_GET_VALUE, &variant)) + type.id = fcp->ChildId[i]; + if (!types_get_info(&type, TI_GET_VALUE, &variant)) continue; switch (variant.n1.n2.vt) { @@ -372,7 +376,7 @@ static void print_typed_basic(const struct dbg_lvalue* lvalue) if (ok) { ptr = NULL; - types_get_info(linear, fcp->ChildId[i], TI_GET_SYMNAME, &ptr); + types_get_info(&type, TI_GET_SYMNAME, &ptr); if (!ptr) continue; WideCharToMultiByte(CP_ACP, 0, ptr, -1, tmp, sizeof(tmp), NULL, NULL); HeapFree(GetProcessHeap(), 0, ptr); @@ -404,8 +408,7 @@ void print_basic(const struct dbg_lvalue* lvalue, int count, char format) { long int res; - assert(lvalue->cookie == DLV_TARGET || lvalue->cookie == DLV_HOST); - if (lvalue->typeid == dbg_itype_none) + if (lvalue->type.id == dbg_itype_none) { dbg_printf("Unable to evaluate expression\n"); return; @@ -465,6 +468,9 @@ void print_bare_address(const ADDRESS* addr) case AddrMode1632: dbg_printf("0x%04x:0x%08lx", addr->Segment, addr->Offset); break; + default: + dbg_printf("Unknown mode %x\n", addr->Mode); + break; } } @@ -499,7 +505,7 @@ void print_address(const ADDRESS* addr, BOOLEAN with_line) } } -struct foo +struct sym_enum { char* tmp; DWORD frame; @@ -507,19 +513,23 @@ struct foo static BOOL WINAPI sym_enum_cb(SYMBOL_INFO* sym_info, ULONG size, void* user) { - struct foo* foo = (struct foo*)user; - DWORD addr; - unsigned val; - long offset; + struct sym_enum* se = (struct sym_enum*)user; + DWORD addr; + unsigned val; + long offset; if ((sym_info->Flags & (SYMFLAG_PARAMETER|SYMFLAG_FRAMEREL)) == (SYMFLAG_PARAMETER|SYMFLAG_FRAMEREL)) { - if (foo->tmp[0]) strcat(foo->tmp, ", "); - addr = foo->frame; - types_get_info(sym_info->ModBase, sym_info->TypeIndex, TI_GET_OFFSET, &offset); + struct dbg_type type; + + if (se->tmp[0]) strcat(se->tmp, ", "); + addr = se->frame; + type.module = sym_info->ModBase; + type.id = sym_info->TypeIndex; + types_get_info(&type, TI_GET_OFFSET, &offset); addr += offset; dbg_read_memory_verbose((char*)addr, &val, sizeof(val)); - sprintf(foo->tmp + strlen(foo->tmp), "%s=0x%x", sym_info->Name, val); + sprintf(se->tmp + strlen(se->tmp), "%s=0x%x", sym_info->Name, val); } return TRUE; } @@ -531,7 +541,7 @@ void print_addr_and_args(const ADDRESS* pc, const ADDRESS* frame) IMAGEHLP_STACK_FRAME isf; IMAGEHLP_LINE il; IMAGEHLP_MODULE im; - struct foo foo; + struct sym_enum se; char tmp[1024]; DWORD disp; @@ -552,10 +562,10 @@ void print_addr_and_args(const ADDRESS* pc, const ADDRESS* frame) if (disp) dbg_printf("+0x%lx", disp); SymSetContext(dbg_curr_process->handle, &isf, NULL); - foo.tmp = tmp; - foo.frame = isf.FrameOffset; + se.tmp = tmp; + se.frame = isf.FrameOffset; tmp[0] = '\0'; - SymEnumSymbols(dbg_curr_process->handle, 0, NULL, sym_enum_cb, &foo); + SymEnumSymbols(dbg_curr_process->handle, 0, NULL, sym_enum_cb, &se); if (tmp[0]) dbg_printf("(%s)", tmp); il.SizeOfStruct = sizeof(il); diff --git a/programs/winedbg/stack.c b/programs/winedbg/stack.c index d1181bbee9f..8a739f5e69e 100644 --- a/programs/winedbg/stack.c +++ b/programs/winedbg/stack.c @@ -42,27 +42,24 @@ static IMAGEHLP_STACK_FRAME* frames = NULL; */ 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 */ - if (!memory_get_current_stack(&lvalue.addr)) - dbg_printf("Bad segment (%d)\n", lvalue.addr.Segment); + if (!memory_get_current_stack(&addr)) + dbg_printf("Bad segment (%d)\n", addr.Segment); dbg_printf("Stack dump:\n"); - switch (lvalue.addr.Mode) + switch (addr.Mode) { case AddrModeFlat: /* 32-bit mode */ case AddrMode1632: /* 32-bit mode */ - memory_examine(&lvalue, 24, 'x'); + memory_examine(memory_to_linear_addr(&addr), 24, 'x'); break; case AddrModeReal: /* 16-bit mode */ case AddrMode1616: - memory_examine(&lvalue, 24, 'w'); + memory_examine(memory_to_linear_addr(&addr), 24, 'w'); break; } - dbg_printf("\n"); } int stack_set_frame(int newframe) diff --git a/programs/winedbg/symbol.c b/programs/winedbg/symbol.c index 6addcb86526..b3de9cef09d 100644 --- a/programs/winedbg/symbol.c +++ b/programs/winedbg/symbol.c @@ -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)]; TI_FINDCHILDREN_PARAMS* fcp = (TI_FINDCHILDREN_PARAMS*)buffer; 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; while (count) { 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++) { - 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; - 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); fcp->Start += 256; @@ -107,7 +112,11 @@ static BOOL CALLBACK sgv_cb(SYMBOL_INFO* sym, ULONG size, void* ctx) else if (sym->Flags & SYMFLAG_FRAMEREL) { 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; } else if (sym->Flags & SYMFLAG_THUNK) @@ -175,11 +184,13 @@ static BOOL CALLBACK sgv_cb(SYMBOL_INFO* sym, ULONG size, void* ctx) memmove(&sgv->syms[insp + 1], &sgv->syms[insp], 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.Offset = addr; - types_get_info(sym->ModBase, sym->TypeIndex, TI_GET_TYPE, - &sgv->syms[insp].lvalue.typeid); - sgv->syms[insp].lvalue.cookie = cookie; + sgv->syms[insp].lvalue.type.module = sym->ModBase; + sgv->syms[insp].lvalue.type.id = sym->TypeIndex; + types_get_info(&sgv->syms[insp].lvalue.type, TI_GET_TYPE, + &sgv->syms[insp].lvalue.type.id); sgv->syms[insp].flags = sym->Flags; sgv->num++; @@ -314,8 +325,9 @@ enum sym_get_lval symbol_get_lvalue(const char* name, const int lineno, } else { - dbg_printf("More than one symbol named %s, picking the first one\n", name); - i = 0; + /* FIXME: could display the list of non-picked up symbols */ + if (sgv.num > 1) + dbg_printf("More than one symbol named %s, picking the first one\n", name); } *rtn = sgv.syms[i].lvalue; return sglv_found; @@ -390,6 +402,7 @@ enum dbg_line_status symbol_get_function_line_status(const ADDRESS* addr) DWORD lin = (DWORD)memory_to_linear_addr(addr); char buffer[sizeof(SYMBOL_INFO) + 256]; SYMBOL_INFO* sym = (SYMBOL_INFO*)buffer; + struct dbg_type type; il.SizeOfStruct = sizeof(il); sym->SizeOfStruct = sizeof(SYMBOL_INFO); @@ -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) 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; if (il.FileName && il.FileName[0] && disp < size) 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 static BOOL CALLBACK info_locals_cb(SYMBOL_INFO* sym, ULONG size, void* ctx) { - DWORD tid; - ULONG v, val; - const char* explain = NULL; - char buf[128]; + ULONG v, val; + const char* explain = NULL; + char buf[128]; + struct dbg_type type; dbg_printf("\t"); - types_get_info(sym->ModBase, sym->TypeIndex, TI_GET_TYPE, &tid); - types_print_type(sym->ModBase, tid, FALSE); + type.module = sym->ModBase; + 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"; 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) } 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; dbg_read_memory_verbose((void*)v, &val, sizeof(val)); @@ -556,13 +574,13 @@ int symbol_info_locals(void) 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); 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"); return TRUE; diff --git a/programs/winedbg/types.c b/programs/winedbg/types.c index 0b3e6300d8b..06c88ed57bd 100644 --- a/programs/winedbg/types.c +++ b/programs/winedbg/types.c @@ -39,19 +39,16 @@ long int types_extract_as_integer(const struct dbg_lvalue* lvalue) { long int rtn = 0; DWORD tag, size, bt; - DWORD linear = (DWORD)memory_to_linear_addr(&lvalue->addr); - assert(lvalue->cookie == DLV_TARGET || lvalue->cookie == DLV_HOST); - - if (lvalue->typeid == dbg_itype_none || - !types_get_info(linear, lvalue->typeid, TI_GET_SYMTAG, &tag)) + if (lvalue->type.id == dbg_itype_none || + !types_get_info(&lvalue->type, TI_GET_SYMTAG, &tag)) return 0; switch (tag) { case SymTagBaseType: - if (!types_get_info(linear, lvalue->typeid, TI_GET_LENGTH, &size) || - !types_get_info(linear, lvalue->typeid, TI_GET_BASETYPE, &bt)) + if (!types_get_info(&lvalue->type, TI_GET_LENGTH, &size) || + !types_get_info(&lvalue->type, TI_GET_BASETYPE, &bt)) { WINE_ERR("Couldn't get information\n"); RaiseException(DEBUG_STATUS_INTERNAL_ERROR, 0, 0, NULL); @@ -107,23 +104,34 @@ long int types_extract_as_integer(const struct dbg_lvalue* lvalue) BOOL types_deref(const struct dbg_lvalue* lvalue, struct dbg_lvalue* result) { DWORD tag; - DWORD linear = (DWORD)memory_to_linear_addr(&lvalue->addr); - - assert(lvalue->cookie == DLV_TARGET || lvalue->cookie == DLV_HOST); memset(result, 0, sizeof(*result)); - result->typeid = dbg_itype_none; + result->type.id = dbg_itype_none; + result->type.module = 0; /* * Make sure that this really makes sense. */ - if (!types_get_info(linear, lvalue->typeid, TI_GET_SYMTAG, &tag) || + if (!types_get_info(&lvalue->type, TI_GET_SYMTAG, &tag) || tag != SymTagPointerType || memory_read_value(lvalue, sizeof(result->addr.Offset), &result->addr.Offset) || - !types_get_info(linear, lvalue->typeid, TI_GET_TYPE, &result->typeid)) + !types_get_info(&lvalue->type, TI_GET_TYPE, &result->type.id)) return FALSE; - - result->cookie = DLV_TARGET; /* see comment on DEREF below */ + result->type.module = lvalue->type.module; + result->cookie = DLV_TARGET; + /* FIXME: this is currently buggy. + * there is no way to tell were the deref:ed value is... + * for example: + * x is a pointer to struct s, x being on the stack + * => lvalue is in debuggee, result is in debugger + * x is a pointer to struct s, x being optimized into a reg + * => lvalue is debugger, result is debuggee + * x is a pointer to internal variable x + * => lvalue is debugger, result is debuggee + * so we force debuggee address space, because dereferencing pointers to + * internal variables is very unlikely. A correct fix would be + * rather large. + */ result->addr.Mode = AddrModeFlat; return TRUE; } @@ -133,19 +141,20 @@ BOOL types_deref(const struct dbg_lvalue* lvalue, struct dbg_lvalue* result) * * Implement a structure derefencement */ -static BOOL types_get_udt_element_lvalue(struct dbg_lvalue* lvalue, DWORD linear, - DWORD typeid, long int* tmpbuf) +static BOOL types_get_udt_element_lvalue(struct dbg_lvalue* lvalue, + const struct dbg_type* type, long int* tmpbuf) { DWORD offset, length, bitoffset; DWORD bt; unsigned mask; - types_get_info(linear, typeid, TI_GET_TYPE, &lvalue->typeid); - types_get_info(linear, typeid, TI_GET_OFFSET, &offset); + types_get_info(type, TI_GET_TYPE, &lvalue->type.id); + lvalue->type.module = type->module; + types_get_info(type, TI_GET_OFFSET, &offset); - if (types_get_info(linear, typeid, TI_GET_BITPOSITION, &bitoffset)) + if (types_get_info(type, TI_GET_BITPOSITION, &bitoffset)) { - types_get_info(linear, typeid, TI_GET_LENGTH, &length); + types_get_info(type, TI_GET_LENGTH, &length); if (length > sizeof(*tmpbuf)) return FALSE; /* * Bitfield operation. We have to extract the field and store @@ -157,8 +166,7 @@ static BOOL types_get_udt_element_lvalue(struct dbg_lvalue* lvalue, DWORD linear *tmpbuf >>= bitoffset & 7; *tmpbuf &= ~mask; - lvalue->cookie = DLV_HOST; - lvalue->addr.Mode = AddrModeFlat; + lvalue->cookie = DLV_HOST; lvalue->addr.Offset = (DWORD)tmpbuf; /* @@ -166,14 +174,14 @@ static BOOL types_get_udt_element_lvalue(struct dbg_lvalue* lvalue, DWORD linear * Check to see whether the basic type is signed or not, and if so, * we need to sign extend the number. */ - if (types_get_info(linear, lvalue->typeid, TI_GET_BASETYPE, &bt) && + if (types_get_info(&lvalue->type, TI_GET_BASETYPE, &bt) && bt == btInt && (*tmpbuf & (1 << (length - 1)))) { *tmpbuf |= mask; } return TRUE; } - if (types_get_info(linear, typeid, TI_GET_OFFSET, &offset)) + if (types_get_info(type, TI_GET_OFFSET, &offset)) { lvalue->addr.Offset += offset; return TRUE; @@ -187,39 +195,38 @@ static BOOL types_get_udt_element_lvalue(struct dbg_lvalue* lvalue, DWORD linear */ BOOL types_udt_find_element(struct dbg_lvalue* lvalue, const char* name, long int* tmpbuf) { - DWORD linear = (DWORD)memory_to_linear_addr(&lvalue->addr); DWORD tag, count; char buffer[sizeof(TI_FINDCHILDREN_PARAMS) + 256 * sizeof(DWORD)]; TI_FINDCHILDREN_PARAMS* fcp = (TI_FINDCHILDREN_PARAMS*)buffer; WCHAR* ptr; char tmp[256]; int i; + struct dbg_type type; - assert(lvalue->cookie == DLV_TARGET || lvalue->cookie == DLV_HOST); - - if (!types_get_info(linear, lvalue->typeid, TI_GET_SYMTAG, &tag) || + if (!types_get_info(&lvalue->type, TI_GET_SYMTAG, &tag) || tag != SymTagUDT) return FALSE; - if (types_get_info(linear, lvalue->typeid, TI_GET_CHILDRENCOUNT, &count)) + if (types_get_info(&lvalue->type, TI_GET_CHILDRENCOUNT, &count)) { fcp->Start = 0; while (count) { fcp->Count = min(count, 256); - if (types_get_info(linear, lvalue->typeid, TI_FINDCHILDREN, fcp)) + if (types_get_info(&lvalue->type, TI_FINDCHILDREN, fcp)) { + type.module = lvalue->type.module; for (i = 0; i < min(fcp->Count, count); i++) { ptr = NULL; - types_get_info(linear, fcp->ChildId[i], TI_GET_SYMNAME, &ptr); + type.id = fcp->ChildId[i]; + types_get_info(&type, TI_GET_SYMNAME, &ptr); if (!ptr) continue; WideCharToMultiByte(CP_ACP, 0, ptr, -1, tmp, sizeof(tmp), NULL, NULL); HeapFree(GetProcessHeap(), 0, ptr); if (strcmp(tmp, name)) continue; - return types_get_udt_element_lvalue(lvalue, linear, - fcp->ChildId[i], tmpbuf); + return types_get_udt_element_lvalue(lvalue, &type, tmpbuf); } } count -= min(count, 256); @@ -238,26 +245,23 @@ BOOL types_array_index(const struct dbg_lvalue* lvalue, int index, struct dbg_lvalue* result) { DWORD tag, length, count; - DWORD linear = (DWORD)memory_to_linear_addr(&lvalue->addr); - assert(lvalue->cookie == DLV_TARGET || lvalue->cookie == DLV_HOST); - - if (!types_get_info(0, lvalue->typeid, TI_GET_SYMTAG, &tag)) + if (!types_get_info(&lvalue->type, TI_GET_SYMTAG, &tag)) return FALSE; switch (tag) { case SymTagArrayType: - types_get_info(linear, lvalue->typeid, TI_GET_COUNT, &count); + types_get_info(&lvalue->type, TI_GET_COUNT, &count); if (index < 0 || index >= count) return FALSE; /* fall through */ case SymTagPointerType: /* * Get the base type, so we know how much to index by. */ - types_get_info(linear, lvalue->typeid, TI_GET_TYPE, &result->typeid); - types_get_info(linear, result->typeid, TI_GET_LENGTH, &length); + types_get_info(&lvalue->type, TI_GET_TYPE, &result->type.id); + result->type.module = lvalue->type.module; + types_get_info(&result->type, TI_GET_LENGTH, &length); /* Contents of array must be on same target */ - result->cookie = lvalue->cookie; result->addr.Mode = lvalue->addr.Mode; memory_read_value(lvalue, sizeof(result->addr.Offset), &result->addr.Offset); result->addr.Offset += index * length; @@ -283,7 +287,7 @@ static BOOL CALLBACK types_cb(PSYMBOL_INFO sym, ULONG size, void* _user) { struct type_find_t* user = (struct type_find_t*)_user; BOOL ret = TRUE; - DWORD typeid; + struct dbg_type type; if (sym->Tag == user->tag) { @@ -297,9 +301,9 @@ static BOOL CALLBACK types_cb(PSYMBOL_INFO sym, ULONG size, void* _user) } break; case SymTagPointerType: - types_get_info(sym->ModBase, sym->TypeIndex, TI_GET_TYPE, &typeid); - if (types_get_info(sym->ModBase, sym->TypeIndex, TI_GET_TYPE, &typeid) && - typeid == user->u.typeid) + type.module = sym->ModBase; + type.id = sym->TypeIndex; + if (types_get_info(&type, TI_GET_TYPE, &type.id) && type.id == user->u.typeid) { user->result = sym->TypeIndex; ret = FALSE; @@ -316,14 +320,18 @@ static BOOL CALLBACK types_cb(PSYMBOL_INFO sym, ULONG size, void* _user) * Should look up in module based at linear whether (typeid*) exists * Otherwise, we could create it locally */ -unsigned long types_find_pointer(unsigned long linear, unsigned long typeid) +struct dbg_type types_find_pointer(const struct dbg_type* type) { struct type_find_t f; + struct dbg_type ret; + f.result = dbg_itype_none; f.tag = SymTagPointerType; - f.u.typeid = typeid; - SymEnumTypes(dbg_curr_process->handle, linear, types_cb, &f); - return f.result; + f.u.typeid = type->id; + SymEnumTypes(dbg_curr_process->handle, type->module, types_cb, &f); + ret.module = type->module; + ret.id = f.result; + return ret; } /****************************************************************** @@ -332,15 +340,19 @@ unsigned long types_find_pointer(unsigned long linear, unsigned long typeid) * Should look up in the module based at linear address whether a type * named 'name' and with the correct tag exists */ -unsigned long types_find_type(unsigned long linear, const char* name, enum SymTagEnum tag) +struct dbg_type types_find_type(unsigned long linear, const char* name, enum SymTagEnum tag) { struct type_find_t f; + struct dbg_type ret; + f.result = dbg_itype_none; f.tag = tag; f.u.name = name; SymEnumTypes(dbg_curr_process->handle, linear, types_cb, &f); - return f.result; + ret.module = linear; + ret.id = f.result; + return ret; } /*********************************************************************** @@ -352,15 +364,11 @@ void print_value(const struct dbg_lvalue* lvalue, char format, int level) { struct dbg_lvalue lvalue_field; int i; - unsigned long linear; DWORD tag; DWORD count; DWORD size; - assert(lvalue->cookie == DLV_TARGET || lvalue->cookie == DLV_HOST); - linear = (unsigned long)memory_to_linear_addr(&lvalue->addr); - - if (lvalue->typeid == dbg_itype_none) + if (lvalue->type.id == dbg_itype_none) { /* No type, just print the addr value */ print_bare_address(&lvalue->addr); @@ -373,7 +381,7 @@ void print_value(const struct dbg_lvalue* lvalue, char format, int level) format = '\0'; } - if (!types_get_info(linear, lvalue->typeid, TI_GET_SYMTAG, &tag)) + if (!types_get_info(&lvalue->type, TI_GET_SYMTAG, &tag)) { WINE_FIXME("---error\n"); return; @@ -386,32 +394,34 @@ void print_value(const struct dbg_lvalue* lvalue, char format, int level) print_basic(lvalue, 1, format); break; case SymTagUDT: - if (types_get_info(linear, lvalue->typeid, TI_GET_CHILDRENCOUNT, &count)) + if (types_get_info(&lvalue->type, TI_GET_CHILDRENCOUNT, &count)) { char buffer[sizeof(TI_FINDCHILDREN_PARAMS) + 256 * sizeof(DWORD)]; TI_FINDCHILDREN_PARAMS* fcp = (TI_FINDCHILDREN_PARAMS*)buffer; WCHAR* ptr; char tmp[256]; long int tmpbuf; + struct dbg_type type; dbg_printf("{"); fcp->Start = 0; while (count) { fcp->Count = min(count, 256); - if (types_get_info(linear, lvalue->typeid, TI_FINDCHILDREN, fcp)) + if (types_get_info(&lvalue->type, TI_FINDCHILDREN, fcp)) { for (i = 0; i < min(fcp->Count, count); i++) { ptr = NULL; - types_get_info(linear, fcp->ChildId[i], TI_GET_SYMNAME, &ptr); + type.module = (unsigned long)memory_to_linear_addr(&lvalue->addr); + type.id = fcp->ChildId[i]; + types_get_info(&type, TI_GET_SYMNAME, &ptr); if (!ptr) continue; WideCharToMultiByte(CP_ACP, 0, ptr, -1, tmp, sizeof(tmp), NULL, NULL); dbg_printf("%s=", tmp); HeapFree(GetProcessHeap(), 0, ptr); lvalue_field = *lvalue; - if (types_get_udt_element_lvalue(&lvalue_field, linear, - fcp->ChildId[i], &tmpbuf)) + if (types_get_udt_element_lvalue(&lvalue_field, &type, &tmpbuf)) { print_value(&lvalue_field, format, level + 1); } @@ -429,8 +439,8 @@ void print_value(const struct dbg_lvalue* lvalue, char format, int level) * Loop over all of the entries, printing stuff as we go. */ count = 1; size = 1; - types_get_info(linear, lvalue->typeid, TI_GET_COUNT, &count); - types_get_info(linear, lvalue->typeid, TI_GET_LENGTH, &size); + types_get_info(&lvalue->type, TI_GET_COUNT, &count); + types_get_info(&lvalue->type, TI_GET_LENGTH, &size); if (size == count) { @@ -441,14 +451,14 @@ void print_value(const struct dbg_lvalue* lvalue, char format, int level) */ /* FIXME should check basic type here (should be a char!!!!)... */ len = min(count, sizeof(buffer)); - memory_get_string(dbg_curr_thread->handle, + memory_get_string(dbg_curr_process->handle, memory_to_linear_addr(&lvalue->addr), - lvalue->cookie, TRUE, buffer, len); + lvalue->cookie == DLV_TARGET, TRUE, buffer, len); dbg_printf("\"%s%s\"", buffer, (len < count) ? "..." : ""); break; } lvalue_field = *lvalue; - types_get_info(linear, lvalue->typeid, TI_GET_TYPE, &lvalue_field.typeid); + types_get_info(&lvalue->type, TI_GET_TYPE, &lvalue_field.type.id); dbg_printf("{"); for (i = 0; i < count; i++) { @@ -461,7 +471,7 @@ void print_value(const struct dbg_lvalue* lvalue, char format, int level) dbg_printf("Function "); print_bare_address(&lvalue->addr); dbg_printf(": "); - types_print_type(linear, lvalue->typeid, FALSE); + types_print_type(&lvalue->type, FALSE); break; default: WINE_FIXME("Unknown tag (%lu)\n", tag); @@ -476,7 +486,11 @@ leave: static BOOL CALLBACK print_types_cb(PSYMBOL_INFO sym, ULONG size, void* ctx) { - types_print_type(sym->ModBase, sym->TypeIndex, TRUE); + struct dbg_type type; + type.module = sym->ModBase; + type.id = sym->TypeIndex; + dbg_printf("Mod: %08lx ID: %08lx \n", type.module, type.id); + types_print_type(&type, TRUE); dbg_printf("\n"); return TRUE; } @@ -492,20 +506,21 @@ int print_types(void) return 0; } -int types_print_type(DWORD linear, DWORD typeid, BOOL details) +int types_print_type(const struct dbg_type* type, BOOL details) { WCHAR* ptr; char tmp[256]; const char* name; - DWORD tag, subtype, count; + DWORD tag, udt, count; + struct dbg_type subtype; - if (typeid == dbg_itype_none || !types_get_info(linear, typeid, TI_GET_SYMTAG, &tag)) + if (type->id == dbg_itype_none || !types_get_info(type, TI_GET_SYMTAG, &tag)) { - dbg_printf("--invalid--<%lxh>--", typeid); + dbg_printf("--invalid--<%lxh>--", type->id); return FALSE; } - if (types_get_info(linear, typeid, TI_GET_SYMNAME, &ptr) && ptr) + if (types_get_info(type, TI_GET_SYMNAME, &ptr) && ptr) { WideCharToMultiByte(CP_ACP, 0, ptr, -1, tmp, sizeof(tmp), NULL, NULL); name = tmp; @@ -519,47 +534,50 @@ int types_print_type(DWORD linear, DWORD typeid, BOOL details) if (details) dbg_printf("Basic<%s>", name); else dbg_printf("%s", name); break; case SymTagPointerType: - types_get_info(linear, typeid, TI_GET_TYPE, &subtype); - types_print_type(linear, subtype, details); + types_get_info(type, TI_GET_TYPE, &subtype.id); + subtype.module = type->module; + types_print_type(&subtype, FALSE); dbg_printf("*"); break; case SymTagUDT: - types_get_info(linear, typeid, TI_GET_UDTKIND, &subtype); - switch (subtype) + types_get_info(type, TI_GET_UDTKIND, &udt); + switch (udt) { case UdtStruct: dbg_printf("struct %s", name); break; case UdtUnion: dbg_printf("union %s", name); break; case UdtClass: dbg_printf("class %s", name); break; } if (details && - types_get_info(linear, typeid, TI_GET_CHILDRENCOUNT, &count)) + types_get_info(type, TI_GET_CHILDRENCOUNT, &count)) { char buffer[sizeof(TI_FINDCHILDREN_PARAMS) + 256 * sizeof(DWORD)]; TI_FINDCHILDREN_PARAMS* fcp = (TI_FINDCHILDREN_PARAMS*)buffer; WCHAR* ptr; char tmp[256]; int i; - + struct dbg_type type_elt; dbg_printf(" {"); fcp->Start = 0; while (count) { fcp->Count = min(count, 256); - if (types_get_info(linear, typeid, TI_FINDCHILDREN, fcp)) + if (types_get_info(type, TI_FINDCHILDREN, fcp)) { for (i = 0; i < min(fcp->Count, count); i++) { ptr = NULL; - types_get_info(linear, fcp->ChildId[i], TI_GET_SYMNAME, &ptr); + type_elt.module = type->module; + type_elt.id = fcp->ChildId[i]; + types_get_info(&type_elt, TI_GET_SYMNAME, &ptr); if (!ptr) continue; WideCharToMultiByte(CP_ACP, 0, ptr, -1, tmp, sizeof(tmp), NULL, NULL); HeapFree(GetProcessHeap(), 0, ptr); dbg_printf("%s", tmp); - if (types_get_info(linear, fcp->ChildId[i], TI_GET_TYPE, &subtype)) + if (types_get_info(&type_elt, TI_GET_TYPE, &type_elt.id)) { dbg_printf(":"); - types_print_type(linear, subtype, details); + types_print_type(&type_elt, details); } if (i < min(fcp->Count, count) - 1 || count > 256) dbg_printf(", "); } @@ -571,18 +589,20 @@ int types_print_type(DWORD linear, DWORD typeid, BOOL details) } break; case SymTagArrayType: - types_get_info(linear, typeid, TI_GET_TYPE, &subtype); - types_print_type(linear, subtype, details); + types_get_info(type, TI_GET_TYPE, &subtype.id); + subtype.module = type->module; + types_print_type(&subtype, details); dbg_printf(" %s[]", name); break; case SymTagEnum: dbg_printf("enum %s", name); break; case SymTagFunctionType: - types_get_info(linear, typeid, TI_GET_TYPE, &subtype); - types_print_type(linear, subtype, FALSE); + types_get_info(type, TI_GET_TYPE, &subtype.id); + subtype.module = type->module; + types_print_type(&subtype, FALSE); dbg_printf(" (*%s)(", name); - if (types_get_info(linear, typeid, TI_GET_CHILDRENCOUNT, &count)) + if (types_get_info(type, TI_GET_CHILDRENCOUNT, &count)) { char buffer[sizeof(TI_FINDCHILDREN_PARAMS) + 256 * sizeof(DWORD)]; TI_FINDCHILDREN_PARAMS* fcp = (TI_FINDCHILDREN_PARAMS*)buffer; @@ -592,11 +612,12 @@ int types_print_type(DWORD linear, DWORD typeid, BOOL details) while (count) { fcp->Count = min(count, 256); - if (types_get_info(linear, typeid, TI_FINDCHILDREN, fcp)) + if (types_get_info(type, TI_FINDCHILDREN, fcp)) { for (i = 0; i < min(fcp->Count, count); i++) { - types_print_type(linear, fcp->ChildId[i], FALSE); + subtype.id = fcp->ChildId[i]; + types_print_type(&subtype, FALSE); if (i < min(fcp->Count, count) - 1 || count > 256) dbg_printf(", "); } } @@ -614,31 +635,17 @@ int types_print_type(DWORD linear, DWORD typeid, BOOL details) return TRUE; } -BOOL types_get_info(unsigned long modbase, unsigned long typeid, - IMAGEHLP_SYMBOL_TYPE_INFO ti, void* pInfo) +BOOL types_get_info(const struct dbg_type* type, IMAGEHLP_SYMBOL_TYPE_INFO ti, void* pInfo) { - if (typeid == dbg_itype_none) return FALSE; - if (typeid < dbg_itype_first) - { - BOOL ret; - DWORD tag; - - ret = SymGetTypeInfo(dbg_curr_process->handle, modbase, typeid, ti, pInfo); - if (!ret && ti == TI_GET_LENGTH && - (!SymGetTypeInfo(dbg_curr_process->handle, modbase, typeid, - TI_GET_SYMTAG, &tag) || tag == SymTagData)) - { - WINE_FIXME("get length on symtag data is no longer supported\n"); - assert(0); - } - return ret; - } - assert(modbase); + if (type->id == dbg_itype_none) return FALSE; + if (type->module != 0) + return SymGetTypeInfo(dbg_curr_process->handle, type->module, type->id, ti, pInfo); + assert(type->id >= dbg_itype_first); /* helper to typecast pInfo to its expected type (_t) */ #define X(_t) (*((_t*)pInfo)) - switch (typeid) + switch (type->id) { case dbg_itype_unsigned_int: switch (ti) @@ -712,7 +719,7 @@ BOOL types_get_info(unsigned long modbase, unsigned long typeid, default: WINE_FIXME("unsupported %u for a string\n", ti); return FALSE; } break; - default: WINE_FIXME("unsupported typeid 0x%lx\n", typeid); + default: WINE_FIXME("unsupported type id 0x%lx\n", type->id); } #undef X diff --git a/programs/winedbg/winedbg.c b/programs/winedbg/winedbg.c index 64ce2873e4b..ee37c0fc45e 100644 --- a/programs/winedbg/winedbg.c +++ b/programs/winedbg/winedbg.c @@ -45,6 +45,9 @@ * + make the output as close as possible to what gdb does * - symbol management: * + 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: * + some bits of internal types are missing (like type casts and the address * operator) @@ -55,7 +58,10 @@ * o bitfield size is on a 4-bytes * + some bits of internal types are missing (like type casts and the address * 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 * + implement function call in debuggee * + 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, t->wait_for_first_exception = 0; t->exec_mode = dbg_exec_cont; 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); @@ -354,8 +362,8 @@ static void dbg_init_current_thread(void* start) { if (start) { - if (dbg_curr_thread->process->threads && - !dbg_curr_thread->process->threads->next && /* first thread ? */ + if (dbg_curr_process->threads && + !dbg_curr_process->threads->next && /* first thread ? */ DBG_IVAR(BreakAllThreadsStartup)) { ADDRESS addr; @@ -562,8 +570,7 @@ static DWORD dbg_handle_exception(EXCEPTION_RECORD* rec, BOOL first_chance, else pThread = dbg_get_thread(dbg_curr_process, pThreadName->dwThreadID); - if (ReadProcessMemory(dbg_curr_thread->process->handle, pThreadName->szName, - pThread->name, 9, NULL)) + if (dbg_read_memory(pThreadName->szName, pThread->name, 9)) dbg_printf("Thread ID=0x%lx renamed using MS VC6 extension (name==\"%s\")\n", pThread->tid, pThread->name); return DBG_CONTINUE; @@ -636,11 +643,11 @@ static DWORD dbg_handle_exception(EXCEPTION_RECORD* rec, BOOL first_chance, case EXCEPTION_WINE_STUB: { char dll[32], name[64]; - memory_get_string(dbg_curr_thread->process->handle, - (void*)rec->ExceptionInformation[0], DLV_TARGET, FALSE, + memory_get_string(dbg_curr_process->handle, + (void*)rec->ExceptionInformation[0], TRUE, FALSE, dll, sizeof(dll)); - memory_get_string(dbg_curr_thread->process->handle, - (void*)rec->ExceptionInformation[1], DLV_TARGET, FALSE, + memory_get_string(dbg_curr_process->handle, + (void*)rec->ExceptionInformation[1], TRUE, FALSE, name, sizeof(name)); dbg_printf("unimplemented function %s.%s called", dll, name); } @@ -854,7 +861,7 @@ static unsigned dbg_handle_debug_event(DEBUG_EVENT* de) WINE_ERR("Unknown thread\n"); 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.fUnicode, buffer, sizeof(buffer)); @@ -894,8 +901,8 @@ static unsigned dbg_handle_debug_event(DEBUG_EVENT* de) break; } - memory_get_string(dbg_curr_thread->process->handle, - de->u.DebugString.lpDebugStringData, DLV_TARGET, + memory_get_string(dbg_curr_process->handle, + de->u.DebugString.lpDebugStringData, TRUE, de->u.DebugString.fUnicode, buffer, sizeof(buffer)); WINE_TRACE("%08lx:%08lx: output debug string (%s)\n", de->dwProcessId, de->dwThreadId, buffer);