## Bug诊断报告
**错误类型**:运行时(白屏 500)
**错误信息**:Uncaught TypeError: Cannot access offset of type bool
**发生位置**:e/class/functions.php / GetFcache / 第 204 行
## 根因分析
**问题描述**:反序列化缓存后未做类型校验,直接当下标访问。
**详细分析**:`unserialize` 失败返回 `false`(bool);旧缓存格式非数组时,直接 `$cache['key']` 在 PHP 8.1+ 触发 TypeError。
**相关代码**:
```php
$cache = unserialize($str);
return $cache['key']; // unserialize 失败返 false(bool) 时当下标访问报 TypeError
```
## 修复方案
```php
$cache = unserialize($str);
if (!is_array($cache)) return '';
return $cache['key'] ?? '';
```
## 验证方法
1. `php -l` 语法通过
2. 用旧格式缓存触发该路径,确认不再白屏
## 预防措施
- 反序列化结果先做 is_array 校验再访问下标
诊断前先检查相关spec中的scenario:
无spec:诊断后建议补充spec防止同类bug
✓ Spec场景检查:
- 相关Scenario: [scenario名称]
- 预期行为: [spec定义]
- 实际行为: [观察到的行为]
- 偏差分析: [spec vs 实现]
检查项目记忆中的已知问题:
| 错误类型 | 常见根因 | 分析方法 |
|---|---|---|
| 语法错误 | 拼写错误、括号不匹配、缩进错误 | 定位到具体行号和字符 |
| 运行时错误 | 空指针、数组越界、类型错误 | 检查变量状态和数据流 |
| 逻辑错误 | 条件判断错误、算法缺陷 | 追踪执行路径和中间结果 |
| 环境错误 | 依赖缺失、版本不兼容、配置错误 | 检查环境和依赖信息 |
| 并发错误 | 竞态条件、死锁、资源竞争 | 分析线程/协程交互 |
根因分析中,AI 推断只能作为候选假设,不能直接作为结论交付。每个候选根因至少匹配一种验证证据:
| 证据类型 | 适用场景 | 验证方式 |
|---|---|---|
| 日志/堆栈 | 报错、异常、线上问题 | 对齐错误时间、调用链、文件行号和错误码 |
| 复现测试 | 稳定可触发的功能缺陷 | 构造最小输入,先复现失败,再验证修复后通过 |
| 源码路径 | 逻辑错误、数据流异常 | 从入口追踪到出错分支,说明变量状态变化 |
| 环境/版本 | 依赖、运行时、配置差异 | 对比语言版本、依赖版本、配置项和平台差异 |
| 外部权威源 | 框架/API/数据库行为不确定 | 引用官方文档、发行说明或已验证的项目内规范 |
| 运行证据 | 性能、并发、资源泄漏 | 使用 benchmark、profile、EXPLAIN、线程/堆/GC 日志验证 |
如果证据不足,必须输出"最可能原因"和"待验证动作",不得写成已确认根因。若多个候选根因都符合症状,按可能性排序并给出最小排除步骤。
给出修复方案前,必须先回答:这是根因(root cause)还是只打补丁(symptom patch)? 禁止未区分就直接改码。
if (x) return),而未说明为什么会进入该状态,即为补丁,必须继续追问上游成因。命中"只打补丁"时,在报告中单独标注「补丁风险」,并给出上游根因的最小排查动作。
基于已确定的根因和修复方案,明确定义"修复成功"的标准:
示例:
成功标准:用户邮箱为空字符串时,validate_user() 抛出 ValueError 而非崩溃。
复现测试:调用 validate_user({'email': ''}) → 应抛出 ValueError。
验证方法:运行复现测试 → 通过。
修复完成后,将关键决策和变更记录到项目记忆(参见 project-memory-management.md):
帮我诊断这个 CMS 后台 500。
环境:EmpireCMS 7.5,PHP 8.2,MySQL 5.7。
现象:进入 /e/admin 后白屏,前台正常。
错误信息:贴出 php_errors.log 中最新 30 行。
最近变更:刚改过后台插件 action_xxx.php。
要求:先判断可能原因,不要直接改缓存文件;给出最小复现和修复验证命令。
优先加载:bug-diagnosis.md、cms-development.md、code-review.md。
帮我定位订单列表接口偶发超时。
环境:Laravel 10,PHP 8.2,MySQL 8.0。
现象:keyword 为空时正常,带手机号搜索偶尔超过 5 秒。
已有证据:贴出慢查询 SQL、接口参数、表行数、EXPLAIN 结果。
要求:区分已确认根因和待验证假设;不要直接加索引,先说明索引影响和回滚方案。
优先加载:bug-diagnosis.md、mysql-database.md、performance-benchmark.md。
## Bug诊断报告
**错误类型**:[语法/运行时/逻辑/环境/并发]
**错误信息**:[核心错误消息]
**发生位置**:[文件/函数/行号]
## 根因分析
**问题描述**:[一句话说明]
**详细分析**:[逐步推理过程]
**相关代码**:
```[问题代码]```
## 修复方案
```[修复后的代码]```
**修复说明**:[为什么这样修复]
## 验证方法
1. [步骤1]
2. [步骤2]
## 预防措施
- [建议1]
- [建议2]
当诊断对象为 PHP+MySQL CMS 时,优先排查以下模式:
| Bug 类型 | 典型表现 | 常见根因 | 修复方向 |
|---|---|---|---|
| PHP 版本兼容 | Fatal error: Uncaught TypeError / Deprecated: |
低版本代码运行在高版本 PHP | 参见 cms-development.md PHP 8.x 兼容性检查表 |
| CMS 缓存失效 | 修改代码后页面无变化 | CMS 模板/数据缓存未清理 | 清理 runtime/ e/tmp/ data/dbcache/ 后重试 |
| 模板引擎错误 | 标签不解析或输出原始标签 | 模板语法错误或引擎版本差异 | 检查模板标签闭合和 CMS 版本对应语法 |
| 数据库表前缀 | Table 'xxx_tablename' doesn't exist |
表前缀配置与实际不一致 | 检查 CMS 配置文件中的表前缀设置 |
| MySQL 慢查询 | 页面卡顿 / SQL 超时 / CPU 飙高 | 缺索引、全表扫描、排序临时表 | 采集 SQL、参数、表行数和 EXPLAIN,参考 mysql-database.md |
| MySQL 死锁 | Deadlock found when trying to get lock |
事务顺序不一致或锁范围过大 | 缩短事务、统一更新顺序、检查索引命中 |
| 序列化数据 | unserialize(): Error at offset |
WordPress wp_options 等序列化数据损坏 |
用 maybe_unserialize() 或修复序列化字符串长度 |
| 伪静态路由 | 404 或路由不生效 | .htaccess / Nginx rewrite 规则缺失 |
检查伪静态规则和 CMS 路由配置 |
| 文件编码 | 中文乱码 / headers already sent |
UTF-8 BOM / GBK 编码混用 | 统一 UTF-8 无 BOM,用二进制方式读写文件 |
详见 cms-development.md。
karpathy-coding-guidelines 确认修复策略符合精准修改原则code-review 检查是否引入新问题test-generation 生成回归测试code-generation 生成替代实现cms-development.md 的兼容性检查和常见 Bug 模式mysql-database.md| 步骤 | 失败条件 | 回退目标 | 最大重试 | 不可恢复时升级路径 |
|---|---|---|---|---|
| 第一步:Spec场景检查 | 无spec或spec与实现不一致 | 基于代码和错误信息诊断,标注"无spec对照" | 1 | 诊断后建议走 Spec驱动开发 补全spec防止同类bug |
| 第二步:已知问题检查 | 项目记忆不可用或无相关记录 | 跳过已知问题检查,标注"记忆未加载" | 1 | 基于当前信息独立诊断,诊断完成后提示手动记录 |
| 第三步:错误解析 | 错误信息不完整,无法分类 | 基于已有信息匹配最接近的错误分类 | 2 | 告知所需最小信息集(错误消息+触发操作),等待补充 |
| 第四步:根因分析 | 多种可能根因均符合症状,无法唯一确定 | 列出候选根因,按可能性排序 | 2 | 输出诊断矩阵(候选根因×验证方法),由用户逐一排除 |
| 第五步:定位问题 | 涉及第三方库/外部服务,代码不可审视 | 标注第三方边界,定位调用链最近的可控点 | 1 | 给出workaround方案,建议向第三方提issue |
| 第六步:提供修复(Surgical Changes) | 修复方案需大规模重构(超出Bug修复范围) | 给出最小修复+重构建议供后续规划 | 2 | 拆分为Bug修复(立即)和架构优化(单独任务) |
| 第七步:定义成功标准(Goal-Driven Execution) | 修复涉及多系统联调,单次验证不充分 | 定义分层验证标准(单元→集成→端到端) | 1 | 给出回归测试checklist,建议灰度发布验证 |
| 第八步:记录到项目记忆 | 项目记忆系统不可用 | 输出Decision Record到本地文件 | 1 | 标注"记忆未沉淀",提示用户手动保存 |