Add support for AF_UNIX sockets (followup)
Follow-up of !2786, which appears to have been abandoned.
Depends on !8182 (merged), !8575 (merged), !8578, !9835 (closed), !9831 (merged), !9835 (closed)
Execute minimal test case
- checkout wine into ~/src/wine
- in dlls/ws2_32/tests/sock.c wrap all calls to test functions after
Init()untiltest_afunix()with #if 0 ... #endif - build into ~/src/wine-build
- run
(cd ~/src/wine-build; \
WINEPREFIX=~/src/wine/.wine \
../wine/tools/runtest -q -P wine -T . -M ws2_32.dll \
-p dlls/ws2_32/tests/i386-windows/ws2_32_test.exe sock)
or without the wrapper and some imported wine debug channels enabled
(cd ~/src/wine-build;
WINEPREFIX=~/src/wine/.wine \
WINEDEBUG=+file,+winsock \
WINEDLLOVERRIDES=';ws2_32.dll=b' \
WINETEST_PLATFORM=wine \
./wine dlls/ws2_32/tests/i386-windows/ws2_32_test.exe sock)
How to debug wineserver
Since wineserver runs in the background, simple calls to printf() will show nothing when the test case is executed. A workaround is to open a file and call fprintf() to write debug messages to this file, which can then be inspected.
The wineserver man page mentions that there is limited support to control wineserver debugging by using WINEDEBUG=+server
-d[n], --debug[=n]
Set the debug level to n. 0 means no debugging information, 1 is the normal level, and 2 is for extra verbose debugging. If n is
not specified, the default is 1. The debug output will be sent to stderr. wine(1) will automatically enable normal level debugging
when starting wineserver if the +server option is set in the WINEDEBUG variable.
However, higher levels probably cannot be set in this way.
Problems with synchronized log output
- The Windows test binary prints test failures to stdout (line-buffered or fully buffered).
- Wine/Wineserver debug prints to stderr (unbuffered). When merged into a single stream (stderr+stdout), stdout lines get fragmented and interleaved between Wine/Wineserver trace messages., which looks like this:
012c:trace:file:NtWriteFile (0xd,(nil),(nil),(nil),0x6afd40,0x4190bc,0x00000012,(nil),(nil))
[?25lsock.c[?25h012c:trace:file:NtWriteFile = SUCCESS (18)
0124:trace:file:NtDeviceIoControlFile (0x10,(nil),(nil),(nil),0x74ddd0,0x00504000,(nil),0x00000000,0x74ddcc,0x00000004)xts={} )
Unfortunately, synchronized logs are important for analyzing processes.
Combining synchronized strace and wine trace messages can be generated with
#!/bin/bash -x
p=$PWD
cd ~/src/wine-build
WINEPREFIX=~/src/wine/.wine \
WINEDEBUG=+file,+winsock \
WINEDLLOVERRIDES=';ws2_32.dll=b' \
WINETEST_PLATFORM=wine \
stdbuf -o0 -eL strace -tt -f -o strace.log \
./wine dlls/ws2_32/tests/i386-windows/ws2_32_test.exe sock 2>&1 | ts 'WINE %H:%M:%.S' > wine.log
cat wine.log strace.log | grep -v 'write(\|read(\|rt_sigprocmask' | sort -k 2 > $p/trace.log
How to debug a wine test case
At https://gitlab.winehq.org/wine/wine/-/blob/master/tools/runtest#L151 there is mentioned a environment variable name WINETEST_WRAPPER, with which it may be possible to run gdb to debug test cases
(cd ~/src/wine-build; make -j10 ;\
WINETEST_WRAPPER="gdb --args" \
WINEPREFIX=~/src/wine/.wine \
../wine/tools/runtest -P wine -T . -M ws2_32.dll \
-p dlls/ws2_32/tests/i386-windows/ws2_32_test.exe sock)
Reading symbols from ./wine...
(gdb) set follow-fork-mode child
(gdb) r
current directory: 'Z:\home\ralf.habacker\src\wine-build'
sock.c:14624: Test failed: test_afunix.sock: wrong attr ffffffff
sock.c:14658: Test failed: test_afunix.sock: wrong family 0
sock.c:14693: Test failed: test_afunix.sock: wrong family 0
...
or without the wrapper and some important debug channels enabled
(cd ~/src/wine-build; \
make -j10; \
WINEDEBUG=+file,+winsock \
WINEDLLOVERRIDES=';ws2_32.dll=b' \
WINETEST_PLATFORM=wine \
gdb --args ./wine dlls/ws2_32/tests/i386-windows/ws2_32_test.exe sock)
With this you can debug the wine application, but unfortunally not the windows api.
How to debug a wine test case (windows api)
- After building wine install the binaries into a temporary location
make -C ~/src/wine-build install DESTDIR=~/src/wine-install
- run
(cd ../wine-build; \
WINEPREFIX=~/src/wine/.wine \
WINEDLLOVERRIDES=';ws2_32.dll=b' \
WINETEST_PLATFORM=wine \
./wine programs/winedbg/i386-windows/winedbg.exe --gdb dlls/ws2_32/tests/i386-windows/ws2_32_test.exe sock)
Now let's look at the loaded shared libraries
Wine-gdb> info sharedlibrary
From To Syms Read Shared Object Library
0xf7b39000 0xf7bff6e0 Yes /home/user/src/wine-build/dlls/ntdll/ntdll.so
0x00401000 0x00478e2c Yes /home/user/src/wine-build/dlls/ws2_32/tests/i386-windows/ws2_32_test.exe
0x7bcc1000 0x7bd69280 Yes /home/user/src/wine/.wine/drive_c/windows/system32/ntdll.dll
0x7bb31000 0x7bb91594 Yes /home/user/src/wine/.wine/drive_c/windows/system32/kernel32.dll
0x7b5b1000 0x7b841f38 Yes /home/user/src/wine/.wine/drive_c/windows/system32/kernelbase.dll
0x77fd1000 0x77ff89d8 Yes /home/user/src/wine/.wine/drive_c/windows/system32/iphlpapi.dll
0x7b4b1000 0x7b4ebcb8 Yes /home/user/src/wine/.wine/drive_c/windows/system32/advapi32.dll
0x7b1e1000 0x7b280014 Yes /home/user/src/wine/.wine/drive_c/windows/system32/msvcrt.dll
0x7b151000 0x7b16de40 Yes /home/user/src/wine/.wine/drive_c/windows/system32/sechost.dll
0x7adf1000 0x7aec2690 Yes /home/user/src/wine/.wine/drive_c/windows/system32/ucrtbase.dll
0x77f71000 0x77f85a80 Yes /home/user/src/wine/.wine/drive_c/windows/system32/dnsapi.dll
0x77f31000 0x77f3b240 Yes /home/user/src/wine/.wine/drive_c/windows/system32/nsi.dll
0x7ad41000 0x7ad6653c Yes /home/user/src/wine/.wine/drive_c/windows/system32/ws2_32.dll
0x7a111000 0x7a2cc55c Yes /home/user/src/wine/.wine/drive_c/windows/system32/user32.dll
0x7a631000 0x7a6ae67c Yes /home/user/src/wine/.wine/drive_c/windows/system32/gdi32.dll
0x7a0b1000 0x7a0e48e8 Yes /home/user/src/wine/.wine/drive_c/windows/system32/win32u.dll
0x78121000 0x7813de90 Yes /home/user/src/wine/.wine/drive_c/windows/system32/imm32.dll
It is visible, that the unix variant of the shared libraries (ntdll.so) are read from the build dir and also the test case.
The Windows part (*.dll) is loaded from the wine prefix, so that these must be copied from the build directory initially and whenever changes are made.
With this is possible to set breakpoints
Wine-gdb> b GetFileAttributesW@4
Breakpoint 1 at 0x7b5d3725: file ../wine/dlls/kernelbase/file.c, line 1665.
Wine-gdb> c
Continuing.
Breakpoint 1, GetFileAttributesW@4 (
name=0x40fcfa <test_afunix+1434> L"\xec83\x8304\xfff8\x940f\x89c0\x247c\xf08\xc0b6\x44c7\x424\x1bbf\103\x489\xe824\x52e6\001\x44c7", <incomplete sequence \x824>)
at ../wine/dlls/kernelbase/file.c:1665
1665 TRACE( "%s\n", debugstr_w(name) );
Followup
By adding WINESYSTEMDLLPATH=/home/user/src/wine-install/usr/local/lib/wine/i386-windows/ to the command line, some shared libraries are loaded directly from the build directory, so they do not need to be copied.
From To Syms Read Shared Object Library
0xf7eb2000 0xf7f786e0 Yes /home/user/src/wine-build/dlls/ntdll/ntdll.so
0x00401000 0x00478e2c Yes /home/user/src/wine-build/dlls/ws2_32/tests/i386-windows/ws2_32_test.exe
0x7bcc1000 0x7bd69280 Yes /home/user/src/wine/.wine/drive_c/windows/system32/ntdll.dll
0x7bb31000 0x7bb91594 Yes /home/user/src/wine/.wine/drive_c/windows/system32/kernel32.dll
0x7b5b1000 0x7b841f38 Yes /home/user/src/wine/.wine/drive_c/windows/system32/kernelbase.dll
0x77fd1000 0x77ff89d8 Yes /home/user/src/wine/.wine/drive_c/windows/system32/iphlpapi.dll
0x7b4b1000 0x7b4ebcb8 Yes /home/user/src/wine-install/usr/local/lib/wine/i386-windows/advapi32.dll
0x7b1e1000 0x7b280014 Yes /home/user/src/wine-install/usr/local/lib/wine/i386-windows/msvcrt.dll
0x7b151000 0x7b16de40 Yes /home/user/src/wine-install/usr/local/lib/wine/i386-windows/sechost.dll
0x7adf1000 0x7aec2690 Yes /home/user/src/wine-install/usr/local/lib/wine/i386-windows/ucrtbase.dll
0x77f71000 0x77f85a80 Yes /home/user/src/wine/.wine/drive_c/windows/system32/dnsapi.dll
0x77f31000 0x77f3b240 Yes /home/user/src/wine/.wine/drive_c/windows/system32/nsi.dll
0x7ad41000 0x7ad6653c Yes /home/user/src/wine-install/usr/local/lib/wine/i386-windows/ws2_32.dll
0x7a111000 0x7a2cc55c Yes /home/user/src/wine-install/usr/local/lib/wine/i386-windows/user32.dll
0x7a631000 0x7a6ae67c Yes /home/user/src/wine-install/usr/local/lib/wine/i386-windows/gdi32.dll
0x79e31000 0x79e648e8 Yes /home/user/src/wine-install/usr/local/lib/wine/i386-windows/win32u.dll
0x78121000 0x7813de90 Yes /home/user/src/wine/.wine/drive_c/windows/system32/imm32.dll
Why this does not apply to all system libraries is currently unclear. It would help if at least ntdll.dll could be loaded from the build directory as it gets several changes here.