[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"$ft19vq8PBYr9ZR73RR7wV58YmTvKT9KEL9zNv6yhnxyg":3},{"item":4,"related":48},{"id":5,"type":6,"title":7,"slug":8,"summary":9,"body":10,"coverUrl":11,"productScreenshots":12,"productLinks":13,"authorName":14,"authorUrl":15,"authorSubject":16,"category":17,"tags":22,"sourceLabel":39,"sourceName":40,"sourceUrl":41,"status":42,"seoTitle":7,"seoDescription":9,"canonicalUrl":39,"isFeatured":43,"sno":44,"sortOrder":45,"publishedAt":46,"updatedAt":47,"createdAt":47},"6404d41a-6276-4ad4-9d36-d974ef59cd37","article","Symbolic Execution：把输入变成未知数，程序能自己找出崩溃条件吗？","symbolic-execution-program-paths-explained","Symbolic Execution 不只用几个样例运行程序，而是把输入当成未知变量，记录每条路径的条件，并尝试构造能触发越界或崩溃的具体输入。本文解释路径爆炸、模型边界，以及它如何辅助 AI 生成代码的安全检查。","测试一个程序时，最常见的做法是准备若干具体输入：空字符串、很长的字符串、正常账号和异常账号。Symbolic Execution 则把输入当成未知变量，让程序沿着不同分支运行，并把每条路径上的条件记录成约束。这样，工具不仅能告诉你“这里可能出错”，还可能给出一组触发错误的输入条件。\n\n## 具体输入和符号输入\n\n考虑一个简单函数：当 `x > 10` 时访问数组的第一个位置，否则访问第二个位置。用具体输入运行，只能走其中一条路。用符号变量 `x` 运行，执行器会分成两条路径，并分别记录 `x > 10` 与 `x \u003C= 10`。\n\n如果后续代码又要求 `x` 必须小于 0，某条路径的条件就可能变成矛盾；如果访问下标要求 `x` 在数组范围之外，约束求解器便可能构造出一个能触发越界的具体数字。\n\n## 它为什么不会无限分支\n\n符号执行最大的困难是路径爆炸。一个程序里有很多 `if`、循环和递归，路径数量可能呈指数增长。实际工具会采用边界限制、路径合并、状态缓存、随机搜索和优先级策略，把资源集中在更可能发现问题的路径上。\n\n符号值本身也有边界。字符串、系统调用、浮点数和外部服务很难完全用简单数学表达。工具往往需要模型化这些环境，或者在符号分析和具体执行之间切换。\n\n## 在安全和 AI 编程里的位置\n\n符号执行常用于发现崩溃、越界、整数溢出和某些安全漏洞。对 AI 生成代码，它可以成为测试之外的一层检查：不是只问“这几个样例通过了吗”，而是询问“在什么条件下，这段代码会走到危险路径”。\n\n但它不是万能证明器。工具覆盖的路径受到时间、内存、模型精度和程序结构限制。一个没有被发现的 bug，不代表所有输入都安全；一个被发现的路径，也还需要工程师判断是否能在真实环境中复现。\n\n## 读者应该记住\n\nSymbolic Execution 的直觉很简单：把“输入一个数字”变成“输入满足某些条件的任意数字”，让程序自己暴露路径约束。它把测试从样例驱动，推进到条件驱动。\n\n资料：[KLEE 官方文档](https:\u002F\u002Fklee-se.org\u002Fdocs\u002F)；[KLEE 项目](https:\u002F\u002Fgithub.com\u002Fklee\u002Fklee)","\u002Fuploads\u002F2026-09-20\u002Ffe785363-a081-411b-bd2e-e191c0f0d86e.jpg",[],[],"Foundit","https:\u002F\u002Ffoundit.cn","foundit-ai-editorial",{"id":18,"name":19,"slug":20,"description":21},"6179d3b6-dc34-4483-9ded-3cd9f1b37a47","科普","abbreviation","介绍各领域新兴概念",[23,27,31,35],{"id":24,"name":25,"slug":26},"144abe77-0dc6-4f66-a176-20bddb1c0bfa","编程","coding",{"id":28,"name":29,"slug":30},"07b0ad92-5bba-481c-a567-6ae6d32c2122","Bug","bug",{"id":32,"name":33,"slug":34},"4c2bbea6-eab7-40a8-8447-1de478ff7749","分析","analyse",{"id":36,"name":37,"slug":38},"7c76bfc2-f80f-4ee0-a95d-27bd8708b434","技术","slug",null,"KLEE 官方文档","https:\u002F\u002Fklee-se.org\u002Fdocs\u002F","published",false,44,0,"2026-09-20T00:00:00.000Z","2026-09-20T03:57:45.100Z",[49,58,67],{"id":50,"type":6,"title":51,"slug":52,"summary":53,"coverUrl":54,"authorName":14,"sno":55,"publishedAt":56,"createdAt":57},"62724dbd-ce49-4be9-afa9-4ba127513a62","语音搜索一定先变成文字吗？AI 开始绕过转写这一步","speech-to-retrieval-without-transcription","传统语音搜索先把声音转成文字，再拿文字查资料，一次听错就可能让搜索方向完全跑偏。Speech-to-Retrieval 尝试直接把语音与相关文档映射到同一个语义空间。本文用蒙克名画的例子讲清新旧架构及其边界。","\u002Fuploads\u002F2026-09-08\u002Fe1173842-1ec4-48f3-8349-240fc2d78197.jpg",50,"2026-08-30T00:00:00.000Z","2026-08-14T03:06:11.525Z",{"id":59,"type":6,"title":60,"slug":61,"summary":62,"coverUrl":63,"authorName":14,"sno":64,"publishedAt":65,"createdAt":66},"0999bb14-a97c-4003-84e7-61ad2da998e0","文件删除以后去了哪里？为什么有时还能恢复？","where-deleted-files-go-data-recovery","普通删除往往只是移除文件系统里的索引并把空间标记为可重用，数据本身未必立即消失；SSD 的 TRIM、磨损均衡与加密又让情况更加复杂。本文区分回收站、删除、覆盖和安全清除，说明何时应停止写入设备。","\u002Fuploads\u002F2026-09-08\u002Fb7222764-de75-4863-8679-0a94a8965af3.jpg",51,"2026-08-20T00:00:00.000Z","2026-08-14T03:06:15.710Z",{"id":68,"type":6,"title":69,"slug":70,"summary":71,"coverUrl":72,"authorName":14,"sno":73,"publishedAt":74,"createdAt":75},"55f42805-a25a-4ce3-89d9-121b9a268a8f","0.1＋0.2 为什么不等于 0.3？计算机真的算错了吗？","why-point-one-plus-point-two-not-point-three","许多十进制小数无法用有限位二进制精确表示，计算机只能保存最接近的值。微小误差在显示时常被隐藏，却会在比较、累计和金额计算中冒出来。本文用三分之一的类比讲清浮点数，并给出可靠的处理原则。","\u002Fuploads\u002F2026-09-08\u002Ffd3a7daf-2a2c-4ef0-8f57-38f1d9de962c.jpg",54,"2026-09-06T00:00:00.000Z","2026-08-14T03:06:15.129Z"]