https://bugs.winehq.org/show_bug.cgi?id=10924
Anastasius Focht focht@gmx.net changed:
What |Removed |Added ---------------------------------------------------------------------------- CC| |focht@gmx.net Component|-unknown |ntdll Hardware|Other |x86 Version|unspecified |0.9.51. OS|other |Linux
--- Comment #10 from Anastasius Focht focht@gmx.net --- Hello folks,
confirming, still present.
JDK prerequisite can be downloaded here:
http://www.atteya.net/site/en/downloads/java-jdk?download=47:java-jdk-6u45-w...
To install JDK in unattended, silent mode:
--- snip --- $ wine jdk-6u45-windows-i586.exe /s --- snip ---
To avoid resetting the WINEPREFIX every time after testing (installer complains about already running installer after abort due to lockfiles):
--- snip --- $ wine cmd.exe /C "rmdir %USERPROFILE%\.nbi /s /q" --- snip ---
The bootstapper process spawns several Java JVMs to execute prerequisite checks and finally for the full installer which lives in a Java bundle.
For each process a set of named pipes is created for stdin/out/err redirection. Additionally a 'wineconsole' process is created implicitly due to the nature of 'java.exe' being a console process type.
The process/thread ids for better overview:
--- snip --- Wine-dbg>info thread
process tid prio (all id:s are in hex) 00000008 netbeans-6.0.1-ml-javase-windows.exe 00000022 0 00000009 0 ... 00000030 (D) C:\Program Files\Java\jre6\bin\java.exe 0000000b 1 00000047 0 00000046 0 00000045 0 00000044 0 00000042 0 00000041 0 0000003f 0 0000003e 0 0000003d 2 0000003c 2 0000003b 0 0000003a 2 00000039 2 00000038 2 00000037 1 00000036 2 00000035 2 00000034 0 00000031 0 00000032 wineconsole.exe 00000033 0 --- snip ---
Trace log:
--- snip --- $ WINEDEBUG=+tid,+seh,+loaddll,+process,+wineconsole,+relay,+server wine ./netbeans-6.0.1-ml-javase-windows.exe >>log.txt 2>&1 ... 0022:Call KERNEL32.CreatePipe(0067e9e8,0067e9ec,0067e9d4,00000000) ret=004075ef 0022: create_named_pipe( access=80100000, attributes=00000042, rootdir=0000, options=00000020, sharing=00000002, maxinstances=00000001, outsize=00000000, insize=00000000, timeout=0, flags=00000000, name=L"\??\pipe\Win32.Pipes.00000008.00000007" ) 0022: create_named_pipe() = 0 { handle=0090 } 0022: open_file_object( access=40100000, attributes=00000042, rootdir=0000, sharing=00000000, options=00000060, filename=L"\??\pipe\Win32.Pipes.00000008.00000007" ) 0022: open_file_object() = 0 { handle=0094 } 0022:Ret KERNEL32.CreatePipe() retval=00000001 ret=004075ef ... 0022:Call KERNEL32.CreatePipe(0067e9e0,0067e9e4,0067e9d4,00000000) ret=00407639 0022: create_named_pipe( access=80100000, attributes=00000042, rootdir=0000, options=00000020, sharing=00000002, maxinstances=00000001, outsize=00000000, insize=00000000, timeout=0, flags=00000000, name=L"\??\pipe\Win32.Pipes.00000008.00000008" ) 0022: create_named_pipe() = 0 { handle=0098 } 0022: open_file_object( access=40100000, attributes=00000042, rootdir=0000, sharing=00000000, options=00000060, filename=L"\??\pipe\Win32.Pipes.00000008.00000008" ) 0022: open_file_object() = 0 { handle=009c } 0022:Ret KERNEL32.CreatePipe() retval=00000001 ret=00407639 ... 0022:Call KERNEL32.CreateProcessW(00000000,0014fab0 L""C:\Program Files\Java\jre6\bin\java.exe" -Djava.io.tmpdir=C:\users\focht\Temp\ -Xmx256m -Xms64m -classpath C:\users\focht\Temp\\NBI33045.tmp\bundle.jar org.netbeans.installer.Installer ",00000000,00000000,00000001,0c000030,00000000,0013eab8 L"Z:\home\focht\Downloads",0067e96c,0067e9c4) ret=00407718 ... 0022:trace:process:create_process_impl app (null) cmdline L""C:\Program Files\Java\jre6\bin\java.exe" -Djava.io.tmpdir=C:\users\focht\Temp\ -Xmx256m -Xms64m -classpath C:\users\focht\Temp\\NBI33045.tmp\bundle.jar org.netbeans.installer.Installer " ... 0031: get_startup_info() = 0 { exe_file=0014, info_size=968, info={debug_flags=0,console_flags=0,console=0001,hstdin=0088,hstdout=0094,hstderr=009c, ... 0022:trace:process:create_process_impl started process pid 0030 tid 0031 ... 0022:Ret KERNEL32.CreateProcessW() retval=00000001 ret=00407718 ... 0031:trace:process:create_process_impl app (null) cmdline L"wineconsole --use-event=20" ... 0033: get_startup_info() = 0 { exe_file=001c, info_size=656, info={debug_flags=0,console_flags=0,console=0000,hstdin=0088,hstdout=0094,hstderr=009c ... 0031:trace:process:create_process_impl started process pid 0032 tid 0033 ... 0033: get_console_mode( handle=0088 ) 0033: get_console_mode() = OBJECT_TYPE_MISMATCH { mode=0 } 0033: get_console_mode( handle=0094 ) 0033: get_console_mode() = ACCESS_DENIED { mode=0 } 0033: get_console_mode( handle=009c ) 0033: get_console_mode() = ACCESS_DENIED { mode=0 } ... 0033:Starting process L"C:\windows\system32\wineconsole.exe" (entryproc=0x7edd1a80) ... 0033:trace:wineconsole:WINECON_Init using hConIn 0x28, hSynchro event 0x2c 0033: create_console_output( handle_in=0028, access=c0000000, attributes=00000000, share=00000003, fd=-1 ) 0033: create_console_output() = 0 { handle_out=0034 } 0033:trace:wineconsole:WINECON_Init using hConOut 0x34 ... --- snip ---
Within the JVM, another helper thread is created which writes to stdout:
--- snip --- 0031:Call KERNEL32.CreateThread(00000000,00000000,00408545,004342e8,00010000,0033fa94) ret=00408640 ... 0031:Ret KERNEL32.CreateThread() retval=00000068 ret=00408640 ... 0034: init_thread() = 0 { pid=0030, tid=0034, server_start=1cfdfbad7352e2c (-3.7657530), info_size=0, version=457, all_cpus=00000001 } ... 0034:Call KERNEL32.GetProcAddress(6d330000,00545990 "_Java_java_io_FileDescriptor_set@12") ret=6d8f6412 0034:Ret KERNEL32.GetProcAddress() retval=6d331cba ret=6d8f6412 0034:Call KERNEL32.GetStdHandle(fffffff6) ret=6d331cca 0034:Ret KERNEL32.GetStdHandle() retval=00000088 ret=6d331cca 0034:Call KERNEL32.GetStdHandle(fffffff5) ret=6d331cca 0034:Ret KERNEL32.GetStdHandle() retval=00000094 ret=6d331cca 0034:Call KERNEL32.GetStdHandle(fffffff4) ret=6d331cca 0034:Ret KERNEL32.GetStdHandle() retval=0000009c ret=6d331cca ... 0034:Call KERNEL32.CreateFileW(005ebe00 L"C:\users\focht\.nbi\log\20141004125823.log",40000000,00000003,00000000,00000002,00000080,00000000) ret=6d33479a 0034:Ret KERNEL32.CreateFileW() retval=000001b4 ret=6d33479a ... 0034:Call KERNEL32.WriteFile(00000094,0085c424,00000051,0085c3fc,00000000) ret=6d334a71 0034:Ret KERNEL32.WriteFile() retval=00000001 ret=6d334a71 0034:Call KERNEL32.WriteFile(00000094,0085c454,00000002,0085c42c,00000000) ret=6d334a71 0034:Ret KERNEL32.WriteFile() retval=00000001 ret=6d334a71 ... 0022:Call KERNEL32.PeekNamedPipe(00000090,0067e128,000003ff,0067e0dc,0067e0cc,00000000) ret=0040732e 0022:Ret KERNEL32.PeekNamedPipe() retval=00000001 ret=0040732e 0022:Call KERNEL32.ReadFile(00000090,0067e128,000003ff,0067e0dc,00000000) ret=004072cb 0034:Call KERNEL32.WriteFile(000001b4,0085c514,00000044,0085c4ec,00000000) ret=6d334a71 0034:Ret KERNEL32.WriteFile() retval=00000001 ret=6d334a71 0022:Ret KERNEL32.ReadFile() retval=00000001 ret=004072cb
<this is the last time a 'ReadFile' on pipe is seen in the parent>
0022:Call KERNEL32.WriteFile(00000004,0067e128,000001f4,0067e0bc,00000000) ret=004072ef [2014-10-04 12:58:23.632]: entering -- org.netbeans.installer.Installer.main():99 [2014-10-04 12:58:23.638]: initializing the installer engine [2014-10-04 12:58:23.652]: entering -- org.netbeans.installer.Installer.<init>():156 [2014-10-04 12:58:23.652]: dumping target system information [2014-10-04 12:58:23.652]: system properties: [2014-10-04 12:58:23.653]: awt.toolkit => sun.awt.windows.WToolkit [2014-10-04 12:58:23.653]: file.encoding => Cp1252 ... 0022:Call KERNEL32.WriteFile(00000004,0067e128,00000332,0067e0bc,00000000) ret=004072ef [2014-10-04 12:58:23.654]: java.vm.info => mixed mode, sharing [2014-10-04 12:58:23.654]: java.vm.name => Java HotSpot(TM) Client VM [2014-10-04 12:58:23.654]: java.vm.specification.name => Java Virtual Machine Specification [2014-10-04 12:58:23.654]: java.vm.specification.vendor => Sun Microsystems Inc. [2014-10-04 12:58:23.654]: java.vm.specification.version => 1.0 [2014-10-04 12:58:23.654]: java.vm.vendor => Sun Microsystems Inc. [2014-10-04 12:58:23.654]: java.vm.version => 20.45-b01 [2014-10-04 12:58:23.654]: line.separator => [2014-10-04 12:58:23.654]: os.arch => x86 [2014-10-04 12:58:23.655]: os.name => Windows XP [2014-10-04 12:58:23.655]: os.version => 5.1 ... --- snip ---
The parent process periodically polls the named pipes which are connected to the child process via std handles -> 'PeekNamedPipe(00000090, ...)' and writes to its own stdout -> 'WriteFile(00000004, ...)'. Additionally there is a log file (handle=000001b4) which is also written to.
At one point another JNI library is loaded within the VM which also starts writing to the log file and stdout:
--- snip --- ... 0034:Call KERNEL32.CreateThread(00000000,00000000,7c3494f6,032b38f0,00010004,0085e634) ret=7c3495f0 ... 0044: init_thread() = 0 { pid=0030, tid=0044, server_start=1cfdfbad7352e2c (-6.9984780), info_size=0, version=457, all_cpus=00000001 } ... 0034:Ret KERNEL32.CreateThread() retval=00000308 ret=7c3495f0 ... 0044:Call KERNEL32.CreateFileW(03368918 L"C:\users\focht\Temp\nbi-3176498415577698668.tmp",40000000,00000003,00000000,00000002,00000080,00000000) ret=6d33479a 0044:Ret KERNEL32.CreateFileW() retval=0000032c ret=6d33479a ... 0044:trace:loaddll:load_native_dll Loaded L"C:\users\focht\Temp\nbi-3176498415577698668.tmp" at 0x10000000: native ... 0044:Call KERNEL32.GetStdHandle(fffffff5) ret=10006a05 0044:Ret KERNEL32.GetStdHandle() retval=00000094 ret=10006a05 0044:Call KERNEL32.GetFileType(00000094) ret=10006a17 0044:Ret KERNEL32.GetFileType() retval=00000003 ret=10006a17 ... 0044:Call KERNEL32.GetProcAddress(10000000,0326e0b0 "_Java_org_netbeans_installer_utils_system_windows_WindowsRegistry_getStringValue0@24") ret=6d331a97 0044:Ret KERNEL32.GetProcAddress() retval=100019af ret=6d331a97 ... 0044:Call KERNEL32.WriteFile(000001b4,0415c0c4,00000065,0415c09c,00000000) ret=6d334a71 0044:Ret KERNEL32.WriteFile() retval=00000001 ret=6d334a71 0044:Call KERNEL32.WriteFile(00000094,0415bfd4,00000063,0415bfac,00000000) ret=6d334a71 0044:Ret KERNEL32.WriteFile() retval=00000001 ret=6d334a71 0044:Call KERNEL32.WriteFile(00000094,0415c004,00000002,0415bfdc,00000000) ret=6d334a71
<thread 0044 now blocks forever on the pipe>
0022:Call KERNEL32.Sleep(00000001) ret=00407468 0022:Ret KERNEL32.Sleep() retval=00000000 ret=00407468 0022:Call KERNEL32.PeekNamedPipe(00000090,0067e128,000003ff,0067e0dc,0067e0cc,00000000) ret=0040732e 0022:Ret KERNEL32.PeekNamedPipe() retval=00000001 ret=0040732e 0022:Call KERNEL32.PeekNamedPipe(00000098,0067e128,000003ff,0067e0d0,0067e0c0,00000000) ret=0040732e 0022:Ret KERNEL32.PeekNamedPipe() retval=00000001 ret=0040732e 0022:Call KERNEL32.PeekNamedPipe(00000088,0067e128,000003ff,0067e0c4,0067e0b4,00000000) ret=0040732e 0022:Ret KERNEL32.PeekNamedPipe() retval=00000001 ret=0040732e 0022:Call KERNEL32.GetExitCodeProcess(000000a8,0067e124) ret=004074a8 0022: get_process_info( handle=00a8 ) 0022: get_process_info() = 0 { pid=0030, ppid=0008, affinity=0000000f, peb=7ffdf000, start_time=1cfdfbad93e45fa (-12.0077230), end_time=0, exit_code=259, priority=2, cpu=x86, debugger_present=0 } 0022:Ret KERNEL32.GetExitCodeProcess() retval=00000001 ret=004074a8 <sequence repeats over again> --- snip ---
Thread 0022 child stdin/out/err named pipe peek repeats all the time but no further reads are seen -> 'ReadFile(00000090, ...)'. They simply stop at some point but the child still keeps writing data to the other pipe end.
When the pipe buffer limit is reached, the write will block, causing the GUI to freeze (simplified, it's more complicated though, there are several threads in the VM which are "chained" through events).
If the parent process is left out of the equation (which also removes the std pipe redirection), the installer works fine:
You need to copy/find the extracted 'bundle.jar' from temp install folder.
--- snip --- $ wine "C:\Program Files\Java\jre6\bin\java.exe" -Djava.io.tmpdir="C:\users\focht\Temp" -Xmx256m -Xms64m -classpath "bundle.jar" org.netbeans.installer.Installer --- snip ---
Down to the metal ...
The code from the parent process (bootstrapper) in question:
--- snip --- ... 00407315 PUSH ECX ; NULL 00407316 LEA EAX,DWORD PTR SS:[EBP-4] 00407319 PUSH EAX ; &bytesAvail 0040731A LEA EAX,DWORD PTR SS:[EBP+C] 0040731D PUSH EAX ; &bytesRead 0040731E MOV ESI,3FF 00407323 PUSH ESI ; PIPE_BUFLEN-1 = 0x3ff (1023) 00407324 PUSH EDI ; Buffer 00407325 PUSH DWORD PTR SS:[EBP+8] ; hPipe 00407328 CALL DWORD PTR DS:[<&KERNEL32.PeekNamedPipe>] 0040732E CMP DWORD PTR SS:[EBP+C],0 00407332 JE SHORT netbeans.0040737B ; fast fail 00407334 PUSH 4 00407336 POP ECX ; 4 bytes ??? 00407337 MOV EAX,EDI 00407339 MOV BYTE PTR DS:[EAX],0 ; zero bytes on pipe buffer 0040733C INC EAX 0040733D DEC ECX 0040733E JNZ SHORT netbeans.00407339 00407340 CMP DWORD PTR SS:[EBP-4],400 ; bytesAvail >= PIPE_BUFLEN? 00407347 JNB SHORT netbeans.00407374 ; -> check bytesRead 00407349 PUSH DWORD PTR SS:[EBP+10] ; Arg4 = handle 0040734C LEA EAX,DWORD PTR SS:[EBP+C] 0040734F PUSH EAX ; Arg3 = &bytesRead 00407350 PUSH EDI ; Arg2 = Buffer 00407351 PUSH DWORD PTR SS:[EBP+8] ; Arg1 = hPipe 00407354 CALL netbeans.004072B0 ; ReadFile on the pipe buffer 00407359 ADD ESP,10 0040735C MOV EAX,DWORD PTR SS:[EBP+C] ; bytesRead 0040735F JMP SHORT netbeans.0040737D ; return bytesRead 00407361 PUSH DWORD PTR SS:[EBP+10] ; Arg4 = handle 00407364 LEA EAX,DWORD PTR SS:[EBP+C] 00407367 PUSH EAX ; Arg3 = &bytesRead 00407368 PUSH EDI ; Arg2 = Buffer 00407369 PUSH DWORD PTR SS:[EBP+8] ; Arg1 = hPipe 0040736C CALL netbeans.004072B0 ; ReadFile on the pipe buffer 00407371 ADD ESP,10 00407374 CMP DWORD PTR SS:[EBP+C],ESI ; bytesRead >= PIPE_BUFLEN-1 ? 00407377 JNB SHORT netbeans.00407361 ; read loop 00407379 JMP SHORT netbeans.0040735C 0040737B XOR EAX,EAX ; return 0 0040737D POP EDI 0040737E POP ESI 0040737F LEAVE 00407380 RETN --- snip ---
The following C-code snippet is basically the above assembly translated:
--- snip --- ... DWORD bytesRead; DWORD bytesAvail;
PeekNamedPipe(hPipe, buf, PIPE_BUFLEN-1, &bytesRead, &bytesAvail, NULL); if (bytesRead != 0) { /* probably a sizeof(buf) vs. sizeof(*buf) bug in this garbage code */ zero_out_first_four_bytes_on_buf();
if (bytesAvail >= PIPE_BUFLEN) { while (bytesRead >= PIPE_BUFLEN-1) { /* ReadFile(hPipe, buf, PIPE_BUFLEN-1, &bytesRead, NULL) */ read_buf_helper(hPipe, buf, &bytesRead, hSomeHandle); } } else { readBuf(hRead, buf, &bytesRead, hSomeHandle); } return bytesRead; } return 0; } --- snip ---
Following is a custom trace of pipe peek to illustrate the problem from the Linux side, after 'recv( ... MSG_PEEK)' call.
I instrumented this code: http://source.winehq.org/git/wine.git/blob/82ce3fdcfd1a5d8bfe24d58dcc51ddc3a...
'recv' is not even guaranteed to return all data that is currently buffered.
--- snip --- 0022:trace:ntdll:NtFsControlFile **** avail=61, data_size=1023, recv_res=8 0022:trace:ntdll:NtFsControlFile **** avail=61, data_size=1023, recv_res=61 0022:trace:ntdll:NtFsControlFile **** avail=568, data_size=1023, recv_res=81 0022:trace:ntdll:NtFsControlFile **** avail=463, data_size=1023, recv_res=2 0022:trace:ntdll:NtFsControlFile **** avail=366, data_size=1023, recv_res=2 0022:trace:ntdll:NtFsControlFile **** avail=511, data_size=1023, recv_res=91 0022:trace:ntdll:NtFsControlFile **** avail=514, data_size=1023, recv_res=78 0022:trace:ntdll:NtFsControlFile **** avail=434, data_size=1023, recv_res=92 0022:trace:ntdll:NtFsControlFile **** avail=809, data_size=1023, recv_res=60 0022:trace:ntdll:NtFsControlFile **** avail=809, data_size=1023, recv_res=2 0022:trace:ntdll:NtFsControlFile **** avail=1149, data_size=1023, recv_res=57 0022:trace:ntdll:NtFsControlFile **** avail=2630, data_size=1023, recv_res=57 0022:trace:ntdll:NtFsControlFile **** avail=4248, data_size=1023, recv_res=57 0022:trace:ntdll:NtFsControlFile **** avail=5577, data_size=1023, recv_res=57 ... 0022:trace:ntdll:NtFsControlFile **** avail=12187, data_size=1023, res=57 --- snip ---
The only way to work around this app garbage code is to limit 'buffer->ReadDataAvailable' to not exceed caller 'data_size'. With that fix in place the installer works.
If Alexandre doesn't want this limitation, the bug is a WONTFIX (stupid app).
$ sha1sum netbeans-6.0.1-ml-javase-windows.exe 70e8a3426214bb47f4db01570849903a3ab44960 netbeans-6.0.1-ml-javase-windows.exe
$ du -sh netbeans-6.0.1-ml-javase-windows.exe 28M netbeans-6.0.1-ml-javase-windows.exe
$ wine --version wine-1.7.28
Regards