Hyprland 切换布局时闪退问题修复
在 hyprland-git 0.54.0 中,调用 hyprctl getoption general:layout 会触发 IPC 路径中的 std::format/JSON 处理 bug,导致 Hyprland 出现 SIGABRT 崩溃。该问题属于上游缺陷。临时通过状态文件替代查询逻辑,成功规避崩溃并实现布局切换
Hyprland 问题记录
2026-03-21 | hyprctl getoption 触发 SIGABRT 崩溃
现象
更新 hyprland-git 到最新版本(hyprland-git 0.54.0.r108.8726a7363-1)后,按 SUPER+S 切换布局(dwindle -> scrolling)时 Hyprland 稳定崩溃,随后 watchdog 触发安全模式启动,再次崩溃。
如何发现问题
第一步:确认崩溃记录
coredumpctl list发现今天(2026-03-21)有多条 Hyprland SIGABRT 记录:
Sat 2026-03-21 10:31:49 CST 1058 SIGABRT /usr/bin/Hyprland 24.8M
Sat 2026-03-21 10:31:50 CST 1499 SIGSEGV /usr/lib/xdg-desktop-portal-hyprland
Sat 2026-03-21 10:31:50 CST 15459 SIGABRT /usr/bin/Hyprland 1.0M
Sat 2026-03-21 10:32:32 CST 15696 SIGABRT /usr/bin/Hyprland 22.0M
...体积小(1M)的是安全模式崩溃,体积大(24M)的是主进程崩溃,从最大的 PID 开始分析。
第二步:查看崩溃堆栈
coredumpctl info 1058关键堆栈(第一次崩溃):
#5 _Z17escapeJSONStringsRK... ← 崩溃点
#6 n/a (/usr/bin/Hyprland)
#7 CHyprCtl::getReply ← IPC 处理
#10 wl_event_loop_dispatch
#12 main初步判断:hyprctl getoption 的 JSON 输出路径有 bug。
第三步:修复后仍然崩溃,再次查堆栈
去掉 -j 改为纯文本解析后,SUPER+S 仍然崩溃。查新的崩溃(PID 18433):
coredumpctl info 18433关键堆栈:
#5 n/a (libc.so.6) ← __chk_fail / format 异常
#6 std::__format::_Sink::_M_write ← std::format 内部
#10 std::vformat ← 格式化崩溃
#11 n/a (/usr/bin/Hyprland)
#12 CHyprCtl::getReply ← 同一路径确认:不是 -j 参数的问题,而是 hyprctl getoption 本身触发了 CHyprCtl::getReply 中的 std::format bug。
问题分析
SUPER+S 的切换脚本使用 hyprctl getoption general:layout 查询当前布局,这个 IPC 请求在新版 hyprland-git 的 CHyprCtl::getReply 中触发了 std::format / escapeJSONStrings 的 bug,导致 SIGABRT。
崩溃链:
SUPER+S触发 shell 脚本- 脚本调用
hyprctl getoption general:layout - Hyprland IPC →
CHyprCtl::getReply - 内部
std::format格式化响应时越界/断言失败 abort()→ SIGABRT- Watchdog 检测到崩溃,以安全模式重启
- 安全模式下配置解析同样崩溃(config 路径问题)
这是 hyprland-git 上游 bug,与本地配置无关。
解决方案
绕开 hyprctl getoption,改用状态文件记录当前布局:
修复前(hyprland.conf):
bind = $mainMod, S, exec, \
current=$(hyprctl getoption general:layout -j | jq -r '.str'); \
if [ "$current" = "dwindle" ]; then \
hyprctl keyword general:layout scrolling && notify-send "切换到 scrolling 布局"; \
else \
hyprctl keyword general:layout dwindle && notify-send "切换到 dwindle 布局"; \
fi修复后(hyprland.conf):
bind = $mainMod, S, exec, \
state_file=/tmp/hypr_layout_state; \
current=$(cat "$state_file" 2>/dev/null || echo "dwindle"); \
if [ "$current" = "dwindle" ]; then \
hyprctl keyword general:layout scrolling && echo scrolling > "$state_file" && notify-send "切换到 scrolling 布局"; \
else \
hyprctl keyword general:layout dwindle && echo dwindle > "$state_file" && notify-send "切换到 dwindle 布局"; \
fi注意事项
- 状态文件
/tmp/hypr_layout_state在重启后丢失,默认回退到dwindle,与hyprland.conf中general:layout的默认值保持一致即可。 - 这应该是
hyprland-git上游 bug,等待上游修复后可恢复使用hyprctl getoption。 - 排查命令速查:
coredumpctl list # 查看崩溃历史 coredumpctl info <PID> # 查看指定崩溃的详细堆栈 journalctl -b 0 | grep -i hypr # 查看本次启动的 hyprland 日志 ls $XDG_RUNTIME_DIR/hypr/ # 查看 hyprland 运行时日志目录
💬 评论区
留下你的足迹,分享你的想法
这里还没有评论,来做第一个进来的人吧~ ~