文章摘要
作者修复了Enlightenment E16窗口管理器中一个存在20年的罕见bug,该bug源于2006年代码中对牛顿算法的错误实现。尽管这个窗口管理器发布于1997年,作者仍日常使用并解决了这个关键问题。
文章总结
修复Enlightenment E16中一个存在20年的错误
作者:Kamila Szewczyk
发布日期:2026年4月15日
简介
Kamila Szewczyk是一位日常使用1997年发布的窗口管理器Enlightenment E16的用户。尽管该软件已有多年历史,但她对其轻量级(峰值内存占用仅24MB)、可定制性和键盘友好性赞不绝口。然而,这个古老的代码库也积累了不少技术债务,其中一个罕见的错误甚至可以追溯到2006年。
问题描述
在一次紧急处理课程幻灯片时,Kamila打开一个特定的PDF文件后,整个桌面突然冻结。通过TTY终止X11会话后,她发现这个问题具有确定性——每次打开该PDF都会重现。
使用gdb调试发现,程序卡在imlib2的字体缓存中,具体是在处理窗口标题的截断逻辑时陷入无限循环。该循环原本用于在标题过长时,通过牛顿迭代法计算合适的截断位置(例如显示为"Kickoff.pdf...Introduction"),但由于缺乏迭代限制和容错机制,导致算法在特定条件下振荡不收敛。
问题根源
代码中的牛顿迭代法存在三个关键缺陷:
1. 无迭代上限:算法可能无限振荡或发散。
2. 负值处理缺失:截断字符数可能变为负数,生成无效字符串。
3. 零宽度字符:当字符宽度计算为零时,导致除零错误。
修复方案
Kamila提交的补丁包含以下改进:
1. 限制迭代次数:超过32次迭代后,若当前尝试可行则接受,否则逐步调整截断数。
2. 截断数下限:强制截断数至少为1,避免无效字符串。
3. 字符宽度保护:确保字符宽度不小于1像素,防止计算错误。
重现条件
当窗口标题满足以下条件时触发:
- 长度超过81个宽字符(如包含长破折号的标题)。
- 标题栏宽度约291像素,且平均字符宽度为3像素左右。
哲学思考
Kamila借此反思软件维护的现状:
- 新≠好:新软件可能引入更多未知错误,而老代码在稳定维护下反而更可靠。
- 供应链风险:她以近期Linux内核的fgetxattr漏洞和XZ后门事件为例,强调即使稳定版本也可能因维护者失误或恶意攻击出现严重问题。
- 自主可控:对于关键工具,她倾向于使用自己能维护的旧版软件,避免依赖不可控的供应链。
补丁代码
(详见原文Diff,主要修改了text.c中的迭代逻辑和安全检查。)
注:本文经编辑删减,保留核心技术和背景信息,省略部分个人化叙述和重复内容。
评论总结
以下是评论内容的总结,平衡呈现不同观点并保留关键引用:
启蒙作用与怀旧情怀
- 多位用户回忆E16如何激发他们对Linux的兴趣(评论1、2、7)
- 关键引用:"E16 was the hook that caught me"(评论1);"Makes me want to reinstall E16"(评论2)
关于轻量化的争议
- 有用户指出E16在当时并不被视为轻量(评论3、4)
- 关键引用:"Certainly wasn't considered lightweight back then"(评论3);"harangue him for being glib on resource usage"(评论4)
技术贡献与持续使用
- 年轻开发者修复古老bug获得赞赏(评论5)
- 部分用户仍在使用Enlightenment及其组件(评论6、8)
- 关键引用:"Very happy to see a 20-something year old find and fix bugs"(评论5);"What a gorgeous and functional Terminal emulator"(评论8)
市场影响与用户流失
- 有观点认为Enlightenment未能产生重大影响(评论6、9)
- 用户转向其他桌面环境的原因(评论7、10)
- 关键引用:"nothing big came out of Enlightenment"(评论6);"Gnome turned hostile on power users"(评论10)
设计时代的终结
- 部分用户认为早期Linux桌面定制化时代已结束(评论10)
- 关键引用:"end of an era of design and theming experiments"(评论10)
总结呈现了怀旧情绪、技术评价和市场影响三个维度的主要观点,保持正反意见平衡,引用均来自原始评论的关键语句。