我正在尝试获取 clang 的
acquire_handle
和 release_handle
属性 的句柄 (du-dum-tsh)。我写过
int create_foo(void) __attribute__((acquire_handle("foo")));
void destroy_foo(int __attribute__((release_handle("foo"))) foo);
void func(void)
{
int foo = create_foo();
destroy_foo(foo);
destroy_foo(foo);
}
虽然编译得很好,但为什么不行
scan-build clang -c foo.c
检测到双重释放?
这是 clang 14.0.0。
Clang 中的
acquire_handle
和 release_handle
属性旨在帮助跟踪代码中的资源管理,特别是对于需要显式获取和释放的资源。然而,静态分析器(如scan-build
)可能并不总是能捕获所有潜在的错误,尤其是在更复杂的情况下。
在您的代码中,您定义了
create_foo
来获取句柄,并定义 destroy_foo
来释放它。但是,静态分析器可能无法跨多个函数调用跟踪句柄的所有权,特别是当资源管理函数位于不同的转换单元中或者当处理相同资源不是很明显时。
为了帮助静态分析器更可靠地检测双重释放,除了
__attribute__((ownership_returns(foo)))
和 __attribute__((ownership_holds(foo)))
属性之外,您还可以使用 acquire_handle
和 release_handle
属性。这些属性指定 create_foo
函数返回句柄的所有权,并且 destroy_foo
函数持有所有权。
这是具有这些属性的代码的更新版本:
int create_foo(void) __attribute__((acquire_handle("foo"), ownership_returns("foo")));
void destroy_foo(int __attribute__((release_handle("foo"), ownership_holds("foo"))) foo);
void func(void)
{
int foo = create_foo();
destroy_foo(foo);
destroy_foo(foo); // This should now be detected as a double release.
}
添加
ownership_returns
和 ownership_holds
属性有助于静态分析器更好地了解所有权流程,并可以提高其检测潜在问题的能力。但是,请记住,静态分析器的有效性取决于代码的复杂性及其执行的具体分析。在更复杂的场景中,可能仍然需要手动检查以确保正确的资源管理。