728 lines
30 KiB
Markdown
728 lines
30 KiB
Markdown
#### C. 类别三:代码审查与质量保障 (QA & Review)
|
||
|
||
**模板索引 (Index)**
|
||
|
||
| 模板ID | 核心用途 | 使用场景 / 关键词 |
|
||
| :--- | :--- | :--- |
|
||
| **C-1: 静态理解与逻辑分析** | | |
|
||
| **[`C1`](#C1)** | 复杂逻辑解释 | __syncthreads, 模板元编程, 位运算, 正则解析 |
|
||
| **[`C2`](#C2)** | 依赖与调用链分析 | include依赖, Call Graph, Mermaid |
|
||
| **[`C3`](#C3)** | 接口与实现一致性审查 | 派生类签名校验, const/noexcept, 覆盖完整性 |
|
||
| **C-2: 验证与测试用例生成** | | |
|
||
| **[`C4`](#C4)** | 单元测试生成 | gtest脚手架, Happy/Edge, 异常测试 |
|
||
| **[`C5`](#C5)** | 边界条件增强 | Edge cases, 负路径, 完备性检查 |
|
||
| **[`C6`](#C6)** | 模拟数据/桩函数生成 | gmock, Mock类, 样例数据 |
|
||
| **[`C7`](#C7)** | 集成/E2E测试脚本 | gRPC/REST脚本, 端到端验证 |
|
||
| **C-3: 风险、安全与并发审查** | | |
|
||
| **[`C8`](#C8)** | 潜在Bug与逻辑审查 | 逻辑缺陷, 资源泄漏, 越界 |
|
||
| **[`C9`](#C9)** | 并发安全专项审查 | Data Race, 共享状态, mutex |
|
||
| **[`C10`](#C10)** | 错误处理路径审查 | 资源释放, 返回值健壮性 |
|
||
| **[`C11`](#C11)** | 安全漏洞专项审查 | 缓冲区溢出, 格式化字符串, 注入风险 |
|
||
| **C-4: 迭代与代码评审** | | |
|
||
| **[`C12`](#C12)** | 方案自我批判 | 缺陷/陷阱识别, 改进建议 |
|
||
| **[`C13`](#C13)** | 可读性与规范评审 | 命名/风格/全局状态, 重构建议 |
|
||
|
||
-----
|
||
|
||
**子类别 C-1: 静态理解与逻辑分析 (Static Understanding & Analysis)**
|
||
|
||
<a id="C1"></a>
|
||
|
||
-----
|
||
|
||
**模板名称:** `C1: 复杂逻辑解释`
|
||
**适用场景:** `原则二:玻璃盒` 的核心应用。用于深入理解一个复杂的、难以读懂的代码块。例如:`2.2.4` 中的 `__syncthreads` 工作原理、C++模板元编程(TMP)、复杂的位运算技巧、或晦涩的正则表达式。
|
||
**内嵌原则:** `[原则二:玻璃盒心态]` (核心), `[原则五:上下文即燃料]` (输入代码是关键)。
|
||
|
||
**[Prompt 模板]**
|
||
|
||
```txt
|
||
角色:你是一名精通 [相关领域,例如:CUDA C++ / C++20 模板元编程 / POSIX并发] 的专家和技术导师。
|
||
|
||
任务:请向我(一名有经验但非此领域专家的工程师)深入、清晰地解释以下代码片段。
|
||
|
||
== 待解释的代码 ==
|
||
[粘贴你无法理解的复杂代码片段。例如:
|
||
__global__ void myKernel(...) {
|
||
// ...
|
||
extern __shared__ float s_data[];
|
||
s_data[threadIdx.x] = ...;
|
||
__syncthreads(); // <-- 重点解释这个
|
||
// ...
|
||
}
|
||
]
|
||
|
||
== 解释要求 (玻璃盒原则) ==
|
||
请严格按照以下结构回答:
|
||
1. 核心功能 (What): 这段代码(或特定行 [例如:__syncthreads()]) 的主要目的是什么?
|
||
2. 工作原理 (How): 它在技术/时序上是如何实现这一目的的?(请分步骤说明)
|
||
3. 设计动机 (Why): 为什么作者选择用这种(看起来很复杂)的方式来实现?它解决了什么性能/逻辑问题?
|
||
4. 风险与“反面教材” (What If): 如果 [例如:删除 __syncthreads() / 替换为其他实现],会导致什么具体的错误或性能退化?(这是关键)
|
||
```
|
||
|
||
**填充指南:**
|
||
|
||
- `[相关领域]`:明确告知AI需要扮演的专家角色,例如 `CUDA C++`, `C++20 Concepts`, `Boost.Asio`。
|
||
- `[待解释的代码]`:粘贴你希望理解的代码。
|
||
- `[解释要求]`:**这是此模板的核心**。通过`What/How/Why/What If`结构,强制AI提供“深度、可操作”的解释,而非停留在表面的“它是一个同步原语”这种废话上(玻璃盒原则)。
|
||
|
||
<a id="C2"></a>
|
||
|
||
-----
|
||
|
||
**模板名称:** `C2: 代码依赖与调用链分析`
|
||
**适用场景:** 在进行重构、优化或接手遗留模块(痛点3)之前,需要快速理解其内部结构和外部依赖,绘制“架构地图”。
|
||
**内嵌原则:** `[原则五:上下文即燃料]` (输入文件是关键), `[原则七:结构化输出]` (强制输出结构化列表或图)。
|
||
|
||
**[Prompt 模板]**
|
||
|
||
```txt
|
||
角色:你是一名精通C++代码静态分析的工具开发者。
|
||
|
||
任务:请分析以下C++模块的源代码,并提供一份结构化的依赖和调用链报告。
|
||
|
||
== 模块上下文 ==
|
||
[粘贴你需要分析的代码,可以是一个.h文件、一个.cpp文件,或两者的组合]
|
||
// 例如:
|
||
// --- MyProcessor.h ---
|
||
#include <vector>
|
||
#include "IReader.h" // 外部依赖
|
||
#include "utils/common.h" // 内部依赖
|
||
|
||
class MyProcessor {
|
||
public:
|
||
bool runPipeline(const Config& cfg);
|
||
private:
|
||
void loadData(int id);
|
||
bool processBlock(std...);
|
||
IReader* reader_;
|
||
};
|
||
|
||
// --- MyProcessor.cpp ---
|
||
#include "MyProcessor.h"
|
||
#include <iostream> // 外部依赖
|
||
|
||
bool MyProcessor::runPipeline(const Config& cfg) {
|
||
if (!cfg.isValid) return false;
|
||
loadData(cfg.id); // 内部调用1
|
||
processBlock(...); // 内部调用2
|
||
return true;
|
||
}
|
||
// ... (其他实现) ...
|
||
|
||
== 分析与输出要求 ==
|
||
请严格按照以下格式输出:
|
||
1. 外部依赖 (External Includes):
|
||
- [例如:<vector>, <iostream>, "IReader.h"]
|
||
2. 内部依赖 (Internal Includes):
|
||
- [例如:"utils/common.h"]
|
||
3. 调用链分析 (Call Graph):
|
||
- 请为 [目标公共函数,例如:runPipeline] 生成一个调用链(直到私有函数)。
|
||
- (可选) 请使用Mermaid (graph TD) 格式展示。
|
||
- (示例) runPipeline --> loadData; runPipeline --> processBlock;
|
||
```
|
||
|
||
**填充指南:**
|
||
|
||
- `[模块上下文]`:粘贴你希望分析的源代码。代码越完整,分析越准确。
|
||
- `[目标公共函数]`:明确指定你希望分析的调用链入口点。
|
||
- **使用指南:** 此模板用于快速、静态地理解代码结构。对于大型复杂项目,AI的分析可能需要与IDE的“Find All References”功能结合使用。
|
||
|
||
<a id="C3"></a>
|
||
|
||
-----
|
||
|
||
**模板名称:** `C3: 接口与实现一致性审查`
|
||
**适用场景:** 在面向接口编程(痛点4)或代码审查(痛点3)时,确保一个实现类(Concrete Class)严格、完整地遵守了其接口(Interface)的约定。
|
||
**内嵌原则:** `[原则五:上下文即燃料]` (输入接口和实现), `[原则七:结构化输出]` (输出审查报告)。
|
||
|
||
**[Prompt 模板]**
|
||
|
||
```txt
|
||
角色:你是一名严格的C++编译器和代码审查专家。
|
||
|
||
任务:请严格审查以下 [实现类] 是否100%符合 [接口] 的定义和规范。
|
||
|
||
== 接口定义 (.h) ==
|
||
[粘贴接口的头文件内容,例如:IProcessor.h]
|
||
// IProcessor.h
|
||
class IProcessor {
|
||
public:
|
||
virtual ~IProcessor() = default;
|
||
virtual bool initialize(const Config& cfg) = 0;
|
||
virtual int process(float* data) noexcept = 0;
|
||
virtual Status getStatus() const = 0;
|
||
};
|
||
|
||
== 实现类 (.h / .cpp) ==
|
||
[粘贴实现类的头文件或源文件内容,例如:GpuProcessor.h]
|
||
// GpuProcessor.h
|
||
#include "IProcessor.h"
|
||
class GpuProcessor : public IProcessor {
|
||
public:
|
||
// 缺失 virtual 析构函数
|
||
bool initialize(Config& cfg); // 错误:Config 应该是 const&
|
||
int process(float* data); // 错误:缺失 noexcept
|
||
// 错误:缺失 getStatus() 的 const 实现
|
||
};
|
||
|
||
== 审查要求 ==
|
||
请识别 [实现类] 中所有违反 [接口] 约定的地方,并以结构化列表形式返回:
|
||
1. 缺失的实现: [例如:GpuProcessor 必须实现 getStatus() const]
|
||
2. 签名不匹配: [例如:initialize() 的参数类型与接口不匹配 (应该是 const Config&)]
|
||
3. 限定符不匹配 (const/noexcept): [例如:process() 缺失了 noexcept 限定符]
|
||
4. 其他违反(如析构函数): [例如:GpuProcessor 缺少虚析构函数,可能导致内存泄漏]
|
||
```
|
||
|
||
**填充指南:**
|
||
|
||
- `[接口定义]`:提供基类(接口)的完整定义。
|
||
- `[实现类]`:提供派生类(实现)的定义。
|
||
- **使用指南:** 这是确保“面向接口编程”正确性的关键工具,能自动化捕获C++编译器可能(或可能不会)警告的微妙差异(如`noexcept`)。
|
||
|
||
-----
|
||
|
||
**子类别 C-2: 验证与测试用例生成 (Verification & Test Case Generation)**
|
||
|
||
<a id="C4"></a>
|
||
|
||
-----
|
||
|
||
**模板名称:** `C4: 单元测试生成`
|
||
**适用场景:** `2.4.2` 的核心模板。用于为新编写的函数或模块快速生成单元测试(Unit Test)的“脚手架”,解决工程师不愿写测试的痛点。
|
||
**内嵌原则:** `[原则五:上下文即燃料]` (输入原函数), `[原则七:结构化输出]` (输出gtest代码)。
|
||
|
||
**[Prompt 模板]**
|
||
|
||
```txt
|
||
角色:你是一名精通C++和Google Test (gtest) 框架的软件质量保障(QA)工程师。
|
||
|
||
任务:请为以下C++函数/类生成一套完整的gtest单元测试脚手架。
|
||
|
||
== 待测试的代码 ==
|
||
[粘贴你的函数签名或完整实现,例如:]
|
||
#include <string>
|
||
#include <stdexcept>
|
||
|
||
// 函数:安全地将字符串转换为整数
|
||
int stringToInt(const std::string& str) {
|
||
if (str.empty()) {
|
||
throw std::invalid_argument("Input string is empty");
|
||
}
|
||
try {
|
||
return std::stoi(str);
|
||
} catch (const std::exception& e) {
|
||
throw; // 重新抛出
|
||
}
|
||
}
|
||
|
||
== 测试要求 ==
|
||
1. 测试框架:[例如:gtest]
|
||
2. 必须包含必要的 #include (包括 "gtest/gtest.h" 和被测代码的头文件)。
|
||
3. 必须包含一个 "Happy Path"(正常路径)测试用例 (例如:输入 "123")。
|
||
4. 必须包含至少两个 "Negative Path" / "Edge Case"(异常/边界)测试用例 (例如:输入 "abc", 输入 "")。
|
||
5. 对于预期抛出异常的测试,必须使用 EXPECT_THROW 宏。
|
||
6. 提供完整的、可直接编译的 .cpp 测试文件内容。
|
||
```
|
||
|
||
**填充指南:**
|
||
|
||
- `[待测试的代码]`:提供代码。代码越完整(包含实现),AI生成的负面测试用例越准确。
|
||
- `[测试框架]`:明确指定,如 `gtest`, `pytest` (Python), `JUnit` (Java)。
|
||
- **使用指南:** AI生成的测试仅为“脚手架”,工程师必须审查其断言(Assertions)的正确性,并补充AI未能覆盖的业务逻辑边界。
|
||
|
||
<a id="C5"></a>
|
||
|
||
-----
|
||
|
||
**模板名称:** `C5: 测试用例“边界条件”增强`
|
||
**适用场景:** 对抗工程师“只写Happy Path”的惰性(痛点6)。当你已有一个(或AI刚生成)仅覆盖正常路径的测试时,使用此模板强制AI进行“批判性思考”,补充所有被忽略的边界条件。
|
||
**内嵌原则:** `[原则五:上下文即燃料]` (输入原测试), `[原则八:自我批判]` (AI扮演评审专家), `[原则六:示例优先]` (原测试作为示例)。
|
||
|
||
**[Prompt 模板]**
|
||
|
||
```txt
|
||
角色:你是一名资深的、吹毛求疵的QA专家,擅长识别代码中的边界条件(Edge Cases)。
|
||
|
||
任务:我已经为 [函数名] 编写了“Happy Path”测试。请严格审查此测试,并为其补充一套“完备的边界条件”测试用例。
|
||
|
||
== 待测试的函数签名 ==
|
||
[例如:std::vector<float> movingAverage(const std::vector<float>& data, int windowSize);]
|
||
|
||
== 我已有的 "Happy Path" 测试 (✅) ==
|
||
[粘贴你已有的简单测试代码]
|
||
TEST(MovingAverageTest, HandlesNormalInput) {
|
||
std::vector<float> data = {1.0, 2.0, 3.0, 4.0, 5.0};
|
||
int windowSize = 3;
|
||
std::vector<float> result = movingAverage(data, windowSize);
|
||
// 假设结果是 {2.0, 3.0, 4.0} (简化)
|
||
EXPECT_EQ(result.size(), 3);
|
||
EXPECT_NEAR(result[0], 2.0, 0.001);
|
||
}
|
||
|
||
== 增强要求 (❌ 遗漏的) ==
|
||
请为 [函数名] 补充以下所有被遗漏的、关键的边界条件测试:
|
||
1. [边界1,例如:输入空的 std::vector (data.empty())]
|
||
2. [边界2,例如:windowSize 为 0 或 负数]
|
||
3. [边界3,例如:windowSize 大于 data.size()]
|
||
4. [边界4,例如:windowSize 为 1]
|
||
5. (可选) [边界5,例如:data 中包含 NaN 或 Inf 值]
|
||
|
||
== 输出要求 ==
|
||
- 仅提供新生成的、用于覆盖上述边界条件的gtest TEST(...) 代码块。
|
||
```
|
||
|
||
**填充指南:**
|
||
|
||
- `[待测试的函数签名]`:提供函数签名,帮助AI理解上下文。
|
||
- `[我已有的 "Happy Path" 测试]`:提供一个示例(原则六),AI会模仿其风格。
|
||
- `[增强要求]`:明确列出你希望AI覆盖的边界类型。
|
||
|
||
<a id="C6"></a>
|
||
|
||
-----
|
||
|
||
**模板名称:** `C6: 模拟数据/桩函数生成`
|
||
**适用场景:** 在编写单元测试时(尤其是针对复杂数据结构或依赖接口的模块),手动创建模拟数据(Mock Data)或桩函数(Mock/Stub)非常繁琐。
|
||
**内嵌原则:** `[原则五:上下文即燃料]` (输入数据结构/接口), `[原则七:结构化输出]` (输出gmock代码或数据)。
|
||
|
||
**[Prompt 模板]**
|
||
|
||
```txt
|
||
角色:你是一名精通 [框架,例如:gtest/gmock] 的测试工程师。
|
||
|
||
任务:请为我生成 [目标:Mock类 / 模拟数据]。
|
||
|
||
== 上下文 ==
|
||
[粘贴你需要模拟的接口定义或数据结构定义]
|
||
// 例如 (二选一):
|
||
// [上下文A:gmock]
|
||
class IDataReader {
|
||
public:
|
||
virtual ~IDataReader() = default;
|
||
virtual std::vector<float> readData(int id) = 0;
|
||
virtual bool writeConfig(const Config& cfg) = 0;
|
||
};
|
||
|
||
// [上下文B:模拟数据]
|
||
struct RadarTrack {
|
||
int track_id;
|
||
double x, y, z;
|
||
double vx, vy, vz;
|
||
std::string status;
|
||
};
|
||
|
||
== 生成要求 ==
|
||
|
||
[任务A:生成 gmock 类 (基于上下文A)]
|
||
1. 目标:为 IDataReader 接口生成一个完整的 gmock 类 MockDataReader。
|
||
2. 必须包含所有 MOCK_METHOD 宏。
|
||
|
||
[任务B:生成模拟数据 (基于上下文B)]
|
||
1. 目标:生成一个C++代码片段,用于创建一个 std::vector<RadarTrack>。
|
||
2. 要求:向量中必须包含 [数量,例如:5] 个示例对象,每个对象的数据必须是随机但合理的(例如,id递增,status为"active"或"lost")。
|
||
|
||
== 输出要求 ==
|
||
- 提供完整的、可直接复制粘贴的C++代码块。
|
||
```
|
||
|
||
**填充指南:**
|
||
|
||
- `[上下文]`:**必须提供。** AI需要知道接口或`struct`的定义才能生成代码。
|
||
- `[任务A/B]`:**使用时请二选一**,删除你不需要的那个任务。
|
||
- `[数量]`:在生成数据时,指定你需要多少示例。
|
||
|
||
<a id="C7"></a>
|
||
|
||
-----
|
||
|
||
**模板名称:** `C7: 集成/E2E测试脚本生成`
|
||
**适用场景:** 当模块开发完成并暴露API(如gRPC或REST)后,需要快速编写一个“黑盒”测试脚本,从外部验证其端到端(E2E)功能是否符合预期。
|
||
**内嵌原则:** `[原则五:上下文即燃料]` (输入API定义), `[原则七:结构化输出]` (输出脚本代码)。
|
||
|
||
**[Prompt 模板]**
|
||
|
||
```txt
|
||
角色:你是一名精通 [语言/工具,例如:Python (grpcio) / Shell (grpcurl)] 的自动化测试工程师。
|
||
|
||
任务:请为以下 [API类型,例如:gRPC服务] 编写一个端到端(E2E)测试脚本。
|
||
|
||
== API 定义 ==
|
||
[粘贴你的API定义,例如 .proto 文件内容]
|
||
syntax = "proto3";
|
||
package radar.api;
|
||
|
||
service TrackService {
|
||
// 创建一个新航迹
|
||
rpc CreateTrack (CreateTrackRequest) returns (TrackResponse);
|
||
// 获取一个航迹
|
||
rpc GetTrack (GetTrackRequest) returns (TrackResponse);
|
||
}
|
||
|
||
message CreateTrackRequest {
|
||
int32 id = 1;
|
||
double x = 2;
|
||
double y = 3;
|
||
}
|
||
message GetTrackRequest {
|
||
int32 id = 1;
|
||
}
|
||
message TrackResponse {
|
||
int32 id = 1;
|
||
double x = 2;
|
||
double y = 3;
|
||
}
|
||
|
||
== 测试场景要求 ==
|
||
脚本必须在 [语言/工具] 中实现以下E2E测试流程:
|
||
1. [例如:Python] 导入必要的库 (如 grpcio)。
|
||
2. [例如:Python] 创建一个到 localhost:50051 的 gRPC 通道。
|
||
3. 步骤1 (创建): 调用 CreateTrack RPC,创建一个 ID=101, x=1.2, y=3.4 的航迹。
|
||
4. 步骤2 (验证): 立即调用 GetTrack RPC,查询 ID=101。
|
||
5. 步骤3 (断言): 必须检查 GetTrack 返回的响应,确保其 x, y 值与创建时一致。
|
||
6. 打印“测试通过”或“测试失败”的结论。
|
||
|
||
== 输出要求 ==
|
||
- 提供完整的、可直接执行的 [语言/工具] 脚本代码。
|
||
```
|
||
|
||
**填充指南:**
|
||
|
||
- `[语言/工具]`:明确指定你希望用什么来测试,例如 `Python (grpcio)`, `Shell (grpcurl)`, `Python (requests)` (用于REST)。
|
||
- `[API 定义]`:提供`.proto`, `OpenAPI yaml` 或 API的文字描述。
|
||
- `[测试场景要求]`:**这是核心**。清晰描述你希望脚本执行的“步骤”,AI会将其翻译为代码。
|
||
|
||
-----
|
||
|
||
**子类别 C-3: 风险、安全与并发审查 (Risk, Security & Falsification)**
|
||
|
||
<a id="C8"></a>
|
||
|
||
-----
|
||
|
||
**模板名称:** `C8: 潜在Bug与逻辑审查`
|
||
**适用场景:** `2.4.6` 的核心模板。在代码审查(Code Review)阶段,利用AI作为“AI审查员”,自动扫描代码中常见的、容易被忽视的逻辑错误或风险。
|
||
**内嵌原则:** `[原则八:自我批判]` (AI扮演评审专家), `[原则五:上下文即燃料]` (输入代码), `[原则七:结构化输出]` (输出结构化报告)。
|
||
|
||
**[Prompt 模板]**
|
||
|
||
```txt
|
||
角色:你是一名资深的C++代码审查(Code Review)专家,尤其擅长发现内存安全和逻辑漏洞。
|
||
|
||
任务:请严格审查以下C++代码,找出所有潜在的Bug、逻辑错误或未定义行为。
|
||
|
||
== 待审查的代码 ==
|
||
[粘贴你怀疑存在问题,或刚编写完成的C++代码片段]
|
||
// 示例:一个包含多种常见错误的代码
|
||
void process_array(int* data, int size) {
|
||
if (data = nullptr) { // 错误1:赋值而非比较
|
||
return;
|
||
}
|
||
|
||
for (int i = 0; i <= size; i++) { // 错误2:off-by-one 越界
|
||
if (size > 10) {
|
||
int* temp_buffer = new int[size]; // 错误3:资源泄漏
|
||
// ... (do something with temp_buffer) ...
|
||
if (data[i] > 100) {
|
||
// ...
|
||
}
|
||
}
|
||
}
|
||
// 错误3:temp_buffer 在循环结束后未被 delete[]
|
||
}
|
||
|
||
== 审查重点 ==
|
||
1. 逻辑错误: 检查 if 判断(如 == 写成 =)、循环条件(如 off-by-one 错误)。
|
||
2. 内存访问: 检查是否存在数组越界、空指针解引用(nullptr dereference)。
|
||
3. 资源泄漏: 检查是否有 new/malloc/fopen 之后,在所有路径(包括异常路径)上都忘记 delete/free/fclose?
|
||
|
||
== 输出要求 ==
|
||
请严格按照“缺陷报告”的格式返回,逐条列出:
|
||
- [缺陷 1]: (例如:潜在的空指针赋值)
|
||
- [风险]: (例如:if (data = nullptr) 永远为false,且修改了入参指针)
|
||
- [修复建议]: (例如:应改为 if (data == nullptr))
|
||
-----
|
||
- [缺陷 2]: (例如:循环条件越界)
|
||
- [风险]: (例如:i <= size 导致访问 data[size],数组越界)
|
||
- [修复建议]: (例如:应改为 for (int i = 0; i < size; i++))
|
||
-----
|
||
- [缺陷 3]: ...
|
||
```
|
||
|
||
**填充指南:**
|
||
|
||
- `[待审查的代码]`:提供你希望AI进行审查的代码片段。
|
||
- `[审查重点]`:你可以根据代码的特点,调整AI的审查优先级。
|
||
- **使用指南:** 此模板是`原则八:自我批判`的绝佳实践,在你自己(或AI)完成编码后,立即使用此模板进行交叉检查。
|
||
|
||
<a id="C9"></a>
|
||
|
||
-----
|
||
|
||
**模板名称:** `C9: 并发安全专项审查`
|
||
**适用场景:** 针对团队新架构(多线程服务器)的核心痛点(痛点2、痛点3)。在代码审查期间,专门用于分析一个类在多线程环境下的数据竞争(Data Races)风险。
|
||
**内嵌原则:** `[原则二:玻璃盒心态]` (强制分析竞态条件), `[原则五:上下文即燃料]` (输入类定义), `[原则七:结构化输出]` (输出报告)。
|
||
|
||
**[Prompt 模板]**
|
||
|
||
```txt
|
||
角色:你是一名精通C++17/20并发编程(Multithreading)和内存模型(Memory Model)的专家。
|
||
|
||
任务:请严格审查以下C++类在多线程环境下的安全性。
|
||
|
||
== 待审查的类定义 ==
|
||
[粘贴你的C++类定义,包括.h和.cpp的相关方法]
|
||
// 示例:一个线程不安全的计数器
|
||
#include <map>
|
||
#include <string>
|
||
|
||
class UserStats {
|
||
public:
|
||
void incrementLogin(const std::string& user) {
|
||
// 风险点1:对 map 的并发写
|
||
login_counts_[user]++;
|
||
}
|
||
|
||
int getLoginCount(const std::string& user) {
|
||
// 风险点2:对 map 的并发读
|
||
auto it = login_counts_.find(user);
|
||
if (it != login_counts_.end()) {
|
||
return it->second;
|
||
}
|
||
return 0;
|
||
}
|
||
|
||
private:
|
||
// 风险点3:共享状态
|
||
std::map<std::string, int> login_counts_;
|
||
};
|
||
|
||
== 审查要求 ==
|
||
1. 识别共享状态: 找出所有被多个public方法(或线程)并发读/写的成员变量。
|
||
2. 分析竞态条件 (Race Conditions): 明确指出哪些操作组合(如 incrementLogin 与 incrementLogin,或 incrementLogin 与 getLoginCount)会在此共享状态上导致数据竞争。
|
||
3. 修复建议: 提供一个线程安全(Thread-Safe)的修复版本。
|
||
4. 同步机制: 请使用 [偏好的机制,例如:std::mutex / std::shared\_mutex] 来保护共享状态。
|
||
|
||
== 输出要求 ==
|
||
1. 共享状态分析: [例如:login_counts_ 是被 incrementLogin (写) 和 getLoginCount (读) 并发访问的共享状态]
|
||
2. 竞态条件分析: [例如:当两个线程同时调用 incrementLogin 时,map::operator[] 和 int++ 操作非原子,会导致计数丢失或map结构损坏...]
|
||
3. 修复后的代码: (提供添加了 std::mutex 和 std::lock_guard 的线程安全版本)
|
||
```
|
||
|
||
**填充指南:**
|
||
|
||
- `[待审查的类定义]`:提供完整的类代码,AI需要看到所有访问成员变量的方法。
|
||
- `[偏好的机制]`:指定团队技术栈(如 `std::mutex`),确保修复方案的风格一致。
|
||
- **使用指南:** 这是新架构下Code Review的**必选动作**。
|
||
|
||
<a id="C10"></a>
|
||
|
||
-----
|
||
|
||
**模板名称:** `C10: 错误处理路径审查`
|
||
**适用场景:** 确保代码的健壮性。用于审查一个函数是否正确、完整地处理了所有可能的失败路径,防止“静默失败”(Silently Failing)。
|
||
**内嵌原则:** `[原则二:玻璃盒心态]` (强制分析所有路径), `[原则五:上下文即燃料]` (输入代码), `[原则七:结构化输出]` (输出报告)。
|
||
|
||
**[Prompt 模板]**
|
||
|
||
```txt
|
||
角色:你是一名精通防御性编程(Defensive Programming)和C++异常安全的专家。
|
||
|
||
任务:请严格审查以下函数的“错误处理路径”是否健壮和完备。
|
||
|
||
== 待审查的函数 ==
|
||
[粘贴你的函数代码,特别是包含C风格API、外部调用或资源分配的代码]
|
||
// 示例:一个错误处理不完备的函数
|
||
bool load_config_file(const char* path) {
|
||
FILE* fp = fopen(path, "r");
|
||
// 风险1:未检查 fopen 的返回值
|
||
|
||
char buffer[1024];
|
||
size_t read_bytes = fread(buffer, 1, 1024, fp);
|
||
// 风险2:未检查 fread 的返回值 (是否读到预期大小)
|
||
|
||
if (read_bytes > 0) {
|
||
// ... (process buffer) ...
|
||
}
|
||
|
||
// 风险3:未在所有路径(如此处)调用 fclose(fp)
|
||
|
||
return true; // 风险4:无论成功失败,永远返回 true
|
||
}
|
||
|
||
== 审查要求 ==
|
||
请识别此函数中所有缺失或不正确的错误处理路径:
|
||
1. 资源分配/打开: 是否正确检查了(如 fopen, malloc, new)的返回值(如 nullptr)?
|
||
2. 外部调用: 是否正确检查了(如 fread, send, external_api())的返回值或错误码?
|
||
3. 资源释放 (RAII): 是否确保资源(如 FILE*, 内存)在函数的所有出口(包括错误出口)都被正确释放(无泄漏)?
|
||
4. 函数返回值: 函数的返回值是否能准确反映其执行结果(成功/失败)?
|
||
|
||
== 输出要求 ==
|
||
请逐条列出发现的“错误处理缺陷”及其“修复建议”。
|
||
- [缺陷 1]: (例如:未检查 fopen 返回值)
|
||
- [风险]: (如果 path 不存在,fp 为 NULL,后续 fread 将导致段错误)
|
||
- [修复建议]: (例如:if (fp == nullptr) { return false; })
|
||
-----
|
||
- [缺陷 2]: ...
|
||
```
|
||
|
||
**填充指南:**
|
||
|
||
- `[待审查的函数]`:提供代码。
|
||
- **使用指南:** 此模板对于审查与C库(需要手动资源管理)或网络(总会失败)交互的代码至关重要。
|
||
|
||
<a id="C11"></a>
|
||
|
||
-----
|
||
|
||
**模板名称:** `C11: 安全漏洞专项审查`
|
||
**适用场景:** 在代码提交前进行安全左移(Shift-Left Security)。用于审查代码是否存在C/C++中常见(且高风险)的安全漏洞。
|
||
**内嵌原则:** `[原则八:自我批判]` (AI扮演安全专家), `[原则五:上下文即燃料]` (输入代码), `[原则七:结构化输出]` (输出漏洞报告)。
|
||
|
||
**[Prompt 模板]**
|
||
|
||
```txt
|
||
角色:你是一名C/C++应用安全专家(AppSec),精通CWE和OWASP Top 10。
|
||
|
||
任务:请严格审查以下C/C++代码,查找常见的安全漏洞。
|
||
|
||
== 待审查的代码 ==
|
||
[粘贴你的C/C++代码片段,特别是处理用户输入、文件或网络数据的部分]
|
||
// 示例:包含多个漏洞的代码
|
||
void handle_user_request(const char* user_input, int user_id) {
|
||
// 漏洞1:缓冲区溢出
|
||
char buffer[100];
|
||
strcpy(buffer, user_input);
|
||
|
||
// 漏洞2:格式化字符串
|
||
printf(buffer);
|
||
|
||
// 漏洞3:SQL注入 (示例)
|
||
std::string query = "SELECT * FROM users WHERE id = " + std::to_string(user_id);
|
||
// ... (execute query) ...
|
||
}
|
||
|
||
== 审查重点 (CWE) ==
|
||
请重点关注(但不限于)以下高风险漏洞:
|
||
1. 缓冲区溢出 (Buffer Overflow): (例如:strcpy, sprintf, gets)
|
||
2. 格式化字符串 (Format String): (例如:printf(user_input))
|
||
3. 整数溢出 (Integer Overflow): (例如:int size = len1 + len2;)
|
||
4. SQL注入 (SQL Injection): (如果代码涉及构建SQL查询)
|
||
5. 命令注入 (Command Injection): (如果代码涉及调用 system() 或 popen())
|
||
|
||
== 输出要求 ==
|
||
请按照CWE(通用缺陷枚举)的格式,逐条列出发现的漏洞:
|
||
- [漏洞 1]: (例如:CWE-120: 缓冲区溢出)
|
||
- [位置]: (例如:strcpy(buffer, user_input);)
|
||
- [风险]: (例如:user_input 可能长于100字节,导致栈溢出,可能允许远程代码执行)
|
||
- [修复建议]: (例如:使用 strncpy 或更好的 std::string)
|
||
-----
|
||
- [漏洞 2]: ...
|
||
```
|
||
|
||
**填充指南:**
|
||
|
||
- `[待审查的代码]`:提供代码,尤其是处理“不可信输入”的代码。
|
||
- **使用指南:** AI是出色的模式匹配器,非常擅长发现这类有明显“特征”(如`strcpy`)的安全漏洞。
|
||
|
||
-----
|
||
|
||
**子类别 C-4: 迭代与代码评审 (Iteration & Feedback)**
|
||
|
||
<a id="C12"></a>
|
||
|
||
-----
|
||
|
||
**模板名称:** `C12: 方案的自我批判`
|
||
**适用场景:** `原则五:自我批判` 的通用实现。用于对抗AI的“惰性实现”(痛点6)和“上下文惯性”(痛点1)。在你(或AI)给出一个初步方案后,强制AI切换角色,对该方案进行压力测试。
|
||
**内嵌原则:** `[原则五:自我批判]` (核心), `[原则一:敏捷提示]` (迭代式求精)。
|
||
|
||
**[Prompt 模板]**
|
||
|
||
```txt
|
||
角色:(情景切换) 很好,你刚才提供的 [方案/代码] 是一个不错的初稿。
|
||
现在,请你完全忘记你“乐于助人”的助手角色。
|
||
|
||
新角色:你是一名资深的、吹毛求疵的、且极其注重“健壮性”和“性能”的首席架构评审专家。
|
||
|
||
任务:请严格审查你刚才提供的 [方案/代码],找出其中至少 [数量,例如:3] 个潜在的设计缺陷、性能陷阱、隐藏的假设或未处理的边界条件。
|
||
|
||
== 交付要求 ==
|
||
请逐条列出:
|
||
1. [缺陷 1]: (例如:并发不安全)
|
||
2. [分析]: (例如:你提供的方案在多线程环境下存在竞态条件...)
|
||
3. [改进建议]: (例如:应使用 std::mutex...)
|
||
-----
|
||
1. [缺陷 2]: (例如:性能陷阱)
|
||
2. [分析]: (例如:在循环内部分配内存...)
|
||
3. [改进建议]: (例如:应在循环外预分配...)
|
||
```
|
||
|
||
**填充指南:**
|
||
|
||
- **使用指南:** 这是一个“对话式”模板,在你对AI的(或你自己的)上一个回答不完全满意时使用。
|
||
- `[方案/代码]`:替换为你正在讨论的主题,如 “API设计”、“CUDA Kernel实现”。
|
||
- `[数量]`:指定一个具体数字,可以迫使AI更深入地思考。
|
||
|
||
<a id="C13"></a>
|
||
|
||
-----
|
||
|
||
**模板名称:** `C13: 代码可读性与规范性评审`
|
||
**适用场景:** 自动化Code Review中关于“代码风格”的重复性劳动(痛点3)。用于确保代码符合团队规范,提高可读性和可维护性。
|
||
**内嵌原则:** `[原则六:示例优先]` (可选:提供规范), `[原则七:结构化输出]` (输出评审意见)。
|
||
|
||
**[Prompt 模板]**
|
||
|
||
```txt
|
||
角色:你是一名资深的C++工程师,是 [团队/规范,例如:Google C++ Style Guide] 的坚定执行者。
|
||
|
||
任务:请审查以下代码的“可读性”、“可维护性”和“代码风格”。
|
||
|
||
== 待审查的代码 ==
|
||
[粘贴你需要评审的代码片段,例如:命名不规范、函数过长的代码]
|
||
// 示例:风格糟糕的代码
|
||
#include <vector>
|
||
// 全局变量
|
||
std::vector<int> g_vec;
|
||
|
||
// 命名模糊,函数名大写
|
||
bool Process(int x, int y) {
|
||
if (x > y) { // 魔法数字
|
||
int temp = x; // 变量名无意义
|
||
x = y;
|
||
y = temp;
|
||
}
|
||
// ... (省略了50行其他逻辑) ...
|
||
g_vec.push_back(y); // 依赖全局状态
|
||
return true;
|
||
}
|
||
|
||
== 审查重点 ==
|
||
1. 命名规范: (例如:变量名、函数名、类名是否清晰且符合 [规范]?)
|
||
2. 函数长度/职责: (例如:函数是否过长?是否违反了“单一职责原则”?)
|
||
3. 注释: (例如:注释是否缺失?是否注释了“Why”?)
|
||
4. 复杂度: (例如:是否存在过深的嵌套(if/for)?)
|
||
5. 反模式: (例如:是否使用了“魔法数字”?是否滥用全局变量?)
|
||
|
||
== (可选) 我们的风格规范 (示例优先) ==
|
||
- [例如:函数命名使用 lower_snake_case()]
|
||
- [例如:成员变量使用 m_suffix_]
|
||
- [例如:严禁使用全局变量]
|
||
|
||
== 输出要求 ==
|
||
请逐条返回“风格问题”和“重构建议”。
|
||
- [问题 1]: (例如:违反命名规范)
|
||
- [建议]: (例如:函数 Process 应改为 process_data。变量 temp 应改为 lower_bound。)
|
||
-----
|
||
- [问题 2]: (例如:滥用全局变量)
|
||
- [建议]: (例如:g_vec 应作为参数传入或作为类成员,移除全局状态。)
|
||
-----
|
||
- [问题 3]: ...
|
||
```
|
||
|
||
**填充指南:**
|
||
|
||
- `[团队/规范]`:明确告知AI应遵循的风格,如 `Google Style`, `LLVM Style`。
|
||
- `[我们的风格规范]`:**强烈推荐**。通过 `原则六:示例优先` 提供你团队的具体规范,AI的评审会精确得多。
|