diff options
| author | sillylaird <sillyfanboy@gmail.com> | 2026-09-03 00:33:59 +0000 |
|---|---|---|
| committer | sillylaird <sillyfanboy@gmail.com> | 2026-09-03 00:33:59 +0000 |
| commit | 898b52edcb47bcb3e9d6106e74ca73e74ea01e70 (patch) | |
| tree | 85c6ee5ad58b860144551184d4cf86b560c62b91 /.agents/skills/bug-detective/references | |
| download | www-main.tar.gz www-main.zip | |
Diffstat (limited to '.agents/skills/bug-detective/references')
5 files changed, 898 insertions, 0 deletions
diff --git a/.agents/skills/bug-detective/references/common-patterns.md b/.agents/skills/bug-detective/references/common-patterns.md new file mode 100644 index 0000000..b125edc --- /dev/null +++ b/.agents/skills/bug-detective/references/common-patterns.md @@ -0,0 +1,308 @@ +# 常见错误模式 + +## 通用编程错误模式 + +### 1. Off-by-one Error(差一错误) + +**描述**:循环或索引中出现 ±1 的偏差 + +**示例**: +```python +# ❌ 错误:范围应该是 range(n) 而不是 range(n+1) +for i in range(len(items) + 1): + print(items[i]) # IndexError + +# ✅ 正确 +for i in range(len(items)): + print(items[i]) +``` + +### 2. Null/None 引用错误 + +**描述**:尝试访问 None 对象的属性或方法 + +**Python**: +```python +# ❌ 可能返回 None +result = get_data() +print(result.value) # AttributeError + +# ✅ 检查 None +result = get_data() +if result is not None: + print(result.value) +``` + +**JavaScript**: +```javascript +// ❌ 可能是 null +const user = getUser(); +console.log(user.name); // TypeError + +// ✅ 使用可选链 +console.log(user?.name); +``` + +### 3. 资源泄漏 + +**描述**:打开的资源(文件、连接)未正确关闭 + +**Python**: +```python +# ❌ 文件可能未关闭 +f = open("file.txt") +content = f.read() +# 如果发生异常,文件不会关闭 + +# ✅ 使用 with 语句 +with open("file.txt") as f: + content = f.read() +# 文件自动关闭 +``` + +### 4. 竞态条件 + +**描述**:多线程/进程间的时序依赖问题 + +**示例**: +```python +# ❌ 检查后使用(TOCTOU) +if os.path.exists("file.txt"): + # 其他进程可能在这之间删除文件 + with open("file.txt") as f: + content = f.read() + +# ✅ 直接尝试并处理异常 +try: + with open("file.txt") as f: + content = f.read() +except FileNotFoundError: + content = None +``` + +### 5. 忘记返回值 + +**描述**:函数没有显式返回值,导致返回 None + +**示例**: +```python +# ❌ 忘记返回结果 +def calculate(x, y): + result = x + y + # 忘记 return + +# ✅ 正确返回 +def calculate(x, y): + return x + y +``` + +### 6. 错误的比较运算符 + +**描述**:使用 = 代替 ==,或混淆 is 和 == + +**Python**: +```python +# ❌ 赋值而不是比较 +if x = 5: # SyntaxError + +# ❌ 使用 is 比较值 +if x is 5: # 不保证正确 + +# ✅ 正确 +if x == 5: +``` + +### 7. 浮点数精度问题 + +**描述**:浮点数比较因精度问题失败 + +**示例**: +```python +# ❌ 直接比较浮点数 +if 0.1 + 0.2 == 0.3: # False + print("相等") + +# ✅ 使用容差比较 +if abs((0.1 + 0.2) - 0.3) < 1e-9: + print("相等") + +# 或使用 math.isclose() +import math +if math.isclose(0.1 + 0.2, 0.3): + print("相等") +``` + +### 8. 字符串拼接性能问题 + +**描述**:在循环中使用 + 拼接字符串 + +**示例**: +```python +# ❌ 低效:每次创建新字符串 +result = "" +for item in items: + result += str(item) + +# ✅ 高效:使用列表和 join +result = "".join(str(item) for item in items) +``` + +## Python 特有模式 + +### 1. 可变默认参数 + +```python +# ❌ 所有调用共享同一个列表 +def append(item, items=[]): + items.append(item) + return items + +# ✅ 使用 None 作为默认值 +def append(item, items=None): + if items is None: + items = [] + items.append(item) + return items +``` + +### 2. 闭包变量绑定问题 + +```python +# ❌ 所有函数使用相同的 i 值 +funcs = [lambda: i for i in range(3)] +# 所有函数都返回 2 + +# ✅ 使用默认参数捕获值 +funcs = [lambda i=i: i for i in range(3)] +``` + +### 3. 修改正在迭代的序列 + +```python +# ❌ 迭代时修改列表 +items = [1, 2, 3, 4] +for item in items: + if item % 2 == 0: + items.remove(item) + +# ✅ 创建新列表或使用副本 +items = [item for item in items if item % 2 != 0] + +# 或 +for item in items[:]: + if item % 2 == 0: + items.remove(item) +``` + +## JavaScript/TypeScript 特有模式 + +### 1. this 绑定问题 + +```javascript +// ❌ this 丢失上下文 +class Counter { + count = 0; + increment() { + setTimeout(function() { + this.count++; // this 不是 Counter 实例 + }, 100); + } +} + +// ✅ 使用箭头函数 +class Counter { + count = 0; + increment() { + setTimeout(() => { + this.count++; // this 正确绑定 + }, 100); + } +} +``` + +### 2. 异步错误处理 + +```javascript +// ❌ 没有处理 Promise 错误 +async function getData() { + const response = await fetch(url); + return response.json(); // 如果失败会抛出异常 +} + +// ✅ 使用 try-catch +async function getData() { + try { + const response = await fetch(url); + return await response.json(); + } catch (error) { + console.error("获取数据失败:", error); + throw error; + } +} +``` + +### 3. 数组/对象引用 + +```javascript +// ❌ 直接赋值会复制引用 +const arr1 = [1, 2, 3]; +const arr2 = arr1; +arr2.push(4); // arr1 也会被修改 + +// ✅ 创建副本 +const arr2 = [...arr1]; // 或 arr1.slice() + +// 对象 +const obj1 = { a: 1 }; +const obj2 = { ...obj1 }; // 或 Object.assign({}, obj1) +``` + +## 并发错误模式 + +### 1. 死锁 + +```python +# ❌ 可能死锁 +import threading + +lock1 = threading.Lock() +lock2 = threading.Lock() + +def thread1(): + with lock1: + with lock2: + # 操作 + +def thread2(): + with lock2: + with lock1: # 死锁 + # 操作 +``` + +### 2. 数据竞争 + +```python +# ❌ 多个线程同时修改共享变量 +counter = 0 + +def increment(): + global counter + counter += 1 # 非原子操作 + +# ✅ 使用锁 +counter = 0 +lock = threading.Lock() + +def increment(): + global counter + with lock: + counter += 1 +``` + +## 预防措施 + +1. **使用类型检查**:TypeScript、Python 类型注解 +2. **编写单元测试**:覆盖边界条件 +3. **使用静态分析工具**:pylint、eslint +4. **代码审查**:让他人检查代码 +5. **使用防御性编程**:验证输入、处理异常 diff --git a/.agents/skills/bug-detective/references/debugging-tools.md b/.agents/skills/bug-detective/references/debugging-tools.md new file mode 100644 index 0000000..59430a2 --- /dev/null +++ b/.agents/skills/bug-detective/references/debugging-tools.md @@ -0,0 +1,29 @@ +# Debugging Tools + +## Python +```bash +python -m pdb script.py +python -m traceback your_script.py +pytest -x -vv tests/test_target.py +``` + +## Node.js +```bash +node --inspect-brk app.js +node --trace-warnings app.js +npm test -- --runInBand +``` + +## Git +```bash +git bisect start +git bisect bad +git bisect good <known-good-commit> +``` + +## Shell +```bash +bash -n script.sh +bash -x script.sh +shellcheck script.sh +``` diff --git a/.agents/skills/bug-detective/references/javascript-errors.md b/.agents/skills/bug-detective/references/javascript-errors.md new file mode 100644 index 0000000..d731b1e --- /dev/null +++ b/.agents/skills/bug-detective/references/javascript-errors.md @@ -0,0 +1,14 @@ +# JavaScript / TypeScript Error Guide + +## Frequent failure classes +- `TypeError` from undefined/null access +- async error swallowing in `Promise` chains +- `this` binding mismatches +- stale closure bugs in hooks or event handlers +- ESM / CJS import mismatches + +## Minimum debugging flow +1. copy the full stack trace, +2. identify whether the failure is runtime, bundler, or type-level, +3. confirm the failing object/value before changing logic, +4. reproduce with the smallest possible input. diff --git a/.agents/skills/bug-detective/references/python-errors.md b/.agents/skills/bug-detective/references/python-errors.md new file mode 100644 index 0000000..dd973b6 --- /dev/null +++ b/.agents/skills/bug-detective/references/python-errors.md @@ -0,0 +1,311 @@ +# Python 错误详解 + +## 常见内置异常类型 + +### 1. SyntaxError(语法错误) + +**特征**:代码无法解析,在运行前就被检测到 + +**常见原因**: +- 括号不匹配 +- 缺少冒号 +- 缩进不正确 +- 引号不匹配 + +**示例**: +```python +# ❌ 缺少冒号 +if True + print("missing colon") + +# ✅ 正确 +if True: + print("has colon") +``` + +### 2. IndentationError(缩进错误) + +**特征**:缩进不一致或使用错误的缩进 + +**常见原因**: +- 混用 Tab 和空格 +- 缩进级别不正确 + +**示例**: +```python +# ❌ 混用空格和 Tab +def test(): + print("mixed") # Tab + print("spaces") # 空格 + +# ✅ 统一使用 4 个空格 +def test(): + print("spaces") + print("consistent") +``` + +### 3. NameError(名称错误) + +**特征**:变量或函数名不存在 + +**常见原因**: +- 变量未定义就使用 +- 函数名拼写错误 +- 变量作用域问题 + +**示例**: +```python +# ❌ 变量未定义 +print(undefined_var) + +# ✅ 先定义再使用 +my_var = 42 +print(my_var) +``` + +### 4. TypeError(类型错误) + +**特征**:操作或函数应用于错误的数据类型 + +**常见原因**: +- 拼接不同类型 +- 函数参数类型错误 +- 对不支持的操作使用运算符 + +**示例**: +```python +# ❌ 拼接字符串和数字 +result = "Value: " + 42 + +# ✅ 转换类型 +result = "Value: " + str(42) +# 或使用 f-string +result = f"Value: {42}" +``` + +### 5. AttributeError(属性错误) + +**特征**:对象没有指定的属性或方法 + +**常见原因**: +- 属性名拼写错误 +- 对象类型不是预期的 +- 大小写错误 + +**示例**: +```python +# ❌ 列表没有 append 以外的方法 +my_list = [1, 2, 3] +my_list.push(4) # 列表没有 push 方法 + +# ✅ 使用正确的方法 +my_list.append(4) +``` + +### 6. KeyError(键错误) + +**特征**:字典中不存在指定的键 + +**常见原因**: +- 键名拼写错误 +- 键不存在于字典中 + +**示例**: +```python +data = {"name": "Alice"} + +# ❌ 直接访问不存在的键 +age = data["age"] # KeyError + +# ✅ 使用 get() 方法 +age = data.get("age", 0) # 返回默认值 0 +``` + +### 7. IndexError(索引错误) + +**特征**:序列索引超出范围 + +**常见原因**: +- 索引为负数(除非是有意为之) +- 索引大于序列长度-1 +- 序列为空时访问索引 + +**示例**: +```python +items = [1, 2, 3] + +# ❌ 索引超出范围 +item = items[5] # IndexError + +# ✅ 检查长度后再访问 +if len(items) > 5: + item = items[5] +else: + item = None +``` + +### 8. ValueError(值错误) + +**特征**:参数类型正确但值不合适 + +**常见原因**: +- 字符串转整数失败 +- 数学运算值域错误 +- 参数值不在允许范围内 + +**示例**: +```python +# ❌ 无法转换为整数 +num = int("abc") + +# ✅ 处理可能的错误 +try: + num = int(input()) +except ValueError: + num = 0 +``` + +### 9. ImportError / ModuleNotFoundError(导入错误) + +**特征**:无法导入模块 + +**常见原因**: +- 模块未安装 +- 模块路径不在 PYTHONPATH 中 +- 模块名拼写错误 + +**示例**: +```python +# ❌ 模块未安装 +import missing_module + +# 解决方法:安装模块 +# pip install missing-module +``` + +### 10. FileNotFoundError(文件未找到错误) + +**特征**:尝试打开不存在的文件 + +**常见原因**: +- 文件路径错误 +- 文件不存在 +- 相对路径使用错误 + +**示例**: +```python +# ❌ 文件不存在 +with open("missing.txt") as f: + content = f.read() + +# ✅ 使用 try-except 或检查文件存在 +try: + with open("file.txt") as f: + content = f.read() +except FileNotFoundError: + content = "" +``` + +## 异常处理最佳实践 + +### 1. 捕获具体异常 + +```python +# ❌ 捕获所有异常(不良实践) +try: + result = dangerous_operation() +except: + pass + +# ✅ 捕获具体异常 +try: + result = dangerous_operation() +except (ValueError, TypeError) as e: + logger.error(f"操作失败: {e}") +``` + +### 2. 使用 finally 清理资源 + +```python +try: + file = open("data.txt", "r") + content = file.read() +except FileNotFoundError: + content = "" +finally: + # 无论是否发生异常都会执行 + if 'file' in locals(): + file.close() +``` + +### 3. 使用上下文管理器 + +```python +# ✅ 推荐:使用 with 语句 +with open("data.txt", "r") as file: + content = file.read() +# 文件会自动关闭 +``` + +### 4. 链式异常 + +```python +try: + process_data(data) +except ValueError as e: + # 使用 raise from 保留原始异常 + raise RuntimeError("数据处理失败") from e +``` + +## 调试技巧 + +### 1. 使用 traceback 模块 + +```python +import traceback + +try: + risky_operation() +except Exception: + # 打印完整的堆栈跟踪 + traceback.print_exc() +``` + +### 2. 使用 pdb 调试器 + +```python +import pdb + +# 在代码中设置断点 +pdb.set_trace() + +# 或使用 breakpoint() (Python 3.7+) +breakpoint() +``` + +### 3. 使用 logging 模块 + +```python +import logging + +logging.basicConfig(level=logging.DEBUG) +logger = logging.getLogger(__name__) + +logger.debug("调试信息") +logger.info("普通信息") +logger.warning("警告") +logger.error("错误") +logger.critical("严重错误") +``` + +## 常见错误排查清单 + +- [ ] 检查拼写(变量名、函数名、属性名) +- [ ] 检查数据类型(使用 type() 函数) +- [ ] 检查变量值(使用 print() 或调试器) +- [ ] 检查索引和键是否在范围内 +- [ ] 检查文件路径是否正确 +- [ ] 检查缩进是否一致 +- [ ] 检查括号、引号是否匹配 +- [ ] 检查是否正确导入了模块 +- [ ] 检查异常是否被正确处理 diff --git a/.agents/skills/bug-detective/references/shell-errors.md b/.agents/skills/bug-detective/references/shell-errors.md new file mode 100644 index 0000000..82ca8c8 --- /dev/null +++ b/.agents/skills/bug-detective/references/shell-errors.md @@ -0,0 +1,236 @@ +# Bash/Zsh 脚本错误详解 + +## 常见错误类型 + +### 1. Command Not Found + +**特征**:bash: command: command not found + +**常见原因**: +- 命令拼写错误 +- 命令未安装 +- PATH 环境变量不正确 +- 脚本 shebang 错误 + +**示例**: +```bash +# 拼写错误 +pyhon script.py # command not found + +# 正确拼写 +python script.py + +# PATH 问题 +/usr/local/bin/mycommand # 如果 PATH 不包含 /usr/local/bin + +# 使用完整路径或添加到 PATH +export PATH="/usr/local/bin:$PATH" +mycommand +``` + +### 2. Syntax Error + +**特征**:syntax error near unexpected token + +**常见原因**: +- 缺少 then/fi/done/ esac +- 括号不匹配 +- 操作符缺少空格 + +**示例**: +```bash +# 缺少 then +if [ 1 -eq 1 ] +echo "yes" # syntax error + +# 正确 +if [ 1 -eq 1 ]; then + echo "yes" +fi +``` + +### 3. Permission Denied + +**特征**:bash: ./script.sh: Permission denied + +**解决方案**: +```bash +# 添加执行权限 +chmod +x script.sh + +# 或使用 bash 运行 +bash script.sh +``` + +## 调试技巧 + +### 1. 使用 set -x 追踪执行 + +```bash +#!/bin/bash +set -x # 启用命令追踪 + +name="John" +echo "Hello $name" + +# 输出: +# + name=John +# + echo 'Hello John' +# Hello John +``` + +### 2. 使用 set -e 遇错退出 + +```bash +#!/bin/bash +set -e # 任何命令失败时退出 + +cd /nonexistent # 脚本在此处退出 +echo "This won't run" +``` + +### 3. 使用 set -u 检测未定义变量 + +```bash +#!/bin/bash +set -u # 未定义变量时报错 + +echo $undefined_var # 报错并退出 +``` + +### 4. 组合使用调试选项 + +```bash +#!/bin/bash +set -xeuo pipefail # 严格模式 + +# -x: 打印每个命令 +# -e: 错误时退出 +# -u: 未定义变量报错 +# -o pipefail: 管道失败则失败 +``` + +### 5. 使用 trap 捕获错误 + +```bash +#!/bin/bash +# 在脚本退出时执行清理 +trap 'echo "Script exited with code $?"' EXIT + +# 在错误时执行 +trap 'echo "Error on line $LINENO"' ERR + +# 在中断时执行 +trap 'echo "Interrupted"; cleanup' INT +``` + +## 错误处理模式 + +### 1. 检查命令退出码 + +```bash +# 检查上一个命令是否成功 +if [ $? -eq 0 ]; then + echo "Success" +else + echo "Failed" +fi + +# 或使用 || +command || { echo "Failed"; exit 1; } + +# 或使用 && +command && echo "Success" || echo "Failed" +``` + +### 2. 使用函数封装错误处理 + +```bash +# 定义错误处理函数 +die() { + local message=$1 + echo "Error: $message" >&2 + exit 1 +} + +# 使用 +[ -f "$file" ] || die "File not found: $file" +``` + +### 3. 验证输入参数 + +```bash +#!/bin/bash +# 检查参数数量 +[ $# -ge 1 ] || die "Usage: $0 <arg1> [arg2]" + +# 检查文件存在 +[ -f "$1" ] || die "File not found: $1" + +# 检查目录存在 +[ -d "$2" ] || die "Directory not found: $2" +``` + +## 最佳实践 + +### 1. 始终使用 shebang + +```bash +#!/bin/bash +# 或 +#!/usr/bin/env bash +``` + +### 2. 使用 set -euo pipefail + +```bash +#!/bin/bash +set -euo pipefail +``` + +### 3. 引用所有变量 + +```bash +# 除非确定变量不包含空格或通配符 +echo "$var" +``` + +### 4. 使用 [[ ]] 而不是 [ ] + +```bash +# [[ 更强大且更安全 +if [[ $name == "John" ]]; then +if [[ -f $file && $size -gt 100 ]]; then +``` + +### 5. 使用 $(command) 而不是反引号 + +```bash +# $() 更易读且可嵌套 +result=$(command1 $(command2)) +``` + +### 6. 使用函数组织代码 + +```bash +my_function() { + local arg1=$1 + local arg2=$2 + # 函数体 +} + +my_function "value1" "value2" +``` + +## ShellCheck 静态分析 + +ShellCheck 是一个 Shell 脚本静态分析工具: + +```bash +# 安装 ShellCheck +brew install shellcheck # macOS +apt install shellcheck # Ubuntu + +# 使用 +shellcheck script.sh +``` |
