9.30
嘹亮的琴音
中午在一餐吃饭时,久违地听到了钢琴奏响的声音,似乎因为空间宽阔的原因,显得高亢而嘹亮。弹奏了一首海阔天空以及若干我无法识别出名字的歌曲。
九月的尾巴
这是最后一篇带有 tag #2025/9 的日记。
失败的 Attack
启动 attack lab 时发现在输出 Type string 之前就触发了 Segmentation fault。通过阅读反汇编和 gdb breakpoint/backtrace 等多管齐下,发现触发 segmentation fault 的原因是 printf 中的 movaps %xmm1, 0x10(%rsp)
中没有满足对齐要求。
为了验证我的猜测(实际上直接用 gdb 改 rsp 就能进行一定程度上的验证),通过成功运行过 attack lab 的奶龙机器获取到了一些 gdb 的调试信息,发现 rsp 仍然没有对齐,不过没有崩溃的原因未知,于是尝试通过独立运行 movaps 指令来进行验证(确认猜测),不过更令人困惑的情况是,奶龙机器同样对这份代码产生了 Segmentation Fault。这无疑让我深入了深深地思考(错误地排除了正确原因),开始怀疑是链接 C 库的版本不同的原因(开始偏题),尝试更新 GLIBC,由于 apt 的机制,需要处理复杂的包依赖问题(linux-nvidia6.2-tools-common 和 linux-tools-common),出于保守性,令而配置了 docker 的环境(顺带学了学 docker 的用法),在 docker 的 Ubuntu22.04 中尝试了 WSL 中尝试过的一切,包括更新 GLIBC,仍然没有解决问题(从相同的 Ubuntu 版本和 WSL2 作为 docker 的后端中可见一斑)
section .text
global _start
_start:
call test_unaligned
mov rax, 60
mov rdi, 0
syscall
test_unaligned:
push rbp
mov rbp, rsp
and rsp, -16
sub rsp, 8
movaps xmm0, [rsp]
mov rsp, rbp
pop rbp
ret
在穷途末路之际,尝试让 DS 直接检索类似遭遇的网页,出现了一些有效的信息但是仍然无法解决问题,最后灵机一动切到英文版搜索结果第一个就跳出来 stack overflow post 问题完全匹配!
发现了同样的问题根源: movaps
的对齐,帖子提到通过 run-time interpositioning 来解决问题并一针见血地指出问题存在的原因是 System V AMD64 ABI 的提出时间晚于 Attack Lab 的最后更新时间。其他相关的帖子
所以奶龙机器是一台混沌的机器。
通过这次奇妙的 debug,或许可以总结出一些教训
- 分析问题(区别于一般问题/Question,应当是“本不应该出现的问题”/Bug)时需要记录分析历史,循序渐进地逐层分析是正确的,但是当分析深度过大时会爆栈导致思路混乱(比如忘了可以直接用 gdb 改而沉迷于分析 movaps);有时需要跳出细节的桎梏从全局审视,维持对整体的认知;明确分析的目的,是找到真正导致错误的原因,还是解决问题;明确当前分析的问题,到后期分析的问题竟然变为“两台不同的机器运行相同的代码出现不同结果的可能原因”,有点偏题。
- 认可绝对正确信息的效力。他们通常为实践得到的数据,建立在某一些条件下,通过一些合理的假设,抽离核心条件,控制变量等方法对其进行分析。这些数据应当被记录。绝大多数情况下这些数据都能提供一些断言性的信息,其效力显然与理论分析不在同一层次。(比如 gdb
disas /r $pc-20, $pc+20
提供的结果已经可以断言出现 Segmentation Fault 的地方就是movaps
,从而在假设 gdb、机器正常的情况下可以进一步断言一定是违反了movaps
的调用规范) - 信息具有不同的细粒度。AI 并不是万能的,许多细节的问题 AI 受制于参数量无法精确的了解。当问题所设计的细粒度过小时可以诉诸一些 non-generalized 的信息检索。
- workflow、tools 的更新和熟练度提升来自于探索性的实践,探索性意味着从提升效率、发掘功能的需求出发去尝试新的 workflow 和 tools(tools 可以是多个层面的)。
- 请直击核心。
- 根据可靠性、可读性以不同的优先级从不同的信息来源获取信息