找回密码
立即注册
搜索
热搜: Java Python Linux Go
发回帖 发新帖

2545

积分

0

好友

369

主题
发表于 17 小时前 | 查看: 2| 回复: 0

那行导致事故的代码,是我点的 Approve
另外三位资深工程师也点了。
静态分析器点了。
Fuzzer 点了。
所有我们信任、专门用来抓这种 Bug 的工具,全都点了。

结果还是炸了。

一个 lambda 捕获了一个引用。
这个引用活得比它的作用域还久。
在某个层层嵌套的回调链里,我们开始读取一块已经不属于我们的内存
监控系统在 19 分钟 之后才发现异常。

在交易系统里,19 分钟非常、非常长。

找到根因之后,我在停车场坐了半个小时。
不是因为愤怒。
而是因为我真的不知道——我们还能做什么更多的事

所有最佳实践都做了。
现代 C++ 特性全用上了。
我们也很小心。

但这并不重要。

六个月后,我们用 Rust 重写了系统。
然后性能测试的结果,直接把我的世界观打碎了。


没人告诉你的生产事故真相

最糟糕的不是 Bug。
事后的安静

事故发生后,Slack 突然安静下来。
没人想留下任何一句可能会被写进复盘文档的话。

我看着在线状态一个个消失——
大家突然都“有事要忙”。

我留下了。

花了九个小时,顺着回调链一层层追指针,
在我们为了“让 C++ 看起来更安全”而构建的抽象里,
追踪所有权是如何悄悄溜走的。

Bug 藏在一个异步 handler 里。
外层作用域已经结束。
内层 lambda 还握着一个早就不存在的引用。

六行代码。
我们所有工具,全都看不见。

那一刻我才意识到一件很不舒服的事:

我们不是在 C++ 上失败。 我们是在 C++ 上成功了。

当一门语言允许你持有一个“幽灵引用”,
这就是成功的样子。


我们一直在骗自己的那个谎言

我们真的什么都做对了。

  • 智能指针到处都是
  • RAII 干净得可以裱起来
  • 每次提交都跑静态分析
  • Code review 动不动就三天,只因为“内存安全不能妥协”

我们曾经是那种会嘲笑“内存 Bug 公司”的团队。
我甚至在 2023 年做过一次分享,主题是:

安全是纪律问题,不是语言问题。

台下掌声还不错。
那时候我对自己感觉很好。

那些 PPT 我现在还留着。
偶尔打开看看,提醒自己什么叫自信的无知

真相是这样的:

我们一直在防御一个永远不睡觉的敌人
每一个 C++ 函数,都是一次与未定义行为的无声谈判。

你可以赢一千次。
你只需要输一次。

我们输了那一次。

代价是 230 万美元
以及三位工程师决定“到此为止”。


所谓的“安全税”,到底是谁在交

大家一直说 Rust 慢。
说你要为安全付出性能代价。
说 borrow checker 不免费。

这是我们重写撮合引擎后的真实数据:

p99 延迟(微秒)

C++(之前) ████████████████████████  47.2 μs
Rust(之后) ███████████████████       38.1 μs

                ↓
            快了 19.3%

我花了两周时间试图找 benchmark 的问题。

没有问题。

Rust 更快,是因为我们不再恐惧地写代码

  • 不再给永远不会是 null 的指针写防御判断
  • 不再因为所有权不清晰而做多余拷贝
  • 不再在运行时验证编译器早就能证明的事实
// 旧 C++(真实生产代码)
void process(Order* o) {
    if (!o) return;       // 理论上永远不为空,但谁敢信
    auto copy = *o;       // 所有权不清晰,先拷贝一份
    if (copy.qty <= 0) return;
    // 真正逻辑从这里才开始
}
// Rust 版本
fn process(o: &Order) {
    // 编译器保证引用有效
    // 从第一行就开始干正事
}

安全税确实存在。
只是我们之前,一直把钱交给了错误的语言


那些离开的工程师

宣布重写的那周,Marcus 给整个工程团队发了一封邮件。
标题是:

C++ IS NOT THE PROBLEM

十四段文字。
十五年的经验。
一封为自己整个职业生涯辩护的长信。

他在周四辞职了。

我不怪他。

当编译器开始比你更擅长你的工作时,
人心里真的会断点什么。

你花十年培养的直觉,
突然变成可以忽略的警告。

那封邮件我留着。
偶尔会重读一遍,提醒自己:

“正确”和“善良”,不是一回事。


那个让我失眠的部分

上个月,一个初级工程师加入了团队。
23 岁。
8 个月 Rust 经验。

她第二周就提交了生产代码。
默认就是内存安全的代码。

放在 C++ 时代,
我至少会拉三个资深工程师盯着。

她不知道什么是悬空指针。
从没花九个小时追 use-after-free。
看到裸指针也不会条件反射地紧张。

因为她从没被它们伤过。

我有点嫉妒她。
也真心庆幸:
她不必像我一样学这些东西。


老实说一句

你该不该把 C++ 项目重写成 Rust?

我不会说“可能不用”。
我也不打算再保持理性。

我现在真正相信的是:

你留在 C++ 的每一天,
都在选择继续支付安全税。

静态分析器、代码评审、防御式编程、心理负担。
你用工程师的时间、注意力和精力在交这笔税。

在经历了这一切后,我开始在 云栈社区RustC/C++ 板块更活跃地参与讨论。看到更多关于系统语言演进和安全性的思考,让我确信当初的选择并非孤例。




上一篇:如何在树莓派上用baresip和GPIO实现SIP可视告警器?
下一篇:从235B/671B到8B:我如何通过DPO微调解决垂直Agent的稳定性难题
您需要登录后才可以回帖 登录 | 立即注册

手机版|小黑屋|网站地图|云栈社区 ( 苏ICP备2022046150号-2 )

GMT+8, 2026-1-14 18:38 , Processed in 0.208983 second(s), 40 queries , Gzip On.

Powered by Discuz! X3.5

© 2025-2025 云栈社区.

快速回复 返回顶部 返回列表