Commit d170f5e
fix: prevent indefinite blocking in fetchWindowPreview pipe read
When KWin's screenshot service encounters an internal error, it may
hold the write end of the pipe open without writing any data and
without closing it. In this case, the previous blocking `QFile::read()`
would wait forever, hanging the taskbar process.
Three issues are fixed in fetchWindowPreview():
1. Replace `pipe()` with `pipe2(fd, O_CLOEXEC)` to prevent the write
fd from being inherited by child processes, which would also cause
read() to block indefinitely.
2. Replace the blocking `QFile::read()` with a `poll()`-based read
loop with a 5-second timeout. If KWin stalls or the pipe produces
no data within the timeout, the function aborts gracefully and
returns an empty QPixmap instead of hanging.
3. Fix the read buffer size calculation: use `imageHeight * imageStride`
instead of `imageWidth * imageHeight * bpp / 8`. imageStride is the
actual bytes-per-row (including alignment padding) as reported by
KWin, and may be larger than width * bpp/8. The old calculation
could result in reading too few bytes, leading to an out-of-bounds
access when constructing QImage. Also added image.copy() to ensure
the QImage owns its data independently of the fileContent buffer.
当 KWin 截图服务发生内部异常时,可能持有管道写端却不写入任何数据
也不关闭,导致原先的阻塞式 `QFile::read()` 永久等待,任务栏进程卡死。
本次修复了 fetchWindowPreview() 中的三个问题:
1. 将 `pipe()` 改为 `pipe2(fd, O_CLOEXEC)`,防止写端 fd 被 fork
出的子进程继承,否则子进程持有写端也会导致 read() 永久阻塞。
2. 将阻塞式 `QFile::read()` 替换为带 5 秒超时的 `poll()` 读取循环。
若 KWin 卡顿或管道在超时内无数据,函数会提前退出并返回空的
QPixmap,而不是使进程永久挂起。
3. 修正读取缓冲区大小计算:使用 `imageHeight * imageStride` 而非
`imageWidth * imageHeight * bpp / 8`。imageStride 是 KWin 返回的
每行实际字节数(含内存对齐 padding),可能大于 width*bpp/8。
原来的计算会导致读取字节数偏小,在构造 QImage 时发生越界访问。
同时添加 image.copy() 确保 QImage 独立持有数据。
Log: prevent indefinite blocking in fetchWindowPreview pipe read1 parent d12b2dd commit d170f5e
1 file changed
Lines changed: 46 additions & 13 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
1 | | - | |
| 1 | + | |
2 | 2 | | |
3 | 3 | | |
4 | 4 | | |
| |||
11 | 11 | | |
12 | 12 | | |
13 | 13 | | |
| 14 | + | |
| 15 | + | |
14 | 16 | | |
15 | 17 | | |
16 | 18 | | |
| |||
73 | 75 | | |
74 | 76 | | |
75 | 77 | | |
76 | | - | |
| 78 | + | |
77 | 79 | | |
78 | 80 | | |
79 | 81 | | |
| |||
113 | 115 | | |
114 | 116 | | |
115 | 117 | | |
116 | | - | |
117 | | - | |
118 | | - | |
119 | | - | |
120 | | - | |
121 | | - | |
122 | | - | |
123 | 118 | | |
124 | | - | |
125 | 119 | | |
126 | | - | |
127 | | - | |
128 | | - | |
| 120 | + | |
| 121 | + | |
| 122 | + | |
| 123 | + | |
| 124 | + | |
| 125 | + | |
| 126 | + | |
| 127 | + | |
| 128 | + | |
| 129 | + | |
| 130 | + | |
| 131 | + | |
| 132 | + | |
| 133 | + | |
| 134 | + | |
| 135 | + | |
| 136 | + | |
| 137 | + | |
| 138 | + | |
| 139 | + | |
| 140 | + | |
| 141 | + | |
| 142 | + | |
| 143 | + | |
| 144 | + | |
| 145 | + | |
| 146 | + | |
| 147 | + | |
| 148 | + | |
| 149 | + | |
| 150 | + | |
| 151 | + | |
| 152 | + | |
| 153 | + | |
129 | 154 | | |
| 155 | + | |
| 156 | + | |
| 157 | + | |
| 158 | + | |
| 159 | + | |
| 160 | + | |
| 161 | + | |
| 162 | + | |
130 | 163 | | |
131 | 164 | | |
132 | 165 | | |
| |||
0 commit comments