🔧 修复 Enlightenment E16 窗口管理器20年历史的Bug
来源: iczelia.net —HN 216 points
标签: Bug修复窗口管理器Newton算法C语言
📖 内容概述
一位出生于2004年的年轻开发者日常使用1997年的窗口管理器Enlightenment E16,在处理一个特定PDF时发现了桌面冻结的严重Bug。通过调试,她追踪到问题根源是E16文本渲染中一个存在了近20年的Newton算法实现缺陷。
🔍 问题根源分析
E16在渲染过长的窗口标题时使用"中间省略"算法——将长文本截断并在中间显示"..."。该算法使用Newton-style搜索来估计需要删除多少字符以适应宽度限制。
核心问题:Newton方法缺少迭代限制,导致在某些特定文本长度和宽度组合下陷入无限振荡。
代码中的缺陷
for (;;) // 无迭代限制!
{
// ... 计算nuke_count...
if (nc2 >= 0 && nc2 < 3 * cw)
break; // 退出条件
// Newton步进调整
if (nc2 > 0)
nuke_count -= ...;
else
nuke_count += ...;
}
🛠️ 修复方案
作者采用了三个防御性修改:
- 迭代次数上限: 添加32次迭代限制,超出后接受第一个可用的拟合结果
- nuke_count下限: 确保nuke_count至少为1,防止负数导致的头尾重叠
- cw下限: 将cw下限设为1,防止除零错误
💡 关键洞见
- Newton方法可能在特定初始条件下振荡和发散
- 退出容差太紧([0, 3*cw))导致短标题更容易收敛
- 老软件不一定比新软件差——新软件有新的Bug
- 2006年的Bug现在才被发现,因为需要特定的文本长度/字体组合才能触发
🔗 触发条件
任何WM_NAME足够长,导致中间省略搜索进入"overshoot regime"的窗口都会触发此Bug。实际案例:
"Kickoff.pdf — Introduction to Information Theory Session 1: kickoff & first topic"
(81个宽字符,~291px边框标题位)