mirror of
https://github.com/rustdesk/rustdesk.git
synced 2026-09-08 21:41:02 +03:00
drm: close the round-14 review findings
- the .so contract and deb assertions no longer pipe into grep. under `set -o pipefail`, `producer | grep -q` reports a FALSE FAILURE once the producer outruns the 64 KB pipe buffer: grep -q exits at the first match, the producer dies on SIGPIPE, and pipefail makes that the pipeline's status - so a library that HAS the symbol is reported as missing it and the step fails on a good build. measured on a real EGL-enabled .so (101 KB of strings, both markers present): the piped form reported both missing. this was introduced by the strictness fix two rounds ago and only passes today because a release-sized .so fits in the buffer. NOTE the obvious repair does not work either - materializing the output and piping the variable keeps the pipe and fails identically (measured), so these now match with bash's own pattern operator and no subprocess at all. verified with positive and negative controls. - warm_availability decides X11 for itself, inside its retry loop, with the UNMEMOISED `scrap::is_x11()`. this is the same one-shot-at -startup bug the pre-warm had, in its sibling call site, left behind when that one was fixed: the check ran during startup, where loginctl cannot yet name the seat0 session and the answer defaults to "x11", so a Wayland host that came up slowly skipped the warm for the life of the process and got back the cold-probe "No displays" symptom the warm exists to remove. the memoised form would have moved the bug rather than fixed it, since it latches its first answer. - the grab_desc SAFETY comment says what the frame protocol actually is instead of promising a release on every return path: traced in the C, a failing grab_desc leaves nothing to release (-EINVAL returns before allocating, a failed inner grab has already cleaned up, and -ENOTSUP releases the frame itself), so releasing on those paths would be a double free.
This commit is contained in:
@@ -365,8 +365,14 @@ impl DrmReader {
|
||||
/// libdrmtap that does not export this symbol (see `drmtap_dl::abi_accepted`).
|
||||
pub fn grab_desc(&mut self) -> io::Result<(OwnedFd, drmtap_dmabuf_desc)> {
|
||||
let grab_desc = self.lib.grab_desc;
|
||||
// SAFETY: self.ctx is a valid context; desc/frame are zeroed before the
|
||||
// call and the frame is released on every return path (after the dup).
|
||||
// SAFETY: self.ctx is a valid context; desc/frame are zeroed before the call. The frame is
|
||||
// released on every return path that OWNS one, which is not the same as every return path:
|
||||
// a failing `drmtap_grab_desc` leaves nothing for us to release, and releasing anyway would
|
||||
// be a double free. Traced in the C rather than assumed -- on `-EINVAL` it returns before
|
||||
// allocating, on a failed inner grab that grab has already cleaned up after itself, and on
|
||||
// `-ENOTSUP` (pixels but no transferable fd) libdrmtap calls `drmtap_frame_release` ITSELF
|
||||
// before returning. So the error arm below deliberately returns without releasing, and only
|
||||
// the paths that reach a populated frame release it, after dupping the fd out of it.
|
||||
unsafe {
|
||||
let mut desc: drmtap_dmabuf_desc = std::mem::zeroed();
|
||||
let mut frame: drmtap_frame_info = std::mem::zeroed();
|
||||
|
||||
Reference in New Issue
Block a user