http://bugs.winehq.org/show_bug.cgi?id=35991
Anastasius Focht [email protected] changed:
What |Removed |Added ---------------------------------------------------------------------------- Status|UNCONFIRMED |NEW CC| |[email protected] Summary|Communication via COM1 |WinProladder v3.23 crashes |crashes Fatek WinProladder |during 'PLC connect check' | |(async event poll worker | |writes to user event mask | |buffer whose lifetime is | |limited) Ever confirmed|0 |1
--- Comment #5 from Anastasius Focht [email protected] --- Hello folks,
confirming.
Can be reproduced without actual device, you just need a serial port (USB-to-serial adapter).
Create the dosdevice symlink (COM1) and have the app doing the scan the port using different baud rates/settings.
--- snip --- $ pwd /home/focht/.wine/drive_c/Program Files/Fatek/WinProladder
$ WINEDEBUG=+tid,+seh,+loaddll,+process,+comm,+ntdll,+relay wine ./WProlad.exe
log.txt 2>&1
... 003f:Starting thread proc 0x40004a60 (arg=0xcd6e50) 003f:Call KERNEL32.CreateEventA(00000000,ffffffff,ffffffff,00000000) ret=0038c151 003f:Ret KERNEL32.CreateEventA() retval=000000e0 ret=0038c151 003f:Call KERNEL32.CreateEventA(00000000,ffffffff,ffffffff,00000000) ret=0038c17a 003f:Ret KERNEL32.CreateEventA() retval=000000e4 ret=0038c17a 003f:Call KERNEL32.SetCommMask(000000d0,000001a1) ret=0038c1cb 003f:trace:comm:SetCommMask handle 0xd0, mask 1a1 003f:trace:ntdll:NtDeviceIoControlFile (0xd0,(nil),(nil),(nil),0x21be0f0,0x001b0044,0x21be1a4,0x00000004,(nil),0x00000000) 003f:trace:comm:io_control 0xd0 IOCTL_SERIAL_SET_WAIT_MASK 0x21be1a4 4 (nil) 0 0x21be0f0 003f:Ret KERNEL32.SetCommMask() retval=00000001 ret=0038c1cb 003f:Call KERNEL32.WaitForSingleObject(000000d4,00000000) ret=0038c47d 003f:Ret KERNEL32.WaitForSingleObject() retval=00000102 ret=0038c47d 003f:Call KERNEL32.WaitCommEvent(000000d0,021bea14,021be1e0) ret=0038c498 003f:trace:ntdll:NtDeviceIoControlFile (0xd0,0xe4,(nil),0x21be1e0,0x21be1e0,0x001b0048,(nil),0x00000000,0x21bea14,0x00000004) 003f:trace:comm:io_control 0xd0 IOCTL_SERIAL_WAIT_ON_MASK (nil) 0 0x21bea14 4 0x21be1e0 003f:trace:comm:wait_on commio=0x1a0f0d8, commio->events=0x1100b8 003f:trace:comm:get_irq_info TIOCGICOUNT err Inappropriate ioctl for device 003f:trace:comm:get_irq_info TIOCSERGETLSR err Inappropriate ioctl for device 003f:trace:comm:get_modem_status 0004 -> 003f:trace:comm:check_events mask 0x000001a1 003f:trace:comm:check_events old->rx 0x00000000 vs. new->rx 0x00000000 003f:trace:comm:check_events old->tx 0x00000000 vs. new->tx 0x00000000 003f:trace:comm:check_events old->frame 0x00000000 vs. new->frame 0x00000000 003f:trace:comm:check_events old->overrun 0x00000000 vs. new->overrun 0x00000000 003f:trace:comm:check_events old->parity 0x00000000 vs. new->parity 0x00000000 003f:trace:comm:check_events old->brk 0x00000000 vs. new->brk 0x00000000 003f:trace:comm:check_events old->buf_overrun 0x00000000 vs. new->buf_overrun 0x00000000 003f:trace:comm:check_events old->temt 0x00000001 vs. new->temt 0x00000001 003f:Ret KERNEL32.WaitCommEvent() retval=00000000 ret=0038c498 0026:trace:comm:wait_for_event commio=0x1a0f0d8 device=0xd0 fd=0x0000000f mask=0x000001a1 buffer=0x21bea14 event=0xe4 irq_info=0x1a0f0f8 003f:Call KERNEL32.GetLastError() ret=0038c4b6 003f:Ret KERNEL32.GetLastError() retval=000003e5 ret=0038c4b6 003f:Call KERNEL32.WaitForSingleObject(000000d4,00000000) ret=0038c31d 003f:Ret KERNEL32.WaitForSingleObject() retval=00000102 ret=0038c31d 003f:Call KERNEL32.ReadFile(000000d0,021be214,00000800,021bea1c,021be1f4) ret=0038c340 003f:trace:ntdll:NtReadFile (0xd0,0xe0,(nil),0x21be1f4,0x21be1f4,0x21be214,0x00000800,0x21be110,(nil)),partial stub! 003f:trace:ntdll:NtDeviceIoControlFile (0xd0,(nil),(nil),(nil),0x21bdf40,0x001b0020,(nil),0x00000000,0x21bdf48,0x00000014) 003f:trace:comm:io_control 0xd0 IOCTL_SERIAL_GET_TIMEOUTS (nil) 0 0x21bdf48 20 0x21bdf40 003f:trace:ntdll:NtReadFile = 0x00000103 003f:Ret KERNEL32.ReadFile() retval=00000000 ret=0038c340 003f:Call KERNEL32.GetLastError() ret=0038c35f 003f:Ret KERNEL32.GetLastError() retval=000003e5 ret=0038c35f 003f:Call KERNEL32.WaitForMultipleObjects(00000003,021be208,00000000,ffffffff) ret=0038c22c 0026:trace:comm:get_irq_info TIOCGICOUNT err Inappropriate ioctl for device 0026:trace:comm:get_irq_info TIOCSERGETLSR err Inappropriate ioctl for device 0026:trace:comm:get_modem_status 0004 -> 0026:trace:comm:check_events mask 0x000001a1 0026:trace:comm:check_events old->rx 0x00000000 vs. new->rx 0x00000000 0026:trace:comm:check_events old->tx 0x00000000 vs. new->tx 0x00000000 0026:trace:comm:check_events old->frame 0x00000000 vs. new->frame 0x00000000 0026:trace:comm:check_events old->overrun 0x00000000 vs. new->overrun 0x00000000 0026:trace:comm:check_events old->parity 0x00000000 vs. new->parity 0x00000000 0026:trace:comm:check_events old->brk 0x00000000 vs. new->brk 0x00000000 0026:trace:comm:check_events old->buf_overrun 0x00000000 vs. new->buf_overrun 0x00000000 0026:trace:comm:check_events old->temt 0x00000001 vs. new->temt 0x00000001 0026:trace:comm:get_irq_info TIOCGICOUNT err Inappropriate ioctl for device 0026:trace:comm:get_irq_info TIOCSERGETLSR err Inappropriate ioctl for device ... 003f:Ret KERNEL32.WaitForMultipleObjects() retval=00000000 ret=0038c22c 003f:Call KERNEL32.PurgeComm(000000d0,0000000a) ret=0038c2df 003f:trace:ntdll:NtDeviceIoControlFile (0xd0,(nil),(nil),(nil),0x21be100,0x001b004c,0x21be1a4,0x00000004,(nil),0x00000000) 003f:trace:comm:io_control 0xd0 IOCTL_SERIAL_PURGE 0x21be1a4 4 (nil) 0 0x21be100 003f:Ret KERNEL32.PurgeComm() retval=00000001 ret=0038c2df 003f:Call KERNEL32.CloseHandle(000000e0) ret=0038c2eb 003f:Ret KERNEL32.CloseHandle() retval=00000001 ret=0038c2eb 003f:Call KERNEL32.CloseHandle(000000e4) ret=0038c2f7 003f:Ret KERNEL32.CloseHandle() retval=00000001 ret=0038c2f7 003f:Call KERNEL32.ExitThread(00000000) ret=40004ae2 ... 0026:trace:comm:get_irq_info TIOCGICOUNT err Inappropriate ioctl for device 0026:trace:comm:get_irq_info TIOCSERGETLSR err Inappropriate ioctl for device 0026:trace:comm:get_modem_status 0004 -> 0026:trace:comm:check_events mask 0x000001a1 0026:trace:comm:check_events old->rx 0x00000000 vs. new->rx 0x00000000 0026:trace:comm:check_events old->tx 0x00000000 vs. new->tx 0x00000000 0026:trace:comm:check_events old->frame 0x00000000 vs. new->frame 0x00000000 0026:trace:comm:check_events old->overrun 0x00000000 vs. new->overrun 0x00000000 0026:trace:comm:check_events old->parity 0x00000000 vs. new->parity 0x00000000 0026:trace:comm:check_events old->brk 0x00000000 vs. new->brk 0x00000000 0026:trace:comm:check_events old->buf_overrun 0x00000000 vs. new->buf_overrun 0x00000000 0026:trace:comm:check_events old->temt 0x00000001 vs. new->temt 0x00000001 0026:trace:comm:get_irq_info TIOCGICOUNT err Inappropriate ioctl for device 0026:trace:comm:get_irq_info TIOCSERGETLSR err Bad file descriptor 0026:trace:comm:get_irq_info TIOCOUTQ err Bad file descriptor 0026:trace:ntdll:FILE_GetNtStatus errno = 9 0026:warn:comm:get_modem_status TIOCMGET err Bad file descriptor 0026:trace:ntdll:FILE_GetNtStatus errno = 9 0026:trace:comm:wait_for_event get_modem_status failed 0026:trace:seh:raise_exception code=c0000005 flags=0 addr=0x7bc7ee96 ip=7bc7ee96 tid=0026 0026:trace:seh:raise_exception info[0]=00000001 0026:trace:seh:raise_exception info[1]=021bea14 0026:trace:seh:raise_exception eax=021bea14 ebx=7bcd2000 ecx=00000000 edx=022bef8c esi=00000000 edi=021bea14 0026:trace:seh:raise_exception ebp=022be9d8 esp=022be920 cs=0023 ds=002b es=002b fs=0063 gs=006b flags=00210206 0026:trace:seh:call_stack_handlers calling handler at 0x7bc9f9f7 code=c0000005 flags=0 0026:Call KERNEL32.UnhandledExceptionFilter(022be3f4) ret=7bc9fa31 ... Unhandled exception: page fault on write access to 0x021bea14 in 32-bit code (0x7bc7ee96). Register dump: CS:0023 SS:002b DS:002b ES:002b FS:0063 GS:006b EIP:7bc7ee96 ESP:022be920 EBP:022be9d8 EFLAGS:00210206( R- -- I - -P- ) EAX:021bea14 EBX:7bcd2000 ECX:00000000 EDX:022bef8c ESI:00000000 EDI:021bea14 ... Backtrace: =>0 0x7bc7ee96 wait_for_event+0x1a2(arg=<couldn't compute location>) [/home/focht/projects/wine/wine.repo/src/dlls/ntdll/serial.c:951] in ntdll (0x022be9d8) 1 0x7bc90e67 worker_thread_proc+0x14d(param=<couldn't compute location>) [/home/focht/projects/wine/wine.repo/src/dlls/ntdll/threadpool.c:110] in ntdll (0x022bea48) 2 0x7bc87504 call_thread_func_wrapper+0xb() in ntdll (0x022bea68) 3 0x7bc8754d call_thread_func+0x3e(entry=0x7bc90d19, arg=0x0(nil), frame=0x22beb68) [/home/focht/projects/wine/wine.repo/src/dlls/ntdll/signal_i386.c:2629] in ntdll (0x022beb48) 4 0x7bc874e2 call_thread_entry_point+0x11() in ntdll (0x022beb68) 5 0x7bc8e92d start_thread+0x11a(info=0x7ffccfb8) [/home/focht/projects/wine/wine.repo/src/dlls/ntdll/thread.c:428] in ntdll (0x022bf3a8) 6 0xf75ce9da start_thread+0xc9() in libpthread.so.0 (0x022bf468) 7 0xf7500bfe __clone+0x5d() in libc.so.6 (0x00000000) ... 0x7bc7ee96 wait_for_event+0x1a2 [/home/focht/projects/wine/wine.repo/src/dlls/ntdll/serial.c:951] in ntdll: movl $0x0,0x0(%eax) 951 *commio->events = 0; Modules: Module Address Debug info Name (116 modules) PE 340000- 35a000 Deferred fautil10.bpl PE 360000- 380000 Deferred faplcdb10.bpl PE 380000- 3a2000 Deferred fawin50.bpl PE 3b0000- 3ba000 Deferred famnode10.bpl PE 3c0000- 3d5000 Deferred futil PE 400000- 846000 Deferred wprolad PE 850000- a41000 Deferred faiocfg10.bpl PE a50000- bb1000 Deferred prolad18 PE 32500000-32677000 Deferred cc3250mt PE 40000000-401f2000 Deferred vcl50.bpl PE 402f0000-40333000 Deferred vclx50.bpl PE 40b90000-40bc6000 Deferred nmfast50.bpl PE 41000000-4100c000 Deferred borlndmm ELF 4eb20000-4eb3d000 Deferred libgcc_s.so.1 PE 50600000-50629000 Deferred bcbsmp50.bpl ELF 7b800000-7ba61000 Deferred kernel32<elf> -PE 7b810000-7ba61000 \ kernel32 ... Threads: process tid prio (all id:s are in hex) ... 00000022 (D) C:\Program Files\Fatek\WinProladder\WProlad.exe 00000026 0 <== 00000023 0 --- snip ---
The app creates a reader thread which carries out the serial communication to decouple/avoid blocking the user interface. The reader thread calls 'WaitCommEvent' with a thread-stack based 'lpEvtMask' buffer (out parameter).
WaitCommEvent() returns with ERROR_IO_PENDING (expected) and the thread issues an overlapped ReadFile() which is waited on with WaitForMultipleObjects().
At one point the serial comm reader thread decides to give up, issues PurgeComm(), closes the event handles (cleanup) and terminates itself.
Earlier, Wine created an async worker in IOCTL_SERIAL_WAIT_ON_MASK ioctl handler using RtlQueueWorkItem(), which kicks off a poll routine in another thread, see wait_on() here:
http://source.winehq.org/git/wine.git/blob/a890d0f030a864d893646bd0c29dd7617...
A short time later the async worker polling loop figures out something is wrong ('get_modem_status' failed) and writes zero to the user-supplied event mask buffer.
This causes the crash because the original reader thread already terminated at that point and the buffer (thread stack variable) is no longer accessible -> *boom*
$ sha1sum Wprolad323-17205-1-ENU.exe 9491cb2a0fdc745594a30d2025c89b7c38f6b9ca Wprolad323-17205-1-ENU.exe
$ du -sh Wprolad323-17205-1-ENU.exe 3.2M Wprolad323-17205-1-ENU.exe
$ wine --version wine-1.7.16-134-g0ff879b
Regards