@ohos-graphics/stability-code-review 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (70) hide show
  1. package/README.md +169 -0
  2. package/SKILL.md +518 -0
  3. package/bin/install.js +165 -0
  4. package/config/rules.yaml +445 -0
  5. package/config/whitelist.yaml +52 -0
  6. package/package.json +40 -0
  7. package/references/BoundaryCondition/StabilityCodeReview_BoundaryCondition_001.md +275 -0
  8. package/references/BoundaryCondition/StabilityCodeReview_BoundaryCondition_002.md +273 -0
  9. package/references/BoundaryCondition/StabilityCodeReview_BoundaryCondition_003.md +305 -0
  10. package/references/BoundaryCondition/StabilityCodeReview_BoundaryCondition_004.md +350 -0
  11. package/references/BoundaryCondition/StabilityCodeReview_BoundaryCondition_005.md +301 -0
  12. package/references/BoundaryCondition/StabilityCodeReview_BoundaryCondition_006.md +320 -0
  13. package/references/BoundaryCondition/StabilityCodeReview_BoundaryCondition_007.md +432 -0
  14. package/references/BoundaryCondition/StabilityCodeReview_BoundaryCondition_008.md +394 -0
  15. package/references/BoundaryCondition/StabilityCodeReview_BoundaryCondition_009.md +425 -0
  16. package/references/BoundaryCondition/StabilityCodeReview_BoundaryCondition_010.md +472 -0
  17. package/references/BoundaryCondition/StabilityCodeReview_BoundaryCondition_011.md +204 -0
  18. package/references/BoundaryCondition/StabilityCodeReview_BoundaryCondition_012.md +210 -0
  19. package/references/BoundaryCondition/StabilityCodeReview_BoundaryCondition_013.md +226 -0
  20. package/references/BoundaryCondition/StabilityCodeReview_BoundaryCondition_014.md +222 -0
  21. package/references/BoundaryCondition/StabilityCodeReview_BoundaryCondition_015.md +256 -0
  22. package/references/BoundaryCondition/StabilityCodeReview_BoundaryCondition_016.md +269 -0
  23. package/references/BoundaryCondition/StabilityCodeReview_BoundaryCondition_017.md +222 -0
  24. package/references/BoundaryCondition/StabilityCodeReview_BoundaryCondition_018.md +336 -0
  25. package/references/ConcurrencyStability/StabilityCodeReview_ConcurrencyStability_001.md +414 -0
  26. package/references/ConcurrencyStability/StabilityCodeReview_ConcurrencyStability_002.md +335 -0
  27. package/references/ConcurrencyStability/StabilityCodeReview_ConcurrencyStability_003.md +284 -0
  28. package/references/ConcurrencyStability/StabilityCodeReview_ConcurrencyStability_004.md +313 -0
  29. package/references/ConcurrencyStability/StabilityCodeReview_ConcurrencyStability_005.md +364 -0
  30. package/references/ExceptionHandling/StabilityCodeReview_ExceptionHandling_001.md +142 -0
  31. package/references/ExceptionHandling/StabilityCodeReview_ExceptionHandling_002.md +222 -0
  32. package/references/ExceptionHandling/StabilityCodeReview_ExceptionHandling_003.md +383 -0
  33. package/references/GraphicsStability/StabilityCodeReview_GraphicsStability_001.md +258 -0
  34. package/references/GraphicsStability/StabilityCodeReview_GraphicsStability_002.md +131 -0
  35. package/references/GraphicsStability/StabilityCodeReview_GraphicsStability_003.md +220 -0
  36. package/references/GraphicsStability/StabilityCodeReview_GraphicsStability_004.md +224 -0
  37. package/references/GraphicsStability/StabilityCodeReview_GraphicsStability_005.md +250 -0
  38. package/references/GraphicsStability/StabilityCodeReview_GraphicsStability_006.md +153 -0
  39. package/references/GraphicsStability/StabilityCodeReview_GraphicsStability_007.md +169 -0
  40. package/references/GraphicsStability/StabilityCodeReview_GraphicsStability_008.md +153 -0
  41. package/references/GraphicsStability/StabilityCodeReview_GraphicsStability_009.md +144 -0
  42. package/references/GraphicsStability/StabilityCodeReview_GraphicsStability_010.md +152 -0
  43. package/references/GraphicsStability/StabilityCodeReview_GraphicsStability_011.md +221 -0
  44. package/references/GraphicsStability/StabilityCodeReview_GraphicsStability_012.md +318 -0
  45. package/references/InitializationOrder/StabilityCodeReview_InitializationOrder_001.md +411 -0
  46. package/references/Lifecycle/StabilityCodeReview_Lifecycle_001.md +255 -0
  47. package/references/Lifecycle/StabilityCodeReview_Lifecycle_002.md +177 -0
  48. package/references/MemoryStability/StabilityCodeReview_MemoryStability_001.md +332 -0
  49. package/references/MemoryStability/StabilityCodeReview_MemoryStability_002.md +261 -0
  50. package/references/MemoryStability/StabilityCodeReview_MemoryStability_003.md +428 -0
  51. package/references/MemoryStability/StabilityCodeReview_MemoryStability_004.md +400 -0
  52. package/references/MemoryStability/StabilityCodeReview_MemoryStability_005.md +364 -0
  53. package/references/MemoryStability/StabilityCodeReview_MemoryStability_006.md +359 -0
  54. package/references/MemoryStability/StabilityCodeReview_MemoryStability_007.md +279 -0
  55. package/references/PROBLEM_TEMPLATE.md +65 -0
  56. package/references/PerformanceStability/StabilityCodeReview_PerformanceStability_001.md +380 -0
  57. package/references/PerformanceStability/StabilityCodeReview_PerformanceStability_002.md +437 -0
  58. package/references/REPORT_TEMPLATE.csv +5 -0
  59. package/references/REPORT_TEMPLATE.md +132 -0
  60. package/references/RULE_DEVELOPMENT_GUIDE.md +711 -0
  61. package/references/RULE_INDEX.md +101 -0
  62. package/references/RULE_TEMPLATE.md +192 -0
  63. package/references/ResourceManagement/StabilityCodeReview_ResourceManagement_001.md +334 -0
  64. package/references/ResourceManagement/StabilityCodeReview_ResourceManagement_002.md +425 -0
  65. package/references/ResourceManagement/StabilityCodeReview_ResourceManagement_003.md +420 -0
  66. package/references/ResourceManagement/StabilityCodeReview_ResourceManagement_004.md +409 -0
  67. package/references/ResourceManagement/StabilityCodeReview_ResourceManagement_005.md +445 -0
  68. package/references/ResourceManagement/StabilityCodeReview_ResourceManagement_006.md +384 -0
  69. package/references/ResourceManagement/StabilityCodeReview_ResourceManagement_007.md +395 -0
  70. package/scripts/add-rule.py +423 -0
@@ -0,0 +1,318 @@
1
+ ---
2
+ rule_id: "StabilityCodeReview_GraphicsStability_012"
3
+ name: "SyncFence智能指针缓存管理"
4
+ category: "图形稳定性"
5
+ severity: "HIGH"
6
+ language: ["cpp", "c++"]
7
+ author: "OH-Department7 Stability Team"
8
+ ---
9
+
10
+ # SyncFence智能指针缓存管理
11
+
12
+ ## 问题描述
13
+
14
+ 使用GetFenceFdFromSemaphore、vkGetSemaphoreFdKHR等接口从vulkan信号量中导出的fd由智能指针sptr<SyncFence>接管生命周期后,需检验该智能指针是否被存于缓存中,若存在缓存逻辑,需确保缓存的释放逻辑完整且正确、释放时机合理,避免缓存遗漏清理导致内存泄漏与fd泄漏。
15
+
16
+ ## 检测示例
17
+
18
+ ### 错误示例
19
+
20
+ ```cpp
21
+ // 错误示例1:缓存智能指针但未清理
22
+ class FenceCache {
23
+ private:
24
+ std::map<uint64_t, sptr<SyncFence>> fenceCache_;
25
+
26
+ public:
27
+ void AddFence(uint64_t id, VkSemaphore sem)
28
+ {
29
+ int fd = GetFenceFdFromSemaphore(sem);
30
+ if (fd < 0) {
31
+ return;
32
+ }
33
+
34
+ sptr<SyncFence> fence = new SyncFence(fd);
35
+ // 错误:加入缓存但从未清理
36
+ fenceCache_[id] = fence;
37
+ }
38
+
39
+ // 错误:析构时未清理缓存
40
+ ~FenceCache() {}
41
+ };
42
+
43
+ // 错误示例2:缓存清理逻辑不完整
44
+ class SyncFenceManager {
45
+ private:
46
+ std::unordered_map<int, sptr<SyncFence>> fenceMap_;
47
+
48
+ public:
49
+ void CacheFence(int key, VkSemaphore sem)
50
+ {
51
+ int fd = GetFenceFdFromSemaphore(sem);
52
+ if (fd < 0) {
53
+ return;
54
+ }
55
+
56
+ sptr<SyncFence> fence = new SyncFence(fd);
57
+ fenceMap_[key] = fence;
58
+ }
59
+
60
+ void RemoveFence(int key)
61
+ {
62
+ auto it = fenceMap_.find(key);
63
+ if (it != fenceMap_.end()) {
64
+ // 错误:只erase未检查是否需要手动释放
65
+ fenceMap_.erase(it);
66
+ }
67
+ }
68
+
69
+ // 错误:析构时未检查缓存是否为空
70
+ };
71
+
72
+ // 错误示例3:缓存释放时机不合理
73
+ class RenderFencePool {
74
+ private:
75
+ std::vector<sptr<SyncFence>> fencePool_;
76
+
77
+ public:
78
+ void RecycleFence(VkSemaphore sem)
79
+ {
80
+ int fd = GetFenceFdFromSemaphore(sem);
81
+ if (fd < 0) {
82
+ return;
83
+ }
84
+
85
+ sptr<SyncFence> fence = new SyncFence(fd);
86
+ // 错误:缓存一直增长,无清理机制
87
+ fencePool_.push_back(fence);
88
+ }
89
+
90
+ // 错误:缺少定期清理或限制缓存的机制
91
+ };
92
+ ```
93
+
94
+ ### 正确示例
95
+
96
+ ```cpp
97
+ // 正确示例1:完整的缓存清理逻辑
98
+ class FenceCache {
99
+ private:
100
+ std::map<uint64_t, sptr<SyncFence>> fenceCache_;
101
+
102
+ public:
103
+ void AddFence(uint64_t id, VkSemaphore sem)
104
+ {
105
+ int fd = GetFenceFdFromSemaphore(sem);
106
+ if (fd < 0) {
107
+ return;
108
+ }
109
+
110
+ sptr<SyncFence> fence = new SyncFence(fd);
111
+ fenceCache_[id] = fence;
112
+
113
+ // 正确:检查缓存大小并清理旧条目
114
+ if (fenceCache_.size() > MAX_CACHE_SIZE) {
115
+ auto oldest = fenceCache_.begin();
116
+ fenceCache_.erase(oldest);
117
+ }
118
+ }
119
+
120
+ void RemoveFence(uint64_t id)
121
+ {
122
+ auto it = fenceCache_.find(id);
123
+ if (it != fenceCache_.end()) {
124
+ // 正确:sptr引用计数自动管理,erase即可
125
+ fenceCache_.erase(it);
126
+ }
127
+ }
128
+
129
+ void ClearCache()
130
+ {
131
+ // 正确:提供清理接口
132
+ fenceCache_.clear();
133
+ }
134
+
135
+ ~FenceCache()
136
+ {
137
+ // 正确:析构时清理缓存
138
+ ClearCache();
139
+ }
140
+ };
141
+
142
+ // 正确示例2:带引用计数和过期检查的缓存管理
143
+ class SyncFenceManager {
144
+ private:
145
+ std::unordered_map<int, std::pair<sptr<SyncFence>, int64_t>> fenceMap_;
146
+
147
+ public:
148
+ void CacheFence(int key, VkSemaphore sem)
149
+ {
150
+ int fd = GetFenceFdFromSemaphore(sem);
151
+ if (fd < 0) {
152
+ return;
153
+ }
154
+
155
+ sptr<SyncFence> fence = new SyncFence(fd);
156
+ int64_t timestamp = GetCurrentTime();
157
+
158
+ // 正确:清理过期条目
159
+ CleanupExpiredEntries();
160
+
161
+ fenceMap_[key] = {fence, timestamp};
162
+ }
163
+
164
+ void RemoveFence(int key)
165
+ {
166
+ // 正确:erase会自动减少引用计数
167
+ fenceMap_.erase(key);
168
+ }
169
+
170
+ void CleanupExpiredEntries()
171
+ {
172
+ int64_t now = GetCurrentTime();
173
+ for (auto it = fenceMap_.begin(); it != fenceMap_.end(); ) {
174
+ if (now - it->second.second > CACHE_TIMEOUT) {
175
+ it = fenceMap_.erase(it);
176
+ } else {
177
+ ++it;
178
+ }
179
+ }
180
+ }
181
+ };
182
+
183
+ // 正确示例3:限制缓存大小并提供清理机制
184
+ class RenderFencePool {
185
+ private:
186
+ std::deque<sptr<SyncFence>> fencePool_;
187
+ static const size_t MAX_POOL_SIZE = 100;
188
+
189
+ public:
190
+ void RecycleFence(VkSemaphore sem)
191
+ {
192
+ int fd = GetFenceFdFromSemaphore(sem);
193
+ if (fd < 0) {
194
+ return;
195
+ }
196
+
197
+ sptr<SyncFence> fence = new SyncFence(fd);
198
+
199
+ // 正确:限制缓存大小
200
+ if (fencePool_.size() >= MAX_POOL_SIZE) {
201
+ fencePool_.pop_front(); // 移除最旧的
202
+ }
203
+
204
+ fencePool_.push_back(fence);
205
+ }
206
+
207
+ void ClearPool()
208
+ {
209
+ fencePool_.clear();
210
+ }
211
+
212
+ size_t GetPoolSize() const
213
+ {
214
+ return fencePool_.size();
215
+ }
216
+ };
217
+ ```
218
+
219
+ ## 检测范围
220
+
221
+ 检查以下API/函数/模式:
222
+
223
+ - `GetFenceFdFromSemaphore()`后创建`sptr<SyncFence>`并存入缓存
224
+ - 将`SyncFence`智能指针存入`std::map`、`std::unordered_map`、`std::vector`等容器
225
+ - 缓存`SyncFence`对象的管理类、管理器
226
+
227
+ ## 检测要点
228
+
229
+ 1. 识别将SyncFence智能指针存入缓存的代码
230
+ 2. 检查缓存是否有清理机制(erase/clear/remove等)
231
+ 3. 检查缓存清理逻辑是否完整,所有退出路径是否都清理
232
+ 4. 检查缓存大小是否有限制,避免无限增长
233
+ 5. 检查析构函数是否清理缓存
234
+
235
+ ## 风险流分析(RiskFlow)
236
+
237
+ - **RISK_SOURCE**: SyncFence智能指针存入缓存但未正确管理
238
+ - **RISK_TYPE**: 内存泄漏、文件描述符泄漏
239
+ - **RISK_PATH**: fd导出 → SyncFence管理 → 存入缓存 → 未清理 → 内存和fd泄漏
240
+ - **IMPACT_POINT**: 系统资源耗尽,程序性能下降或崩溃
241
+
242
+ ## 影响分析(ImpactAnalysis)
243
+
244
+ - **Trigger**: 将SyncFence智能指针存入缓存容器
245
+ - **Propagation**: 缓存未清理或清理逻辑不完整,条目持续累积
246
+ - **Consequence**: 内存泄漏、fd泄漏累积,系统资源耗尽
247
+ - **Mitigation**: 确保缓存有完整的清理逻辑、大小限制、过期机制
248
+
249
+ ## 误报排除
250
+
251
+ | 场景 | 识别特征 | 处理方式 |
252
+ |------|----------|----------|
253
+ | 临时缓存立即清理 | 缓存后立即erase/clear | 不报 |
254
+ | 有定期清理机制 | 定时器或定期调用clear | 不报 |
255
+ | 缓存大小有限制 | 检查size并删除旧条目 | 不报 |
256
+ | 缓存生命周期短暂 | 局部缓存在作用域结束时销毁 | 不报 |
257
+
258
+ ## 测试用例
259
+
260
+ ### 触发用例(应该报)
261
+
262
+ ```cpp
263
+ // test_StabilityCodeReview_GraphicsStability_012_trigger.cpp
264
+ class BadFenceCache {
265
+ private:
266
+ std::map<int, sptr<SyncFence>> cache_;
267
+
268
+ public:
269
+ void Add(int key, VkSemaphore sem)
270
+ {
271
+ int fd = GetFenceFdFromSemaphore(sem);
272
+ if (fd < 0) return;
273
+
274
+ sptr<SyncFence> fence = new SyncFence(fd);
275
+ cache_[key] = fence;
276
+ // 应该报:缓存未清理
277
+ }
278
+
279
+ // 应该报:析构函数未清理缓存
280
+ };
281
+ ```
282
+
283
+ ### 安全用例(不应该报)
284
+
285
+ ```cpp
286
+ // test_StabilityCodeReview_GraphicsStability_012_safe.cpp
287
+ class GoodFenceCache {
288
+ private:
289
+ std::map<int, sptr<SyncFence>> cache_;
290
+ static const size_t MAX_SIZE = 100;
291
+
292
+ public:
293
+ void Add(int key, VkSemaphore sem)
294
+ {
295
+ int fd = GetFenceFdFromSemaphore(sem);
296
+ if (fd < 0) return;
297
+
298
+ sptr<SyncFence> fence = new SyncFence(fd);
299
+
300
+ // 不报:有大小限制和清理机制
301
+ if (cache_.size() >= MAX_SIZE) {
302
+ cache_.erase(cache_.begin());
303
+ }
304
+
305
+ cache_[key] = fence;
306
+ }
307
+
308
+ void Remove(int key)
309
+ {
310
+ cache_.erase(key); // 不报:有清理接口
311
+ }
312
+
313
+ ~GoodFenceCache()
314
+ {
315
+ cache_.clear(); // 不报:析构时清理
316
+ }
317
+ };
318
+ ```