Logic Analyzer Skill - 代码逻辑变更分析
技能概述
本技能专注于深度分析代码修改的逻辑影响,系统化地发现所有逻辑问题。不同于常规的代码审查,本技能重点关注:
- 逻辑影响范围分析:修改会影响哪些代码路径和数据流
- 逻辑一致性检查:发现逻辑矛盾、不一致和缺陷
- 状态转换验证:验证状态机转换的正确性
- 边界条件分析:发现边界条件处理不当的问题
- 业务规则验证:确保业务逻辑规则的正确性
1. 分析框架
1.1 三层分析模型
┌─────────────────────────────────────────────────┐
│ 第一层:变更识别 (What Changed) │
│ - 识别变更的代码位置 │
│ - 分类变更类型(新增/修改/删除) │
│ - 识别变更的影响范围 │
├─────────────────────────────────────────────────┤
│ 第二层:逻辑分析 (Logic Analysis) │
│ - 控制流分析 │
│ - 数据流分析 │
│ - 状态机分析 │
│ - 约束条件分析 │
├─────────────────────────────────────────────────┤
│ 第三层:影响评估 (Impact Assessment) │
│ - 影响范围评估 │
│ - 风险等级评定 │
│ - 修复建议生成 │
└─────────────────────────────────────────────────┘
1.2 分析维度
| 维度 | 检查内容 | 问题类型 |
|---|---|---|
| 控制流 | 分支、循环、条件判断 | 死代码、不可达代码、逻辑矛盾 |
| 数据流 | 变量定义、赋值、使用 | 未初始化、数据污染、类型不匹配 |
| 状态机 | 状态转换、转换条件 | 非法转换、状态不一致、死锁 |
| 边界条件 | 数组边界、空值、极值 | 越界、空指针、溢出 |
| 错误处理 | 错误码、异常、清理 | 遗漏错误路径、资源泄漏 |
| 并发控制 | 锁、原子操作、竞态 | 死锁、竞态条件、数据竞争 |
| 业务规则 | 约束、不变性、契约 | 规则违反、不变性破坏 |
2. 变更识别与分类
2.1 变更类型分类
#### 类型 1: 控制流变更
+ if (newCondition) { // 新增条件分支
doSomething();
}
#### 类型 2: 数据流变更
- int result = processA(); // 删除原有计算
+ int result = processB(); // 替换为新计算
#### 类型 3: 状态转换变更
- state = ACTIVE; // 修改状态转换目标
+ state = SUSPENDED;
#### 类型 4: 函数签名变更
- ErrCode Function(int id);
+ ErrCode Function(int id, Config config); // 新增参数
#### 类型 5: 错误处理变更
ret = DoSomething();
+ if (ret != ERR_OK) { // 新增错误处理
return ret;
+ }
2.2 影响范围识别
直接影响的代码:
- 被修改的函数及其调用者
- 被修改的成员变量及其访问者
- 被修改的状态及其转换逻辑
间接影响的代码:
- 依赖修改函数返回值的代码
- 依赖修改状态的条件分支
- 调用链上的所有上层函数
可能影响的边界:
- 接口兼容性边界
- 性能边界
- 资源使用边界
- 并发安全边界
3. 逻辑问题检测模式
3.1 控制流问题
问题 1: 死代码 (Dead Code)
检测模式:
// ❌ 问题:永不为真的条件
if (constexpr_condition) { // constexpr_value 总是 false
// 这段代码永远不会执行
NeverExecuted();
}
// ❌ 问题:不可达的代码
return ERR_OK;
DoSomething(); // 永远不会执行
// ❌ 问题:重复的条件
if (condition) {
return A;
} else {
if (condition) { // 重复的条件
return B;
}
}
检测方法:
- 分析条件表达式的常量性
- 构建控制流图(CFG)检测不可达节点
- 检查return/break后的代码
影响分析:
- 代码维护性降低
- 可能隐藏未测试的逻辑
- 造成代码混淆
问题 2: 逻辑矛盾 (Logic Contradiction)
检测模式:
// ❌ 问题:互斥条件同时为真
if (x > 10 && x < 5) { // 永远不会为真
Impossible();
}
// ❌ 问题:冗余条件
if (value != nullptr) {
if (value != nullptr) { // 重复检查
use(value);
}
}
// ❌ 问题:条件覆盖矛盾
if (state == ACTIVE) {
return;
}
if (state == ACTIVE) { // 前面已经return,这里永远不会执行
doSomething();
}
检测方法:
- 使用SMT求解器验证条件可满足性
- 数据流分析追踪变量约束
- 符号执行验证路径可行性
问题 3: 条件覆盖不完整 (Incomplete Condition Coverage)
检测模式:
// ❌ 问题:遗漏分支
enum State { ACTIVE, INACTIVE, SUSPENDED };
void HandleState(State state) {
if (state == ACTIVE) {
HandleActive();
} else if (state == INACTIVE) {
HandleInactive();
}
// 遗漏了 SUSPENDED 状态的处理!
}
// ❌ 问题:默认情况缺失
switch (type) {
case TYPE_A:
DoA();
break;
case TYPE_B:
DoB();
break;
// 缺少 default 分支!
}
// ✅ 正确:完整的条件覆盖
void HandleState(State state) {
if (state == ACTIVE) {
HandleActive();
} else if (state == INACTIVE) {
HandleInactive();
} else {
HILOG_ERROR("Unknown state: %{public}d", state);
HandleUnknown();
}
}
检测方法:
- 枚举类型完整性检查
- switch-case分支完整性检查
- if-else链完整性检查
3.2 数据流问题
问题 1: 未初始化变量 (Uninitialized Variable)
检测模式:
// ❌ 问题:使用未初始化的变量
int result;
if (condition) {
result = 10;
}
// 如果condition为false,result未初始化
return result; // 使用未初始化的值
// ❌ 问题:条件初始化
std::string data;
if (needData) {
data = GetData();
}
// 如果needData为false,data为空
ProcessData(data); // 可能处理空数据
// ✅ 正确:确保初始化
int result = DEFAULT_VALUE; // 默认值
if (condition) {
result = 10;
}
return result;
检测方法:
- 数据流分析追踪变量定义-使用链
- 检查所有可能路径的初始化
- 验证构造函数中的成员初始化列表
问题 2: 数据污染 (Data Tainting)
检测模式:
// ❌ 问题:外部数据未验证直接使用
void ProcessInput(const char* input) {
char buffer[100];
strcpy(buffer, input); // 危险:input可能超过100字节
ProcessBuffer(buffer);
}
// ❌ 问题:污染数据传播到敏感操作
void ExecuteCommand(const std::string& userCmd) {
std::string cmd = "sh -c '" + userCmd + "'"; // 危险:命令注入
system(cmd.c_str());
}
// ✅ 正确:验证和净化外部数据
void ProcessInput(const char* input) {
if (input == nullptr || strlen(input) >= 100) {
HILOG_ERROR("Invalid input");
return;
}
char buffer[100];
strncpy_s(buffer, sizeof(buffer), input, sizeof(buffer) - 1);
buffer[sizeof(buffer) - 1] = '\0';
ProcessBuffer(buffer);
}
检测方法:
- 污点分析(taint analysis)追踪外部数据
- 识别敏感操作(sink points):系统调用、文件操作、SQL执行
- 验证数据净化点(sanitization)
问题 3: 类型不匹配 (Type Mismatch)
检测模式:
// ❌ 问题:有符号/无符号比较
int count = -1;
if (count < vector.size()) { // 危险:有符号与无符号比较
vector[count];
}
// ❌ 问题:枚举类型混用
enum Type { A = 0, B = 1 };
int value = 2;
Type type = static_cast<Type>(value); // 危险:无有效枚举值
// ❌ 问题:指针类型强转
void* ptr = malloc(100);
int* intPtr = static_cast<int*>(ptr);
*intPtr = 0x12345678; // 可能未对齐
// ✅ 正确:类型安全比较
size_t count = 0;
if (count < vector.size()) {
// 安全
}
检测方法:
- 类型推导和约束检查
- 检查隐式类型转换
- 验证枚举值的有效性
3.3 状态机问题
问题 1: 非法状态转换 (Illegal State Transition)
检测模式:
// ❌ 问题:不合法的状态转换
enum State { CREATED, ACTIVATING, ACTIVE, DEACTIVATING };
void ChangeState(State newState) {
// 允许任何转换,包括非法的
currentState_ = newState;
}
// 示例非法转换:
// CREATED -> DEACTIVATING (跳过ACTIVATING和ACTIVE)
// ACTIVE -> CREATED (跳过DEACTIVATING)
// ✅ 正确:验证状态转换
bool ChangeState(State newState) {
switch (currentState_) {
case CREATED:
if (newState != ACTIVATING) {
HILOG_ERROR("Invalid transition: CREATED -> %{public}d", newState);
return false;
}
break;
case ACTIVATING:
if (newState != ACTIVE && newState != CREATED) {
return false;
}
break;
// ... 其他状态验证
}
currentState_ = newState;
return true;
}
检测方法:
- 构建状态转换图
- 验证所有转换的合法性
- 检查是否遗漏中间状态
问题 2: 状态不一致 (State Inconsistency)
检测模式:
// ❌ 问题:状态与实际数据不一致
class Account {
State state_;
bool isActive_;
void Activate() {
state_ = ACTIVE;
// 忘记更新 isActive_
}
bool IsActive() {
return isActive_; // 返回旧值
}
};
// ❌ 问题:多状态变量不同步
class Connection {
bool isConnected_;
bool isReady_;
bool hasError_;
void Connect() {
isConnected_ = true;
// isReady_ 未更新,导致不一致
}
};
// ✅ 正确:确保状态一致性
class Account {
State state_;
void Activate() {
state_ = ACTIVE;
// 单一状态源,无需同步多个变量
}
bool IsActive() {
return state_ == ACTIVE;
}
};
检测方法:
- 识别所有表示状态的相关变量
- 验证状态更新时的一致性
- 检查状态读取点的一致性
问题 3: 状态机死锁 (State Machine Deadlock)
检测模式:
// ❌ 问题:无法到达最终状态
enum State { INIT, WAITING, PROCESSING, DONE };
void ProcessData() {
switch (state_) {
case INIT:
state_ = WAITING;
break;
case WAITING:
if (HasData()) {
state_ = PROCESSING;
}
// 如果没有数据,永远停留在WAITING
break;
case PROCESSING:
if (Success()) {
state_ = DONE;
} else {
state_ = WAITING; // 失败后回到WAITING
}
break;
}
// 没有超时机制,可能永远无法到达DONE
}
// ✅ 正确:添加超时和错误处理
void ProcessData() {
switch (state_) {
case INIT:
state_ = WAITING;
startTime_ = GetCurrentTime();
break;
case WAITING:
if (HasData()) {
state_ = PROCESSING;
} else if (GetCurrentTime() - startTime_ > TIMEOUT) {
state_ = DONE; // 超时退出
errorCode_ = ETIMEDOUT;
}
break;
// ...
}
}
检测方法:
- 构建状态转换图并检查强连通分量
- 验证是否存在无法到达终态的循环
- 检查超时和错误恢复机制
3.4 边界条件问题
问题 1: 数组越界 (Array Out of Bounds)
检测模式:
// ❌ 问题:索引未验证
void ProcessArray(int* data, int size) {
for (int i = 0; i <= size; i++) { // 错误:应该是 i < size
data[i] = 0; // 越界访问
}
}
// ❌ 问题:边界计算错误
void CopyData(const std::vector<int>& src, int* dest, int destSize) {
memcpy(dest, src.data(), src.size() * sizeof(int)); // 未检查destSize
}
// ✅ 正确:边界验证
void ProcessArray(int* data, int size) {
if (data == nullptr || size <= 0) {
return;
}
for (int i = 0; i < size; i++) {
data[i] = 0;
}
}
void CopyData(const std::vector<int>& src, int* dest, int destSize) {
if (dest == nullptr || destSize < static_cast<int>(src.size())) {
HILOG_ERROR("Invalid buffer size");
return;
}
memcpy(dest, src.data(), src.size() * sizeof(int));
}
检测方法:
- 符号执行验证数组访问的边界
- 检查循环边界条件
- 验证memcpy/strcpy等函数的长度参数
问题 2: 空指针解引用 (Null Pointer Dereference)
检测模式:
// ❌ 问题:未检查空指针
void ProcessData(Account* account) {
account->Update(); // account可能为nullptr
}
// ❌ 问题:检查后再次使用
void Process(Account* account) {
if (account != nullptr) {
DoSomething(account);
}
account->Update(); // 可能已经是nullptr
}
// ❌ 问题:函数调用后未验证返回值
Account* GetAccount(int id);
void UseAccount(int id) {
Account* account = GetAccount(id);
account->Process(); // GetAccount可能返回nullptr
}
// ✅ 正确:完整的空指针检查
void ProcessData(Account* account) {
if (account == nullptr) {
HILOG_ERROR("Account is null");
return;
}
account->Update();
}
void UseAccount(int id) {
Account* account = GetAccount(id);
if (account == nullptr) {
HILOG_ERROR("Account not found: %{public}d", id);
return;
}
account->Process();
}
检测方法:
- 数据流分析追踪指针的空值状态
- 识别所有解引用点
- 验证解引用前的空值检查
问题 3: 整数溢出 (Integer Overflow)
检测模式:
// ❌ 问题:加法溢出
int AllocateSize(int count, int itemSize) {
return count * itemSize; // 可能溢出
}
// ❌ 问题:索引计算溢出
void AccessArray(std::vector<int>& data, int offset, int index) {
int pos = offset + index; // 可能溢出为负数
data[pos] = 0; // 负数转换为巨大的无符号数
}
// ❌ 问题:循环计数器溢出
for (int i = 0; i < count; i++) {
// 如果count是INT_MAX,i会溢出
ProcessItem(i);
}
// ✅ 正确:溢出检查
int AllocateSize(int count, int itemSize) {
if (count < 0 || itemSize < 0) {
return -1;
}
if (count > INT_MAX / itemSize) {
HILOG_ERROR("Size overflow");
return -1;
}
return count * itemSize;
}
检测方法:
- 识别所有算术运算
- 使用边界值分析方法
- 检查溢出前的条件验证
3.5 错误处理问题
问题 1: 遗漏错误路径 (Missing Error Path)
检测模式:
// ❌ 问题:不检查返回值
void ProcessFile(const std::string& path) {
FILE* file = fopen(path.c_str(), "r"); // 未检查是否成功
char buffer[100];
fread(buffer, 1, 100, file); // file可能是nullptr
fclose(file);
}
// ❌ 问题:部分错误处理
ErrCode CreateAccount(const AccountInfo& info) {
if (!ValidateInfo(info)) {
return ERR_INVALID;
}
// 未检查数据库写入是否成功
database_->Insert(info);
// 未检查文件写入是否成功
WriteToFile(info);
return ERR_OK;
}
// ✅ 正确:完整的错误处理
ErrCode CreateAccount(const AccountInfo& info) {
if (!ValidateInfo(info)) {
return ERR_INVALID;
}
ErrCode ret = database_->Insert(info);
if (ret != ERR_OK) {
HILOG_ERROR("Database insert failed: %{public}d", ret);
return ret;
}
ret = WriteToFile(info);
if (ret != ERR_OK) {
HILOG_ERROR("File write failed: %{public}d", ret);
// 回滚数据库操作
database_->Delete(info.id);
return ret;
}
return ERR_OK;
}
检测方法:
- 识别所有可能失败的函数调用
- 检查调用点是否有错误处理
- 验证错误处理的完整性
问题 2: 资源泄漏 (Resource Leak)
检测模式:
// ❌ 问题:错误路径未释放资源
void ProcessData() {
char* buffer = new char[1024];
if (!ReadData(buffer)) {
return; // 泄漏buffer
}
delete[] buffer;
}
// ❌ 问题:文件句柄泄漏
void ProcessFile(const std::string& path) {
FILE* file = fopen(path.c_str(), "r");
if (file == nullptr) {
return;
}
char buffer[100];
if (fread(buffer, 1, 100, file) < 100) {
return; // 泄漏file句柄
}
fclose(file);
}
// ✅ 正确:使用RAII确保资源释放
void ProcessData() {
std::unique_ptr<char[]> buffer(new char[1024]);
if (!ReadData(buffer.get())) {
return; // 自动释放
}
}
void ProcessFile(const std::string& path) {
FILE* file = fopen(path.c_str(), "r");
if (file == nullptr) {
return;
}
// 使用RAII包装器
std::unique_ptr<FILE, decltype(&fclose)> fileGuard(file, fclose);
char buffer[100];
if (fread(buffer, 1, 100, file) < 100) {
return; // 自动关闭文件
}
}
检测方法:
- 识别所有资源分配点(malloc、new、fopen等)
- 构建控制流图检查所有可能的退出路径
- 验证每个退出路径是否释放资源
3.6 并发控制问题
问题 1: 死锁 (Deadlock)
检测模式:
// ❌ 问题:锁顺序不一致
void Thread1() {
std::lock_guard<std::mutex> lock1(mutex1_);
std::lock_guard<std::mutex> lock2(mutex2_);
// 操作
}
void Thread2() {
std::lock_guard<std::mutex> lock2(mutex2_); // 不同顺序
std::lock_guard<std::mutex> lock1(mutex1_);
// 可能死锁
}
// ❌ 问题:循环等待
void Process() {
std::lock_guard<std::mutex> lock(globalMutex_);
// 在持有锁的情况下调用可能获取同一锁的函数
Callback(); // 如果Callback也尝试获取globalMutex_,死锁
}
// ✅ 正确:一致的锁顺序
void Thread1() {
std::lock(mutex1_, mutex2_); // C++17 std::lock
std::lock_guard<std::mutex> lock1(mutex1_, std::adopt_lock);
std::lock_guard<std::mutex> lock2(mutex2_, std::adopt_lock);
// 操作
}
void Thread2() {
std::lock(mutex1_, mutex2_); // 相同顺序
std::lock_guard<std::mutex> lock1(mutex1_, std::adopt_lock);
std::lock_guard<std::mutex> lock2(mutex2_, std::adopt_lock);
// 操作
}
检测方法:
- 构建锁依赖图
- 检查是否存在循环依赖
- 验证锁顺序的一致性
问题 2: 竞态条件 (Race Condition)
检测模式:
// ❌ 问题:检查-使用(Check-Then-Act)模式
if (instance_ == nullptr) { // 检查
instance_ = new Instance(); // 使用:多个线程可能同时执行
}
// ❌ 问题:非原子操作
int count_;
void Increment() {
count_++; // 非原子操作,三个步骤:读取、增加、写入
}
// ❌ 问题:状态不一致读取
class Account {
int balance_;
void Deposit(int amount) {
balance_ += amount;
}
int GetBalance() {
return balance_; // 可能读到部分更新的值
}
};
// ✅ 正确:使用原子操作或锁
std::atomic<int> count_;
void Increment() {
count_.fetch_add(1, std::memory_order_relaxed);
}
// 或使用锁
std::mutex mutex_;
int count_;
void Increment() {
std::lock_guard<std::mutex> lock(mutex_);
count_++;
}
检测方法:
- 识别共享变量的访问点
- 检查是否有适当的同步机制
- 验证操作的原子性
问题 3: 数据竞争 (Data Race)
检测模式:
// ❌ 问题:无保护的并发访问
int sharedData = 0;
void Thread1() {
sharedData = 100; // 写入,无保护
}
void Thread2() {
int value = sharedData; // 读取,无保护
// 数据竞争:未定义行为
}
// ❌ 问题:部分保护的访问
class Buffer {
std::mutex mutex_;
std::vector<int> data_;
void Add(int value) {
std::lock_guard<std::mutex> lock(mutex_);
data_.push_back(value);
}
int Size() {
return data_.size(); // 无保护读取
}
};
// ✅ 正确:完全保护的访问
class Buffer {
std::mutex mutex_;
std::vector<int> data_;
void Add(int value) {
std::lock_guard<std::mutex> lock(mutex_);
data_.push_back(value);
}
int Size() {
std::lock_guard<std::mutex> lock(mutex_);
return data_.size();
}
};
检测方法:
- 数据流分析识别共享变量
- 检查所有访问点的同步状态
- 验证内存序(Memory Order)的正确性
3.7 业务规则违反
问题 1: 不变性破坏 (Invariant Violation)
检测模式:
// ❌ 问题:破坏不变性
class AccountManager {
std::map<int, Account> accounts_;
int maxAccounts_; // 不变性:accounts_.size() <= maxAccounts_
ErrCode AddAccount(const Account& account) {
accounts_[account.id] = account;
// 未检查是否超过maxAccounts_
return ERR_OK;
}
};
// ❌ 问题:约束条件违反
class PriorityQueue {
std::vector<int> data_;
void Add(int value) {
data_.push_back(value);
// 忘记调整堆结构,破坏堆性质
}
};
// ✅ 正确:维护不变性
class AccountManager {
std::map<int, Account> accounts_;
int maxAccounts_;
ErrCode AddAccount(const Account& account) {
if (accounts_.size() >= maxAccounts_) {
HILOG_ERROR("Max accounts limit reached");
return ERR_LIMIT_REACHED;
}
accounts_[account.id] = account;
return ERR_OK;
}
};
检测方法:
- 识别类/模块的不变性
- 检查每个操作后是否保持不变性
- 验证构造函数是否建立不变性
问题 2: 契约违反 (Contract Violation)
检测模式:
// ❌ 问题:前置条件未验证
int Divide(int a, int b) {
// 前置条件:b != 0
return a / b; // 未验证前置条件
}
// ❌ 问题:后置条件不保证
int GetNextId() {
int nextId = currentId_++;
// 后置条件:返回的ID应该是唯一的
// 但如果currentId_溢出,可能返回已使用的ID
return nextId;
}
// ✅ 正确:契约式编程
int Divide(int a, int b) {
if (b == 0) {
HILOG_ERROR("Division by zero");
return 0; // 或抛出异常
}
return a / b;
}
int GetNextId() {
int nextId = currentId_;
if (currentId_ == INT_MAX) {
HILOG_ERROR("ID overflow");
return -1;
}
currentId_++;
return nextId;
}
检测方法:
- 识别函数的前置/后置条件
- 检查前置条件验证
- 验证后置条件保证
4. 分析检查清单
4.1 控制流检查清单
-
死代码检测
- 识别永不为真的条件
- 检测不可达的代码段
- 验证return/break后的代码
-
逻辑矛盾检测
- 检查互斥条件
- 识别冗余条件
- 验证条件覆盖
-
条件覆盖完整性
- 枚举类型完整性
- switch-case分支完整性
- if-else链完整性
4.2 数据流检查清单
-
变量初始化
- 所有路径上的初始化
- 成员变量初始化
- 数组/容器初始化
-
数据污染分析
- 外部数据来源识别
- 数据净化点验证
- 敏感操作保护
-
类型安全
- 有符号/无符号比较
- 枚举值有效性
- 指针类型转换
4.3 状态机检查清单
-
状态转换合法性
- 验证每个转换的合法性
- 检查非法转换
- 确认中间状态
-
状态一致性
- 单一状态源
- 相关状态变量同步
- 状态读取一致性
-
状态机活性
- 可达性分析
- 终态可达性
- 超时机制
4.4 边界条件检查清单
-
数组边界
- 索引范围验证
- 循环边界检查
- 缓冲区大小验证
-
空指针检查
- 解引用前验证
- 函数返回值验证
- 智能指针使用
-
整数溢出
- 算术运算验证
- 边界值检查
- 溢出保护
4.5 错误处理检查清单
-
错误路径完整性
- 所有可能失败的操作
- 错误码传递
- 错误日志记录
-
资源管理
- 资源释放配对
- 错误路径释放
- RAII使用
4.6 并发控制检查清单
-
死锁预防
- 锁顺序一致性
- 循环等待检测
- 超时机制
-
竞态条件
- 共享变量保护
- 原子操作
- 同步机制
-
数据竞争
- 访问同步
- 内存序验证
- 读写锁使用
4.7 业务规则检查清单
-
不变性维护
- 识别不变性
- 验证操作后不变性
- 构造函数建立
-
契约遵守
- 前置条件验证
- 后置条件保证
- 异常安全性
5. 分析报告模板
5.1 报告结构
# 代码逻辑变更分析报告
## 1. 变更概览
### 变更文件
- `src/account_manager.cpp`: 45 行变更
- `include/account_manager.h`: 3 行变更
### 变更类型
- 控制流变更: 2 处
- 数据流变更: 1 处
- 状态转换变更: 1 处
### 影响范围评估
- 直接影响: AccountManager类及其3个调用者
- 间接影响: 可能影响所有依赖账户状态的模块
- 风险等级: **高** ⚠️
---
## 2. 逻辑问题详细分析
### 问题 1: 状态转换非法 (致命)
**位置**: `src/account_manager.cpp:123-127`
**问题描述**:
从CREATED状态直接转换到DEACTIVATED状态,跳过了ACTIVE状态。
**当前代码**:
```cpp
ErrCode AccountManager::DeactivateAccount(int id) {
accounts_[id].state_ = DEACTIVATED; // 非法转换
return ERR_OK;
}
影响:
- 破坏状态机完整性
- 可能导致后续操作异常
- 账户数据不一致
修复建议:
ErrCode AccountManager::DeactivateAccount(int id) {
if (accounts_[id].state_ != ACTIVE) {
HILOG_ERROR("Cannot deactivate non-active account");
return ERR_INVALID_STATE;
}
accounts_[id].state_ = DEACTIVATED;
return ERR_OK;
}
严重等级: 🔴 致命
问题 2: 错误路径遗漏 (严重)
位置: src/account_manager.cpp:145-152
问题描述: CreateAccount函数未检查数据库插入是否成功。
当前代码:
ErrCode AccountManager::CreateAccount(const AccountInfo& info) {
if (!ValidateInfo(info)) {
return ERR_INVALID;
}
database_->Insert(info); // 未检查返回值
WriteToFile(info);
return ERR_OK;
}
影响:
- 数据库失败时状态不一致
- 文件已写入但数据库未记录
- 数据恢复困难
修复建议:
ErrCode AccountManager::CreateAccount(const AccountInfo& info) {
if (!ValidateInfo(info)) {
return ERR_INVALID;
}
ErrCode ret = database_->Insert(info);
if (ret != ERR_OK) {
HILOG_ERROR("Database insert failed: %{public}d", ret);
return ret;
}
ret = WriteToFile(info);
if (ret != ERR_OK) {
HILOG_ERROR("File write failed: %{public}d", ret);
database_->Delete(info.id); // 回滚
return ret;
}
return ERR_OK;
}
严重等级: 🟠 严重
问题 3: 竞态条件 (严重)
位置: src/account_manager.cpp:89-93
问题描述: Check-Then-Act模式导致竞态条件。
当前代码:
bool AccountManager::HasAccount(int id) {
if (accounts_.find(id) == accounts_.end()) {
return false;
}
return true;
}
影响:
- 多线程环境下结果不准确
- 可能导致重复创建账户
修复建议:
bool AccountManager::HasAccount(int id) {
std::lock_guard<std::mutex> lock(mutex_);
return accounts_.find(id) != accounts_.end();
}
严重等级: 🟠 严重
3. 影响分析
直接影响
AccountManager::DeactivateAccount(): 行为改变AccountManager::CreateAccount(): 错误处理不完整AccountManager::HasAccount(): 线程不安全
间接影响
- 所有调用
HasAccount()的代码可能受影响 - 依赖账户状态的下游模块
- 可能触发数据不一致问题
风险评估
- 数据一致性: 高风险 🔴
- 线程安全: 高风险 🔴
- 状态机完整性: 高风险 🔴
4. 修复优先级
必须修复 (阻塞上库)
- 问题1: 状态转换非法
- 问题2: 错误路径遗漏
- 问题3: 竞态条件
应该修复 (建议)
- 添加单元测试覆盖边界条件
- 增加日志记录便于调试
可以考虑 (优化)
- 重构状态机使用状态模式
- 引入契约式编程库
5. 总结
本次代码变更引入了3个严重的逻辑问题,主要涉及:
- 状态机完整性
- 错误处理完整性
- 并发安全性
建议: 修复所有致命和严重问题后再合并到主分支。
风险等级: 🔴 高风险
总体评价: ❌ 需要修复
---
## 6. 使用指南
### 6.1 调用技能
```bash
# 分析特定分支的代码变更
claude-code "使用logic_analyzer技能分析分支feature-xxx相对于main的代码逻辑变更"
# 分析特定文件的变更
claude-code "使用logic_analyzer技能分析src/account_manager.cpp文件的逻辑变更"
# 分析特定问题类型
claude-code "使用logic_analyzer技能检查状态机相关的逻辑问题"
6.2 分析流程
1. 识别变更
├─ 获取变更文件列表
├─ 分类变更类型
└─ 识别影响范围
2. 执行分析
├─ 控制流分析
├─ 数据流分析
├─ 状态机分析
├─ 边界条件分析
├─ 错误处理分析
├─ 并发控制分析
└─ 业务规则分析
3. 生成报告
├─ 问题发现与分类
├─ 影响分析
├─ 风险评估
└─ 修复建议
7. 版本历史
| 版本 | 日期 | 变更 | 维护者 |
|---|---|---|---|
| v1.0 | 2026-04-01 | 初始版本,完整的逻辑分析框架 | AI Assistant |
文档结束