Page 252 - 《软件学报》2026年第3期
P. 252

李清伟 等: Go  语言程序的内存性能与安全问题实证研究                                                   1215


                    ● N1: 指针使用前没有检查是否为空. 在该类别中, 根据该问题发生的上下文可分为如下                       4 小类, 模式如代码     11
                 所示.

                 代码  11. N1: 指针使用前没有检查是否为空问题模式.

                 1.   // N1-1: cockroachdb/cockroach/issues/48092
                 2.     asString = GetAString() // may return nil
                 3.   + if asString == nil { return }
                 4.     parse(*asString) // as String not checked for nil
                 5.   // N1-2: milvus-io/milvus/issues/17823
                 6.   // ptr not checked for nil
                 7.   − return ptr.GetState() != someState &&  ...
                 8.   + return ptr != nil && ptr.GetState() != someState &&  ...
                 9.   // N1-3: milvus-io/milvus/issues/5333
                 10.   func getID() (ptr *Meta, err error) {
                 11.     // ptr is notinitialized
                 12. +    ... // initialize ptr
                 13.     ptr.ID =  ...
                 14.      ...
                 15.   }
                 16. // N1-4: milvus-io/milvus/issues/31495
                 17.   if len(GetObj2ByObj1(obj1)) == 0 { continue }
                 18.   obj2 = GetObj2byObj1AndObj3(obj1, obj3)
                 19. + if obj2 == nil { continue }
                 20.   obj2.field // obj2 can still be nil
                    N1-1: 未对函数调用返回的指针进行空值检查. 代码              11  中第  1–4  行展示了  cockroach 的 Issue#48092 [56] 的代码
                 简化, 其中, asString  是函数调用返回的指针. 当      asString  为空时, 编译器生成的运行时检测代码会发现空指针并导
                 致提前崩溃. 虽然这种运行时检查避免了程序继续执行, 防止了未定义行为, 但它实际上可以通过静态分析工具或
                 者编译器的编译时检查进行提前检测, 提前发现部分空指针解引用问题. 尽管如此, 表                          11  中仍有  6  条因未检查函
                 数返回指针是否为空而导致崩溃的 Issues.
                    N1-2: 在条件表达式中使用指针前未进行空值检查. 代码                11  中第 5–8  行展示了  milvus 的  Issue#17823 [57] 的代
                 码简化. 其中, ptr 在未检查是否为空的情况下就直接进行了方法调用, 导致崩溃.
                    N1-3: 指针变量在声明后未初始化就直接使用. 代码              11  中第  9–15  行展示了  milvus 的 Issue#5333 [58] 的代码简
                 化, 由于返回值变量      ptr 未初始化就进行解引用访问操作          ptr.ID, 导致程序运行时崩溃.
                    N1-4: 使用指针前非空判断条件不充分. 代码            11  中第  16–20  行展示了  milvus 的  Issue#31495 [59] 的代码简化.
                 由于  len( ...) == 0  的条件判断不等价于  obj2  不为空, 导致在进行解引用访问      obj2.field  时发生崩溃.
                    ● N2. 某些操作的执行取决于指针是否为            nil 指针. 是否为  nil 可以作为是否执行与指针相关操作的条件. 在
                 某些情况下, 指针应该被置为         nil 以防止非法操作被调用. 代码        12  展示了修复代码, 当发生错误时, d.serializer 被
                 置为空, 以防止后续对非法操作的调用.
                    ● N3. 杂项. 除了上述提到的简单模式之外, 在           21  条与无效内存地址或空指针解引用相关的 Issues 中, 有           10
                 条属于该范畴. 由于这些问题的修复规模较大并且需要较强的领域知识, 故无法推断出导致问题的核心原因.
   247   248   249   250   251   252   253   254   255   256   257