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

  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; 
  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)

  1. After building wine install the binaries into a temporary location
make -C ~/src/wine-build install DESTDIR=~/src/wine-install
  1. 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.

Edited by Ralf Habacker

Merge request reports

Loading