Follow-up of !2786, which appears to have been abandoned.
Depends on !8182, !8575, !8578
# Execute minimal test case
1. checkout wine into ~/src/wine 2. in dlls/ws2_32/tests/sock.c wrap all calls to test functions after `Init()` until `test_afunix()` with #if 0 ... #endif 3. build into ~/src/wine-build 4. 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; 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.
# 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)
1. After building wine install the binaries into a temporary location
``` make -C ~/src/wine-build install DESTDIR=~/src/wine-install ```
2. 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.
-- v46: lookup_unix_name(): fix bug not terminating wide string correctly ws2_32: Add note in bind() for AF_UNIX sockets ws2_32/tests: In tests for AF_UNIX sockets print actual directory used server: Fix getsockname() and accept() on AF_UNIX sockets. server: Introduce error when attempting to create a SOCK_DGRAM AF_UNIX socket. ws2_32: Add support for AF_UNIX sockets. server: Allow for deletion of socket files.