https://bugs.winehq.org/show_bug.cgi?id=36012
Bug ID: 36012 Summary: OllyDbg 2.x debugger crashes with Wine builtin dbghelp Product: Wine Version: 1.7.16 Hardware: x86 OS: Linux Status: NEW Severity: normal Priority: P2 Component: dbghelp Assignee: wine-bugs@winehq.org Reporter: focht@gmx.net
Hello folks,
noticed this a while ago ... reporting now :)
Ollydbg v2.x crashes for me with Wine builtin dbghelp. Interestingly the old Ollydbg v1.x doesn't crash with builtin.
So I ended up with:
Ollydbg 1.x debugging Ollydbg 2.x debugging Wine builtin 'notepad' :)
Relevant part of tracelog (with some helper traces added by me):
--- snip --- $ WINEDEBUG=+tid,+seh,+dbghelp,+dbghelp_symt wine ./ollydbg.exe >>log2.txt 2>&1 ... 0023:trace:dbghelp_symt:symt_new_function Adding global function L"kernel32<elf>":WCEL_InsertChar @7b83839a-7b8383c8 0023:trace:dbghelp_symt:symt_add_func_local Adding local symbol (L"kernel32<elf>":WCEL_InsertChar): ctx 0x20acd44 0023:trace:dbghelp_symt:symt_add_func_local Adding local symbol (L"kernel32<elf>":WCEL_InsertChar): c 0x20aaba0 0023:trace:dbghelp_symt:symt_add_func_local Adding local symbol (L"kernel32<elf>":WCEL_InsertChar): buffer 0x20ad7f0 ... 0023:trace:dbghelp_symt:symt_add_func_line (0x20ae608)WCEL_InsertChar:0 /home/focht/projects/wine/wine.repo/src/dlls/kernel32/editline.c:328 0023:trace:dbghelp_symt:symt_add_func_line (0x20ae608)WCEL_InsertChar:d /home/focht/projects/wine/wine.repo/src/dlls/kernel32/editline.c:331 0023:trace:dbghelp_symt:symt_add_func_line (0x20ae608)WCEL_InsertChar:15 /home/focht/projects/wine/wine.repo/src/dlls/kernel32/editline.c:332 0023:trace:dbghelp_symt:symt_add_func_line (0x20ae608)WCEL_InsertChar:1b /home/focht/projects/wine/wine.repo/src/dlls/kernel32/editline.c:333 0023:trace:dbghelp_symt:symt_add_func_line (0x20ae608)WCEL_InsertChar:2d /home/focht/projects/wine/wine.repo/src/dlls/kernel32/editline.c:334 ... 0023:trace:dbghelp_symt:symt_new_public Adding public symbol L"kernel32<elf>":WCEL_InsertChar @7b83839a ... 0023:trace:dbghelp:SymMatchStringW L"WCEL_InsertChar" L"*" N 0023:trace:dbghelp_symt:symt_fill_sym_info 0x20ae608 => WCEL_InsertChar 47 7b83839a 0023:trace:dbghelp:send_symbol se->cb=0x7d7f4fd1 se->sym_info=0x335fd8, se->sym_info->Size=47 se->user=0x33683c 0023:trace:dbghelp:sym_enumW sew->cb=0x4c90bc sew->sym_info=0x336848 size=47 sew->ctx=0x337098 0023:trace:dbghelp:SymSetContext Setting same frame {rtn=0 frm=0 stk=0} 0023:trace:dbghelp:symt_enum_locals_helper pair=0x3312fc match=0x7d800bd2 se=0x331398 func=0x20ae608 v=0x20ae63c vlen=4 0023:trace:dbghelp:symt_enum_locals_helper i=0 lsym=0x20ae66c, lsym->tag=0x7 0023:trace:dbghelp:SymMatchStringW L"ctx" L"*" Y 0023:trace:dbghelp_symt:symt_fill_sym_info 0x20ae66c => ctx 4 4 0023:trace:dbghelp:send_symbol se->cb=0x7d7f4fd1 se->sym_info=0x3313b8, se->sym_info->Size=4 se->user=0x331c1c 0023:trace:dbghelp:sym_enumW sew->cb=0x4c8f54 sew->sym_info=0x331c28 size=4 sew->ctx=0x33250c 0023:trace:dbghelp:symt_enum_locals_helper i=1 lsym=0x20ae6e4, lsym->tag=0x7 0023:trace:dbghelp:SymMatchStringW L"c" L"*" Y 0023:trace:dbghelp_symt:symt_fill_sym_info 0x20ae6e4 => c 2 ffffffe0 0023:trace:dbghelp:send_symbol se->cb=0x7d7f4fd1 se->sym_info=0x3313b8, se->sym_info->Size=2 se->user=0x331c1c 0023:trace:dbghelp:sym_enumW sew->cb=0x4c8f54 sew->sym_info=0x331c28 size=2 sew->ctx=0x33250c 0023:trace:seh:raise_exception code=c0000005 flags=0 addr=0x7d7f1208 ip=7d7f1208 tid=0023 0023:trace:seh:raise_exception info[0]=00000000 0023:trace:seh:raise_exception info[1]=00000064 0023:trace:seh:raise_exception eax=00000058 ebx=7d80d000 ecx=003311f0 edx=fffffd6f esi=00000040 edi=0033689c 0023:trace:seh:raise_exception ebp=00331248 esp=00331248 cs=0023 ds=002b es=002b fs=0063 gs=006b flags=00010202 0023:trace:seh:call_stack_handlers calling handler at 0x4e87c0 code=c0000005 flags=0 --- snip ---
'WCEL_InsertChar' seems to be the offender. Populating the symbol info for that function causes the crash in the debugger callback.
http://source.winehq.org/git/wine.git/blob/fc38254fed5dbc07a2a61a2411bfaadcc...
--- snip --- 327 static void WCEL_InsertChar(WCEL_Context* ctx, WCHAR c) 328 { 329 WCHAR buffer[2]; 330 331 buffer[0] = c; 332 buffer[1] = 0; 333 WCEL_InsertString(ctx, buffer); 334 } --- snip ---
During symbol evaluation of second function parameter 'c', the debugger syminfo callback corrupts parts of the caller stack hence the next for-loop iteration 'vector_length(v)' which ought to prepare 'buffer' local symbol info crashes.
Source: http://source.winehq.org/git/wine.git/blob/d0665616255ae8b720e14e02072996b7a...
--- snip --- 909 static BOOL symt_enum_locals_helper(struct module_pair* pair, 910 const WCHAR* match, const struct sym_enum* se, 911 struct symt_function* func, const struct vector* v) 912 { 913 struct symt* lsym = NULL; 914 DWORD pc = pair->pcs->ctx_frame.InstructionOffset; 915 unsigned int i; 916 WCHAR* nameW; 917 BOOL ret; 918 919 for (i=0; i<vector_length(v); i++) 920 { 921 lsym = *(struct symt**)vector_at(v, i); 922 switch (lsym->tag) 923 { ... 933 case SymTagData: 934 nameW = symt_get_nameW(lsym); 935 ret = SymMatchStringW(nameW, match, 936 !(dbghelp_options & SYMOPT_CASE_INSENSITIVE)); 937 HeapFree(GetProcessHeap(), 0, nameW); 938 if (ret) 939 { 940 if (send_symbol(se, pair, func, lsym)) return FALSE; 941 } 942 break; ... 951 } 952 } 953 return TRUE; 954 } --- snip ---
Dump of symbol info for second parameter 'c':
--- snip --- Wine-dbg>p *se.sym_info {SizeOfStruct=0x58, TypeIndex=0x20a2b90, Reserved={0, 0}, info=0x20a66d4, Size=0x2, ModBase=0x7b810000, Flags=0xd0, Value=0, Address=0xffffffe0, Register=0x15, Scope=0, Tag=0x7, NameLen=0x1, MaxNameLen=0x7d0, Name=""} --- snip ---
Flags: 0xD0 = SYMFLAG_LOCAL | SYMFLAG_PARAMETER | SYMFLAG_REGREL Register: 0x15 = CV_REG_ESP
Disassembly of 'WCEL_InsertChar':
--- snip --- $ objdump -d editline.o
00000cba <WCEL_InsertChar>: cba: 55 push %ebp cbb: 89 e5 mov %esp,%ebp cbd: 83 ec 28 sub $0x28,%esp cc0: 8b 45 0c mov 0xc(%ebp),%eax ; parameter 'c' cc3: 66 89 45 e4 mov %ax,-0x1c(%ebp) ; 'c' as stack variable cc7: 0f b7 45 e4 movzwl -0x1c(%ebp),%eax ccb: 66 89 45 f4 mov %ax,-0xc(%ebp) ; buffer[0] = c ccf: 66 c7 45 f6 00 00 movw $0x0,-0xa(%ebp) ; buffer[1] = 0 cd5: 8d 45 f4 lea -0xc(%ebp),%eax cd8: 89 44 24 04 mov %eax,0x4(%esp) cdc: 8b 45 08 mov 0x8(%ebp),%eax ; 'ctx' parameter passthru cdf: 89 04 24 mov %eax,(%esp) ce2: e8 30 fe ff ff call b17 <WCEL_InsertString> ce7: c9 leave ce8: c3 ret --- snip ---
DWARF(2) symbol info:
--- snip --- $ objdump -W editline.o
<1><cf7>: Abbrev Number: 43 (DW_TAG_subprogram) <cf8> DW_AT_name : (indirect string, offset: 0x25b): WCEL_InsertChar <cfc> DW_AT_decl_file : 3 <cfd> DW_AT_decl_line : 327 <cff> DW_AT_prototyped : 1 <d00> DW_AT_low_pc : 0xcba <d04> DW_AT_high_pc : 0xce9 <d08> DW_AT_frame_base : 0x3b8 (location list) <d0c> DW_AT_sibling : <0xd3c> <2><d10>: Abbrev Number: 27 (DW_TAG_formal_parameter) <d11> DW_AT_name : ctx <d15> DW_AT_decl_file : 3 <d16> DW_AT_decl_line : 327 <d18> DW_AT_type : <0x847> <d1c> DW_AT_location : 2 byte block: 91 0 (DW_OP_fbreg: 0) <2><d1f>: Abbrev Number: 27 (DW_TAG_formal_parameter) <d20> DW_AT_name : c <d22> DW_AT_decl_file : 3 <d23> DW_AT_decl_line : 327 <d25> DW_AT_type : <0xf7> <d29> DW_AT_location : 2 byte block: 91 5c (DW_OP_fbreg: -36) <2><d2c>: Abbrev Number: 44 (DW_TAG_variable) <d2d> DW_AT_name : (indirect string, offset: 0x67a): buffer <d31> DW_AT_decl_file : 3 <d32> DW_AT_decl_line : 329 <d34> DW_AT_type : <0xa2a> <d38> DW_AT_location : 2 byte block: 91 6c (DW_OP_fbreg: -20) --- snip ---
DW_AT_frame_base = 0x3b8 -> Location list for 0x3b8
--- snip --- $ objdump --dwarf=loc editline.o
editline.o: file format elf32-i386
Contents of the .debug_loc section:
... 000003b8 00000cba 00000cbb (DW_OP_breg4 (esp): 4) 000003c4 00000cbb 00000cbd (DW_OP_breg4 (esp): 8) 000003d0 00000cbd 00000ce8 (DW_OP_breg5 (ebp): 8) 000003dc 00000ce8 00000ce9 (DW_OP_breg4 (esp): 4) 000003e8 <End of list> ... --- snip ---
What might be the culprit here (see disassembly) is that 'c' is actually both: a function parameter ('DW_TAG_formal_parameter' -> 'cc0:') and a local variable ('cc3:'). The DWARF symbol info contains only one entry.
Maybe that's something that confuses the debugger (function parameter handler combined with negative addressing mode which ought to apply for local variable).
$ sha1sum odbg201.zip d41fe77a2801d38476f20468ab61ddce14c3abb8 odbg201.zip
$ du -sh odbg201.zip 6.7M odbg201.zip
$ wine --version wine-1.7.16-178-g7e874ae
Regards