Hyprland 崩溃报告与日志获取指南:Issue 上报规范及源码级实现解析
Hyprland 的 docs/ISSUE_GUIDELINES.md 规定了向官方仓库提交 Issue 前的完整流程:查重、阅读 FAQ 与配置文档、区分「行为异常」与「崩溃」两类 Bug,并给出日志、崩溃报告、coredump 三类诊断材料的标准获取命令。本文在完整继承该规范的基础上,结合 src/debug/ 下的实际实现(CrashReporter 与 Logger),逐条验证每个命令和路径背后的真实逻辑,读完后可独立完成一次高信息量的崩溃 Issue 上报,并理解诊断文件里各字段是怎么生成的。
上报前的三项检查
规范开篇要求所有提交者先完成三件事:
- 确认不是重复 Issue(check that your issue is not a duplicate);
- 阅读 FAQ 文档,很多问题已有现成答案;
- 阅读配置(Configuring)文档,确认问题是否源于配置写法。
这三步的目的是过滤掉可通过文档自查解决的问题,让维护者的精力集中在真正的缺陷上。
功能建议的正确姿势
规范欢迎功能建议(Suggestions),但有一条明确红线:不要建议那些可以用 shell 脚本或 Hyprland IPC socket 实现的功能。Hyprland 提供了进程间通信(IPC)机制,大量「自定义行为」本就应该在用户侧脚本中完成,而不是塞进合成器核心。因此提建议前应先确认该功能无法通过脚本 + socket 组合实现。
Bug 报告的必备要素
所有 Bug 报告必须包含三要素:
- 复现步骤(Steps to reproduce)
- 预期结果(Expected outcome)
- 实际结果(Noted outcome)
对于「不崩溃但行为不对」的 Bug,以上三点就是全部内容,可以直接提交。
对于导致 Hyprland 崩溃的 Bug,还必须额外附上:
| 材料 | 版本范围 |
|---|---|
| Hyprland 日志 | 所有版本 |
| 你的配置文件 | 所有版本 |
| Hyprland Crash Report | v0.22.0beta 及以上 |
| Coredump / Coredump 分析(含堆栈) | v0.21.0beta 及以下 |
此外有一条硬性规定:报告 Bug 时不要使用发行版打包的版本,必须克隆源码自行编译(Clone and compile from source)。这是为了确保崩溃现场与可分析的源码版本严格对应——源码级编译的二进制才携带完整符号信息,且能与仓库中的具体 commit 精确对齐。当前仓库 VERSION 文件记录的版本为 0.56.0,属于 v0.22.0beta 之后的体系,对应的崩溃材料是 Crash Report。
获取 Hyprland 日志
日志文件按会话(session)组织在 $XDG_RUNTIME_DIR/hypr/ 下,每个子目录对应一个 Hyprland 会话实例。规范给出了两种场景的取日志命令:
场景一:你已回到 TTY,崩溃的会话是最后一次启动的
cat $XDG_RUNTIME_DIR/hypr/$(ls -t $XDG_RUNTIME_DIR/hypr | head -n 1)/hyprland.log
ls -t 按修改时间倒序列出会话目录,head -n 1 取最新的一个,即崩溃会话的日志。
场景二:你仍在 Hyprland 会话内,想取上一个会话的日志
cat $XDG_RUNTIME_DIR/hypr/$(ls -t $XDG_RUNTIME_DIR/hypr | head -n 2 | tail -n 1)/hyprland.log
此时当前会话目录是最新的,所以取第二新的目录才是崩溃的那个会话。
可以输出到文件、保存、复制,随附到 Issue 即可。
源码印证:日志文件名与位置的规则由 Logger 初始化代码 确认——initIS() 接收会话实例目录 IS,并按构建类型选择文件名:
m_logger.setOutputFile(std::string{IS} + (ISDEBUG ? "/hyprlandd.log" : "/hyprland.log"));
即 release 构建写 hyprland.log,debug 构建写 hyprlandd.log。因此如果你用 debug 模式编译后复现崩溃(见下文),取日志时应把命令中的文件名换成 hyprlandd.log。另外该代码表明日志默认开启滚动(rolling),这与崩溃报告末尾自动附加「Log tail」的机制(下文详述)相呼应。
获取崩溃报告(Crash Report,v0.22.0beta 及以上)
崩溃报告(Crash Report)是 v0.22.0beta 引入的自动化诊断文件,比传统 coredump 更易获取。按规范:
- 若设置了
$XDG_CACHE_HOME,报告目录为$XDG_CACHE_HOME/hyprland; - 否则为
$HOME/.cache/hyprland; - 目录中会有一个名为
hyprlandCrashReport[XXXX].txt的文件,其中[XXXX]是发生崩溃的进程的 PID; - 将该文件作为附件上传到 Issue。
源码印证:这段路径规则与 CrashReporter::createAndSaveCrash 的实现完全一致——先取 XDG_CACHE_HOME,非空则用 $XDG_CACHE_HOME/hyprland,否则回退 $HOME/.cache/hyprland,两者都不可用则直接报错退出;随后创建目录并以 hyprlandCrashReport + getpid() + .txt 拼出文件名。崩溃发生后,合成器还会向 stderr 打印提示,指明报告文件的完整路径,方便用户定位。
报告里有什么? 从 实现 可以看出,一份崩溃报告依次包含:
- 信号信息:收到的信号编号与名称(如 SIGSEGV);
- 版本指纹:Git commit hash、tag、commit 日期,以及
ISDEBUG等编译标志(debug 构建会明确标注debug),便于维护者确认与你崩溃的是哪一份代码; - 插件清单:若崩溃时加载了插件,报告会列出每个插件的名称、作者、版本,并提示「此崩溃可能不是 Hyprland 的锅」——这是排查插件引发崩溃的关键线索;
- 系统信息:
uname输出的内核名/版本、lspci提取的显卡信息、/etc/os-release内容、以及构建时链接的系统库清单; - 反解后的调用栈(Backtrace):先抓取原生栈帧,再调用
addr2line(clang 构建用llvm-addr2line)把每个地址解析为函数名与源文件行号,即报告中#0 | ...逐帧展示的部分; - Log tail:报告最后自动附上滚动日志的尾部内容,崩溃前最后的日志上下文无需另行提取。
值得一提的是,该实现运行在信号处理上下文中,前半段刻意只使用栈内存与 async-signal-safe 的写操作,并且在拼接调用栈前先 flush() 一次——注释中说明这是为了防止恰好死锁在 malloc() 中时报告丢失。对使用者而言,这解释了为什么报告有时只有前段而没有完整 Backtrace:那属于极端情况下的降级产物,但仍值得提交。
获取 Coredump(v0.21.0beta 及以下)
对于 v0.21.0beta 及更早的版本,需要用 coredump 代替崩溃报告。在 systemd 环境下:
coredumpctl
进入交互式列表后按 END 键跳到末尾,找到最近一次 Hyprland 条目,记下其 PID——即时间戳之后的第一个数字(例如 2891)。然后按 Ctrl+C 退出,执行:
coredumpctl info 2891
将输出(含堆栈)附到 Issue 中。
获取 Debug Coredump(推荐,信息量最大)
规范指出,debug 构建产生的 coredump 包含更多调试信息,能显著加速修复。完整流程如下:
- 同步到最新 git:确保处于最新代码,运行
同步主仓库与所有子模块(仓库通过git pull --recurse-submodulessubprojects/管理依赖,子模块不全会导致版本错位、符号对不上)。 - 以 debug 模式编译 Hyprland(参见 wiki 的 Contributing-and-Debugging 中 Build in debug mode 一节)。
注意:debug 构建使用的配置文件是
hyprlandd.lua,而非常规的hyprland.lua。这与源码中 debug 构建日志文件为hyprlandd.log的命名约定一致(见 Logger 实现)。 - 回到主目录
cd ~。 - 为便于收集,从 TTY 启动时附加环境变量,指定 ASan 日志路径:
ASAN_OPTIONS="log_path=asan.log" ~/path/to/Hyprland - 复现崩溃。Hyprland 会立即关闭(ASan 检测到内存错误即终止)。
- 回到
~查找asan.log.XXXXX文件,XXXXX是崩溃实例的 PID 数字后缀。 - 该文件就是你要的 coredump 材料,附到 Issue 即可。
上报清单速查
| 步骤 | 适用场景 | 关键命令 / 路径 |
|---|---|---|
| 查重 + 读 FAQ / Configuring | 一切 Issue | 提交前完成 |
| 三要素(复现/预期/实际) | 所有 Bug | — |
| 日志 | 所有崩溃 | cat $XDG_RUNTIME_DIR/hypr/<会话目录>/hyprland.log |
| 配置文件 | 所有崩溃 | 附完整配置 |
| Crash Report | v0.22.0beta+ | $XDG_CACHE_HOME/hyprland/hyprlandCrashReport<PID>.txt |
| Coredump | ≤ v0.21.0beta | coredumpctl / coredumpctl info <PID> |
| Debug ASan coredump | 崩溃类(推荐) | ASAN_OPTIONS="log_path=asan.log" 启动后找 ~ 下的 asan.log.<PID> |
规范与源码共同传达的原则是:给维护者一份「自包含」的证据包——版本指纹、环境信息、调用栈、日志尾部、配置与插件清单齐备时,很多崩溃可以无需往返澄清即可定位。这也解释了为何强调必须源码编译:只有源码构建的报告才能与仓库中的 commit 精确对应,addr2line 反解出的行号才真正可查证。
atomcodeClaude Code 的开源替代方案。连接任意大模型,编辑代码,运行命令,自动验证 — 全自动执行。用 Rust 构建,极致性能。 | An open-source alternative to Claude Code. Connect any LLM, edit code, run commands, and verify changes — autonomously. Built in Rust for speed. Get StartedRust0624
Hy4-previewHy4 preview 是由腾讯混元团队研发的新一代混合专家(MoE)旗舰模型。模型总参数量 770B,每个 token 激活 49B,主干共包含78层,第一层采用标准 FFN,其余 77 层均为 MoE 结构,每层包含 256 个路由专家与 1 个共享专家,每个 token 激活 top-8 路由专家及共享专家。主干之外原生内置 1 层 MTP(总参数量 10B,激活 0.7B)以支持投机解码。Python00
GLM-5.3GLM-5.3 与 GLM-5.2 使用相同的基座模型——所有提升均来自后训练。与 GLM-5.2 相比,它在复杂编程和长程任务上的表现显著提升。Jinja00
GLM-5.3-FlashGLM-5.3-Flash (320B-A18B),是GLM-5系列的首个原生多模态模型。320B总参数,能力超过GLM-5.2Jinja00
Spark-X2.5-4BSpark-X2.5-4B 旨在让强大的 AI 更实用、更高效、更易获得。在广泛日常任务中表现强劲,涵盖对话、写作、翻译、推理、编码、工具调用以及智能体工作流,并在同等规模的开源模型中取得领先成绩。Spark-X2.5 将面向效率的架构与最高 1M tokens 的原生上下文窗口相结合,并支持 200 多种语言。Python00
Spark-X2.5-1.7BSpark-X2.5-1.7B 旨在让强大的 AI 更加实用、高效且易于获取。这些模型在广泛的日常任务中表现出色,涵盖对话、写作、翻译、推理、编程、工具调用和智能体工作流,并在同等规模的开源模型中取得领先结果。Spark-X2.5 将面向效率的架构与最高 1M tokens 的原生上下文窗口相结合,并支持 200 多种语言。Python00