https://bugs.kde.org/show_bug.cgi?id=527202
[email protected] changed: What |Removed |Added ---------------------------------------------------------------------------- CC| |[email protected] --- Comment #1 from [email protected] --- Independent reproduction on a second machine, plus the cause. Setup: CachyOS, krdp 6.8.0, Plasma 6.8.0 (kwin, xdg-desktop-portal-kde, kpipewire 6.8.0), FreeRDP 3.32.2, Qt 6.12.0, kernel 7.2.9, Wayland, NVIDIA RTX 2080 Ti (580.178.04, no VA-API H.264 encode, so libx264). Server started as `krdpserver --virtual-monitor 1800x1169@1 -u … -p …` (portal path). Client: Windows App 11.4.2 on macOS 27.0.1. Reconnects worked on krdp 6.7.5 with the same client. == Symptom == First connection after krdpserver starts works. Every later connection authenticates, the portal session starts, the encoder starts, and the client drops the TCP connection about 6 ms after the first frame. Windows App shows 0x200d. Server side: transport_read_layer: BIO_read retries exceeded transport_read_layer: ERRCONNECT_CONNECT_TRANSPORT_FAILED [0x0002000D] rdpgfx_server_handle_messages: WTSVirtualChannelRead failed! rdpgfx_server_thread_func: rdpgfx_server_handle_messages failed with error 1359 Those are the effect of the client hanging up, not the cause: `org.kde.krdp` debug logging shows no krdp warning before them, and the portal session reports "Started Freedesktop Portal session" normally each time. Same result with KRDP_DISABLE_H264=1 (progressive codec), so the codec is not involved. A second connection from sdl-freerdp3 (FreeRDP 3.32.2 client, same server process) works, so the client matters: FreeRDP tolerates what the server sends, Windows App does not. == Cause: uninitialised Surface in VideoStreamSurface == With WLOG_LEVEL=DEBUG, WLOG_FILTER=com.freerdp.channels.rdpgfx.server:TRACE on the server, the GFX PDUs the server sends at the first frame differ between the first and the second connection of the same process: First connection (works): rdpgfx_send_caps_confirm_pdu rdpgfx_send_reset_graphics_pdu rdpgfx_send_create_surface_pdu rdpgfx_send_map_surface_to_output_pdu rdpgfx_send_start_frame_pdu / surface_command / end_frame_pdu ... FRAMEACKNOWLEDGE, session runs Second connection (fails): rdpgfx_send_caps_confirm_pdu rdpgfx_send_delete_encoding_context_pdu <-- for a surface that was never created rdpgfx_send_delete_surface_pdu <-- same rdpgfx_send_reset_graphics_pdu rdpgfx_send_create_surface_pdu rdpgfx_send_map_surface_to_output_pdu rdpgfx_send_start_frame_pdu / surface_command / end_frame_pdu (6 ms later) transport_read_pdu() -1, client gone DeleteEncodingContext and DeleteSurface before any CreateSurface is exactly what `VideoStream::destroySurface()` emits when `d->surface->surface.id != 0` and `codecContextId != 0` at the top of the first `performReset()`. On a fresh connection both must be 0. They are not, because they are never initialised: src/VideoStreamSurface.h (Plasma/6.8 and master): struct Surface { uint16_t id; uint32_t codecContextId; QSize size; }; ... class VideoStreamSurface : public QObject { ... Surface surface; // no initialiser ... }; src/VideoStreamSurface.cpp: VideoStreamSurface::VideoStreamSurface(VideoStream *stream) : QObject(stream) , m_stream(stream) { } `Surface` has no default member initialisers and the constructor does not value-initialise `surface`, so `id` and `codecContextId` are indeterminate. The first VideoStreamSurface of the process usually lands on fresh (zeroed) heap pages, so it works. Later ones reuse freed memory and inherit garbage, so `destroySurface()` sends DeleteEncodingContext/DeleteSurface for bogus ids before ResetGraphics. Windows App treats a DeleteSurface for an unknown surfaceId as a protocol error and disconnects; FreeRDP-based clients only warn. That also explains why it looked like a portal-vs-plasma difference (different heap layout) and why nothing in PortalSession or xdg-desktop-portal-kde logs an error. The struct came in with 50120646 "Introduce a separate VideoStreamSurface object" (2026-09-08), which is why 6.7.5 is fine. 6.8.1 (d6b12bf5, 6d453c86) only touches authentication settings and does not change this. Suggested fix (either line is enough): - Surface surface; + Surface surface{}; or give the struct defaults: struct Surface { uint16_t id = 0; uint32_t codecContextId = 0; QSize size; }; `VideoStream::destroySurface()` already resets with `surface = Surface{}` after use, so only the initial state is wrong. == Repro == 1. `krdpserver --virtual-monitor 1800x1169@1 -u user -p pass` (plain portal mode without --virtual-monitor fails the same way for the other reporter). 2. Connect with Windows App (macOS 11.4.2 here), wait, disconnect. 3. Connect again: 0x200d within a second. Every further attempt fails until krdpserver restarts. 4. Optional: WLOG_LEVEL=DEBUG WLOG_APPENDER=JOURNALD WLOG_FILTER=com.freerdp.channels.rdpgfx.server:TRACE shows the two delete PDUs on connection 2. (Without the JOURNALD appender FreeRDP's console log is block-buffered under systemd and the lines appear only on the next flush.) == Workaround in use == A systemd --user unit that follows the krdpserver journal and restarts the service 2 s after each session ends (match on "ERRINFO_LOGOFF_BY_USER [" or "ERRCONNECT_CONNECT_TRANSPORT_FAILED"). --plasma is not an option with --virtual-monitor on 6.8.0 because of the pointer offset problem (bug 526783). -- You are receiving this mail because: You are watching all bug changes.
