如何用 ASAN 编译并运行 Hyprland 以捕获内存错误 asan.log?
2026/9/12 2:17:56 网站建设 项目流程

如何用 ASAN 编译并运行 Hyprland 以捕获内存错误 asan.log?

【免费下载链接】HyprlandHyprland is an independent, highly customizable, dynamic tiling Wayland compositor that doesn't sacrifice on its looks.项目地址: https://gitcode.com/GitHub_Trending/hy/Hyprland

如果你的 Hyprland 崩溃,普通日志往往不够定位内存错误(如越界写、use-after-free)。Hyprland 仓库自带一条完整的 ASan 构建路径:Makefile 中的asan目标会把 wayland 服务器库用 AddressSanitizer 本地编译并静态链入 Hyprland,再直接从 TTY 启动 Hyprland;崩溃时 ASan 报告被写入asan.log.<PID>文件,按 docs/ISSUE_GUIDELINES.md 的说法,这个文件就是你可以附上 issue 的崩溃报告。本文覆盖从构建到取出报告的完整操作。

ASan 构建在仓库中是如何生效的

先理解这条路径的构成,后面执行时才知道每一步在做什么:

  • CMakeLists.txt 中,只有当CMAKE_BUILD_TYPEDebugWITH_ASAN打开时,才会对hyprland_lib链接asan并加上-fsanitize=address。也就是说 ASan 构建必须基于 Debug 构建,asan目标的 cmake 命令正是Debug+-DWITH_ASAN:STRING=True
  • scripts/hyprlandStaticAsan.diff 在 ASan 分支上额外把本地构建的libwayland-server.alibffi链入hyprland_lib。这是asan目标先用 meson 以-Db_sanitize=address编译 wayland 的原因:让 wayland 服务器库本身也带 ASan 插桩,避免未插桩的共享库干扰检测。

所以make asan不是简单的“换个 flag 重编译”,而是一条包含第三方库本地构建的流水线。

执行前的准备

asan目标会实际执行以下动作,执行前先确认你知道这些影响:

  1. 只在 TTY 中运行。目标开头就打印!!WARNING!! Only run this in the TTY.,并且通过pidof Hyprland检查,如果当前已有 Hyprland 实例在运行,目标直接exit 1拒绝执行。所以先在桌面外(tty1 之类)操作,并确认没有 Hyprland 进程。
  2. 它会删除仓库根目录下已有的./wayland目录(rm -rf ./wayland),然后从网络git clone --recursivewayland 源码并本地编译。
  3. 它会用patch -p1应用 scripts/hyprlandStaticAsan.diff,即修改你本地工作区的CMakeLists.txt(加入链接本地 wayland 静态库与libffi的两行)。如果之后要恢复干净的工作区,自行处理这个改动。
  4. 目标中途有一个交互提示:If you want to apply a patch, input its path (leave empty for none):,输入要应用的补丁文件路径,直接回车表示不打补丁。
  5. 命令链中实际用到的工具是gitpatchmesonninjacmake,这些需要可用;运行步骤还会用到你的 Hyprland 配置文件,目标默认指定~/.config/hypr/hyprland.lua

运行 make asan

在仓库根目录执行:

make asan

该目标的完整流程(摘自 Makefile)依次是:

rm -rf ./wayland # 交互提示:输入补丁路径或留空 git clone --recursive https://gitlab.freedesktop.org/wayland/wayland cd wayland && patch -p1 < ../scripts/waylandStatic.diff && meson setup build --buildtype=debug -Db_sanitize=address -Ddocumentation=false && ninja -C build && cd .. cp ./wayland/build/src/libwayland-server.a . patch -p1 < ./scripts/hyprlandStaticAsan.diff cmake --no-warn-unused-cli -DCMAKE_BUILD_TYPE:STRING=Debug -DWITH_ASAN:STRING=True -DUSE_TRACY:STRING=False -DUSE_TRACY_GPU:STRING=False -S . -B ./build cmake --build ./build --config Debug --target all

wayland 库编译完成后打印Wayland done,Hyprland 编译完成后打印Hyprland done。目标最后一步会立即启动 Hyprland 本身:

ASAN_OPTIONS="detect_odr_violation=0,log_path=asan.log" HYPRLAND_NO_CRASHREPORTER=1 ./build/Hyprland -c ~/.config/hypr/hyprland.lua

各部分的用途:

  • log_path=asan.log:让 ASan 把报告写到asan.log.<PID>而不是 stdout;
  • detect_odr_violation=0:关闭 ODR 违规检测;
  • HYPRLAND_NO_CRASHREPORTER=1:该环境变量置位后 Hyprland 不启用自己的 crash reporter(参见 src/Compositor.cpp),避免和 ASan 报告互相干扰;
  • -c ~/.config/hypr/hyprland.lua:明确指定配置文件。注意 docs/ISSUE_GUIDELINES.md 提到 debug 构建默认使用的配置是hyprlandd.lua,而这里用-c显式指定了hyprland.lua,如果你想用自己的配置,改这个参数即可。

启动后 Hyprland 会接管当前 TTY,目标命令不会返回,直到这个 Hyprland 会话结束。

复现崩溃并取出 asan.log

按 docs/ISSUE_GUIDELINES.md 的“Obtaining the debug Hyprland coredump”一节:

  1. 复现导致崩溃的操作。Hyprland 应当立即关闭。
  2. 到启动 Hyprland 时所在的目录找名为asan.log.XXXXX的文件,XXXXX是崩溃那个 Hyprland 实例的 PID。make asan从仓库根目录启动,报告就落在仓库根目录;指南里推荐的手动方式是先cd ~再启动,报告就落在~
  3. 这个asan.log.<PID>文件就是你要的 ASan 报告(指南称之为 debug coredump),可以直接附上 issue。

如果不想走make asan的整条流水线,指南也给了手动启动形式:在 TTY 中用ASAN_OPTIONS="log_path=asan.log" ~/path/to/Hyprland启动——注意这只对已按 ASan 构建的 Hyprland 二进制有意义,否则ASAN_OPTIONS不会生效。构建步骤本身仍按上面的 cmake 参数完成:Debug构建类型加-DWITH_ASAN:STRING=True

限制与边界

  • 只能在 TTY 中做这件事;已有 Hyprland 实例在跑时make asan会拒绝执行。
  • ASan 只作用于 Debug 构建(CMakeLists.txt),Release 构建加WITH_ASAN不生效。
  • asan目标会修改本地工作区(应用hyprlandStaticAsan.diffCMakeLists.txt)并在根目录克隆wayland,完成后如需干净的构建状态,自行还原这些改动。
  • 该路径产出的报告用于复现崩溃与 issue 提交;报告里记什么、怎么解读,以 ASan 输出内容本身为准,仓库文档未做进一步说明。

【免费下载链接】HyprlandHyprland is an independent, highly customizable, dynamic tiling Wayland compositor that doesn't sacrifice on its looks.项目地址: https://gitcode.com/GitHub_Trending/hy/Hyprland

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询