有没有一种方法告诉clang分析器一个函数返回了malloc()分配的内存?

7

我正在开发一个小型库,我不想在可能出现的每个地方都处理分配错误,因此我编写了一个malloc()的包装器,如果出现错误,它将终止程序(目前如此)。

void *cstr_malloc(size_t size)
{
    void *buf = malloc(size);
    if (!buf)
    {
        fprintf(stderr, "Allocation error, terminating\n");
        exit(2);
    }
    return buf;
}

没有什么花哨的东西。然而,我注意到clang静态分析器(至少在Xcode中)不会像以前一样捕获明显的泄漏。

如果我做这样的事情:

void foo(void)
{
    void *p = malloc(100);
}

如果我自然地知道,p 很可能会泄漏内存。

但是,有了...

void foo(void)
{
    void *p = malloc(100);
    void *q = cstr_malloc(100);
}

它只报告 p 泄漏,而不是q

这很有道理;它不能知道程序在哪里分配内存并且在合理的时间内分析它。如果我将分配器内联,它可以很好地处理,因此它能看见它,但否则它就不能看见。

有没有办法告诉分析器我有一个函数返回新分配的内存?类似于 __attribute__((malloc)) 或类似的属性吗?

当然,我可以将函数内联,但我还有一堆类似地分配内存的其他函数,如果将它们全部内联将会很麻烦。


@P.P 然而似乎不起作用:https://godbolt.org/z/9o19esbhG - user17732522
1
我尝试过__attribute__((malloc)),但它对我没有起作用。当然,可能还有其他问题,这就是为什么我没有看到效果的原因。但是仅仅使用属性并不能解决问题,而内联分配器确实可以... - Thomas Mailund
嗯,在Godbolt上@P.P对我有效(但在我的电脑上无效)。我应该理解为它在Godbolt上对你无效吗?那可能是我需要解决的配置问题。编辑:不,我误读了Godbolt。它在那里也不起作用。 - Thomas Mailund
@StoryTeller-UnslanderMonica 我只看到了针对分配的 p 的警告,而没有看到(同样分配的)q 的警告。它没有看到(当然,在这里也看不到)q 也分配了内存。 - Thomas Mailund
不用理会那个注释。警告文本提到了 p,但是下面代码高亮却在 q 上。很令人困惑的东西。 - StoryTeller - Unslander Monica
@StoryTeller-UnslanderMonica,这也是我第一次误读它的方式。 - Thomas Mailund
1个回答

3

经过几个小时的谷歌搜索,我找到了至少看起来像是解决方案的内容。技巧确实是使用属性,但不是 __attribute__((malloc))

我需要的属性是 ownership_returns(malloc)。使用它,我会得到警告,至少对于这个函数而言。

__attribute__((ownership_returns(malloc)))
void *cstr_malloc(size_t size);

请参见https://godbolt.org/z/MEfvThKnW

不幸的是,我的喜悦很短暂。如果我使用ownership_returns(malloc),那么分析器会认为内存也未初始化,但实际上并非总是如此。我不知道如何提示我返回必须释放但不是未初始化内存的内存。

由于clang可以确定calloc()的情况,因此可能有一种方法可以对我的函数进行处理,但我尚未找到。

以下是clang处理从calloc()返回的内存以及它对我的函数返回的内存的看法的示例:https://godbolt.org/z/P45o691Tx


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接