Robert Baruch
2001-Dec-08 18:52 UTC
LoadOEMResource crash [Was: Re: Problem report: SHRINKER.ERR, fix to DEVICE_Open/CreateFileA? ]
Hooray, I got gdb to do what I need, to skip the first exception and break before the second. The key commands are: gdb (winepath)/bin/wine Set the arguments: > set args --winver nt40 yourapp Tell gdb to pass segmentation faults to the program: > handle SIGSEGV nostop pass Set a breakpoint at main: > b main Run the program: > run This loads all the shared libraries, and now we can set more breakpoints in those libraries. Set a breakpoint where wine handles exceptions, and continue the program: > break EXC_RtlRaiseException > cont Now the first exception should be hit. We continue again to hit the second exception: > cont And now I have a trace where the second exception will be called: Continuing. Program received signal SIGSEGV, Segmentation fault. Breakpoint 3, EXC_RtlRaiseException (rec=0x404f3c60, context=0x404f3cdc) at exception.c:176 176 TRACE( "code=%lx flags=%lx\n", rec->ExceptionCode, rec->ExceptionFlags ); (gdb) where #0 EXC_RtlRaiseException (rec=0x404f3c60, context=0x404f3cdc) at exception.c:176 #1 0x40076748 in do_segv (context=0x404f3cdc, trap_code=14, cr2=0x45f00c, err_code=4) at signal_i386.c:711 #2 0x40076ada in segv_handler (__signal=11, __context {sc_gs = 0, __gsh = 0, sc_fs = 143, __fsh = 0, sc_es = 43, __esh = 0, sc_ds = 43, __dsh = 0, sc_edi = 4583440, sc_esi = 4583424, sc_ebp = 1078935716, sc_esp = 1078935700, sc_ebx = 1074829380, sc_edx = 4583424, sc_ecx = 3117568, sc_eax = 14, sc_trapno = 14, sc_err = 4, sc_eip = 1074344288, sc_cs = 35, __csh = 0, sc_eflags = 66050, esp_at_signal = 1078935700, sc_ss = 43, __ssh = 0, i387 = 0, oldmask = 0, cr2 = 4583436}) at signal_i386.c:882 #3 <signal handler called> #4 find_entry_by_id (dir=0x45f000, id=14, root=0x45f000) at pe_resource.c:83 #5 0x4009322e in find_entry_by_nameW (dir=0x45f000, name=0xe, root=0x45f000) at pe_resource.c:115 #6 0x400934b4 in PE_FindResourceW (hmod=4194304, name=0x4074c30e, type=0xe) at pe_resource.c:239 #7 0x40094083 in RES_FindResource2 (hModule=4194304, type=0xe "", name=0x4074c30e "", lang=0, bUnicode=1, bRet16=0) at resource.c:197 #8 0x40093f4d in RES_FindResource2 (hModule=182, type=0xe "", name=0x4074c30e "", lang=0, bUnicode=1, bRet16=0) at resource.c:171 #9 0x40094140 in RES_FindResource (hModule=182, type=0xe "", name=0x4074c30e "", lang=0, bUnicode=1, bRet16=0) at resource.c:220 #10 0x40094453 in FindResourceW (hModule=182, name=0x4074c30e, type=0xe) at resource.c:360 #11 0x40718664 in CURSORICON_Load (hInstance=182, name=0x4074c30e, width=32, height=32, colors=256, fCursor=0, loadflags=32832) at cursoricon.c:735 #12 0x4071ade0 in LoadImageW (hinst=4194304, name=0x4074c30e, type=1, desiredx=32, desiredy=0, loadflags=32832) at cursoricon.c:2261 #13 0x4071a086 in LoadIconW (hInstance=4194304, name=0x4074c30e) at cursoricon.c:1765 #14 0x4070ff55 in STATIC_LoadIconW (hwnd=65570, name=0x4074c30e) at static.c:146 #15 0x40710278 in StaticWndProc_common (hwnd=65570, uMsg=129, wParam=0, lParam=1078937708, unicode=1) at static.c:254 #16 0x407104b1 in StaticWndProcW (hWnd=65570, uMsg=129, wParam=0, lParam=1078937708) at static.c:347 #17 0x4074070b in WINPROC_wrapper () at winproc.c:120 #18 0x40740796 in WINPROC_CallWndProc (proc=0x4071047c <StaticWndProcW>, hwnd=65570, msg=129, wParam=0, lParam=1078937708) at winproc.c:173 #19 0x4074635e in CallWindowProcW (func=0x4071047c <StaticWndProcW>, hwnd=65570, msg=129, wParam=0, lParam=1078937708) at winproc.c:2659 #20 0x406e6509 in call_window_proc (hwnd=65570, msg=129, wparam=0, lparam=1078937708, unicode=1) at message.c:1141 #21 0x406e700a in SendMessageTimeoutW (hwnd=65570, msg=129, wparam=0, lparam=1078937708, flags=0, timeout=4294967295, res_ptr=0x404f4540) at message.c:1529 #22 0x406e7277 in SendMessageW (hwnd=65570, msg=129, wparam=0, lparam=1078937708) at message.c:1610 #23 0x40b1b62e in X11DRV_CreateWindow (hwnd=65570, cs=0x404f486c, unicode=1) at window.c:882 #24 0x4073abec in WIN_CreateWindowEx (cs=0x404f486c, classAtom=49159, type=WIN_PROC_32W) at win.c:1177 #25 0x4073b154 in CreateWindowExW (exStyle=4, className=0x4074e8e8, windowName=0x4074c30e, style=1342177283, x=16, y=40, width=32, height=32, parent=65569, menu=1088, instance=4194304, data=0x0) at win.c:1392 #26 0x4071ed0c in DIALOG_CreateControls (hwnd=65569, template=0x4074c314 "", dlgTemplate=0x404f4958, hInst=0, win32=1) at dialog.c:487 #27 0x4071f891 in DIALOG_CreateIndirect (hInst=0, dlgTemplate=0x4074c2f8 "\003", owner=0, dlgProc=0x4072bae0 <MSGBOX_DlgProc>, param=1078938108, procType=WIN_PROC_32A, modal=1) at dialog.c:874 #28 0x4071ffb5 in DialogBoxIndirectParamA (hInstance=0, template=0x4074c2e0, owner=0, dlgProc=0x4072bae0 <MSGBOX_DlgProc>, param=1078938108) at dialog.c:1189 #29 0x4072bc2f in MessageBoxA (hWnd=0, text=0x75d4e0 "C:\\My Documents\\power-structure-demo.exe (3.4) 12/08/01 18:31:47 - Dispatcher initialisation error trapping exceptions", title=0x75b3e8 "SHRINKER.ERR", type=8240) at msgbox.c:294 #30 0x0075fc1a in ?? () #31 0x007604e6 in ?? () #32 0x6f442079 in ?? () Cannot access memory at address 0x4d5c3a43 (gdb) That's pretty cool. So the second exception gets thrown while the program is trying to pop up the message box caused by the first exception. I can crawl up the stack trace to list out the line that the exception occurs: (gdb) up #1 0x40076748 in do_segv (context=0x404f3cdc, trap_code=14, cr2=0x45f00c, err_code=4) at signal_i386.c:711 711 EXC_RtlRaiseException( &rec, context ); (gdb) up #2 0x40076ada in segv_handler (__signal=11, __context {sc_gs = 0, __gsh = 0, sc_fs = 143, __fsh = 0, sc_es = 43, __esh = 0, sc_ds = 43, __dsh = 0, sc_edi = 4583440, sc_esi = 4583424, sc_ebp = 1078935716, sc_esp = 1078935700, sc_ebx = 1074829380, sc_edx = 4583424, sc_ecx = 3117568, sc_eax = 14, sc_trapno = 14, sc_err = 4, sc_eip = 1074344288, sc_cs = 35, __csh = 0, sc_eflags = 66050, esp_at_signal = 1078935700, sc_ss = 43, __ssh = 0, i387 = 0, oldmask = 0, cr2 = 4583436}) at signal_i386.c:882 882 get_cr2_value(HANDLER_CONTEXT), get_error_code(HANDLER_CONTEXT) ); (gdb) up #3 <signal handler called> (gdb) up #4 find_entry_by_id (dir=0x45f000, id=14, root=0x45f000) at pe_resource.c:83 83 min = dir->NumberOfNamedEntries; (gdb) That's what I thought in the first place. I'll try to print out dir: (gdb) p dir $14 = (IMAGE_RESOURCE_DIRECTORY *) 0xc0000005 Huh? The stack trace says the argument is 0x45f000, not 0xc0000005. So I'll re-run the program, but this time I'll add a breakpoint at pe_resource.c:find_entry_by_id (just entering "find_entry_by_id" results in gdb setting the breakpoint in a file other than pe_resource): (gdb) run The program being debugged has been started already. Start it from the beginning? (y or n) y Starting program: /usr/local/wine/bin/wine --winver nt40 "/home/baruch/wine-c/My Documents/power-structure-demo.exe" Program received signal SIGSEGV, Segmentation fault. Breakpoint 3, EXC_RtlRaiseException (rec=0x404f4bc8, context=0x404f4c44) at exception.c:176 176 TRACE( "code=%lx flags=%lx\n", rec->ExceptionCode, rec->ExceptionFlags ); (gdb) break pe_resource.c:find_entry_by_id Breakpoint 7 at 0x40093156: file pe_resource.c, line 82. (gdb) cont Continuing. Breakpoint 7, find_entry_by_id (dir=0x40768240, id=0, root=0x40768240) at pe_resource.c:82 82 entry = (const IMAGE_RESOURCE_DIRECTORY_ENTRY *)(dir + 1); (gdb) Continuing. Breakpoint 7, find_entry_by_id (dir=0x40768790, id=16393, root=0x40768240) at pe_resource.c:82 82 entry = (const IMAGE_RESOURCE_DIRECTORY_ENTRY *)(dir + 1); (gdb) Continuing. Breakpoint 7, find_entry_by_id (dir=0x40768790, id=0, root=0x40768240) at pe_resource.c:82 82 entry = (const IMAGE_RESOURCE_DIRECTORY_ENTRY *)(dir + 1); (gdb) Continuing. Breakpoint 7, find_entry_by_id (dir=0x40768790, id=1024, root=0x40768240) at pe_resource.c:82 82 entry = (const IMAGE_RESOURCE_DIRECTORY_ENTRY *)(dir + 1); (gdb) Continuing. Breakpoint 7, find_entry_by_id (dir=0x45f000, id=0, root=0x45f000) at pe_resource.c:82 82 entry = (const IMAGE_RESOURCE_DIRECTORY_ENTRY *)(dir + 1); (gdb) p dir $16 = (IMAGE_RESOURCE_DIRECTORY *) 0x45f000 Better. (gdb) p *dir $17 = {Characteristics = 0, TimeDateStamp = 0, MajorVersion = 0, MinorVersion = 0, NumberOfNamedEntries = 0, NumberOfIdEntries = 0} Hmm. gdb is able to dereference dir. So what's going on? (gdb) step 78 { (gdb) step 82 entry = (const IMAGE_RESOURCE_DIRECTORY_ENTRY *)(dir + 1); (gdb) step 83 min = dir->NumberOfNamedEntries; (gdb) p dir $18 = (IMAGE_RESOURCE_DIRECTORY *) 0x45f000 So far so good. (gdb) step Program received signal SIGSEGV, Segmentation fault. Breakpoint 3, EXC_RtlRaiseException (rec=0x404f3c60, context=0x404f3cdc) at exception.c:176 176 TRACE( "code=%lx flags=%lx\n", rec->ExceptionCode, rec->ExceptionFlags ); What the #&@*#?! Looking at the assembly listing for find_entry_by_id, I can see that dir is stored in edx, and that edx contains 0xc0000005 at the time the signal handler breaks. So maybe that explains why gdb reported dir as 0xc0000005: (gdb) info scope pe_resource.c:find_entry_by_id Scope for pe_resource.c:find_entry_by_id: Symbol dir is an argument at stack/frame offset 8, length 4. Symbol id is an argument at stack/frame offset 12, length 4. Symbol root is an argument at stack/frame offset 16, length 4. Symbol dir is a local variable in register $edx, length 4. Symbol id is a local variable at frame offset -14, length 2. Symbol entry is a local variable at frame offset -12, length 4. Symbol min is a local variable in register $ecx, length 4. Symbol max is a local variable in register $esi, length 4. Symbol pos is a local variable in register $eax, length 4. So for some reason gdb duplicates the arguments as local variables, and then uses the local variable reference to print arguments :P Maybe this is the general optimized-code-trace problem. Anyway, we still haven't explained why the segfault in the first place! At this point I'm out of ideas. Why would gdb be able to deference dir manually, but generate a segfault when running that line? --Rob
gerard patel
2001-Dec-09 04:20 UTC
LoadOEMResource crash [Was: Re: Problem report: SHRINKER.ERR, fix to DEVICE_Open/CreateFileA? ]
On Sat, 08 Dec 2001 19:52:40 -0500, Robert Baruch <autophile@starband.net> wrote: <snip>>That's what I thought in the first place. I'll try to print out dir: > >(gdb) p dir >$14 = (IMAGE_RESOURCE_DIRECTORY *) 0xc0000005 > > >Huh? The stack trace says the argument is 0x45f000, not 0xc0000005.<snip> FYI Win32 uses a structure to control exception handling, structure including a code tagging the exception type. 0xc0000005 is the code that Win32 exception handling uses for a memory access violation. [gerard@duron wine]$ cd include/ [gerard@duron include]$ grep -i c0000005 *.h winnt.h:#define STATUS_ACCESS_VIOLATION 0xC0000005 Gerard
Apparently Analagous Threads
- LoadOEMResource crash [Was: Re: Problem report: SHRINKER.ERR, fix to DEVICE_Open/CreateFileA? ]
- LoadOEMResource crash [Was: Re: Problem report: SHRINKER.ERR, fix to DEVICE_Open/CreateFileA? ]
- kernel32.VirtualAlloc() limitation? - "Insufficient memory to perform operation"
- Problems with installing
- Wine release 1.5.30