【问题标题】:How to detect unreleased lock in multi-task C project using static analysis tools?如何使用静态分析工具检测多任务 C 项目中未释放的锁?
【发布时间】:2020-07-21 10:01:17
【问题描述】:

有没有什么办法,使用静态分析工具(我现在正在使用Codesonar),来检测以下程序中未释放的锁问题(比如未释放的信号量)?(箭头标记的注释部分)

该项目是一个使用循环调度的多任务系统,其中new_request()是一个中断任务随机到来,send_buffer()是另一个周期任务。

在实际情况下,get_buffer()send_buffer() 是各种类型的包装器,它们包含许多调用层,直到实际的锁定/解锁过程。所以我不能在静态分析工具的设置中简单地将get_buffer()指定为lock function

int bufferSize = 0;     // say max size is 5

// random task
void new_request()
{
    int bufferNo = get_buffer();    // wrapper

    if (bufferNo == -1)
    {
        return;    // buffer is full
    }   

    if (check_something() == OK)
    {
        add_to_sendlist(bufferNo);  // for asynchronous process of send_buffer()
    }
    else    // bad request
    {
        // ↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓
        // There should be clear_buffer placed here
        // but forgotten. Eventually the buffer will be
        // full and won't be cleared since 5th bad request comes.
        // ↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑

        do_nothing();
        // clear_buffer(bufferNo);
    }
}

int get_buffer()
{
    if(bufferSize < 5)
    {
        bufferSize++;
        return bufferSize;
    }
    else
    {
        wait_until_empty(); // wait until someone is sent by send_buffer()
        return -1;
    }

}

// clear specifiled one in buffer
void clear_buffer(int bufferNo) 
{
    delete(bufferNo)
    bufferSize--;
    
}
// period task
void send_buffer()
{
    int sent = send_1st_stuff_in_list();
    clear_buffer(sent);
}

【问题讨论】:

  • 你真的需要这个吗?我问是因为,在多年编写多线程应用程序之后,我还没有看到这样一个问题,它不会在测试期间导致明显的循环、锁定、死锁或明显的段错误/AV 灾难也许这只是运气,我应该买彩票:)
  • 请注意,我并不是说我没有遇到这些问题,只是说它们很容易找到并修复:)
  • 这是一个旧代码,我们最近发现攻击者可以利用这个漏洞,发送恶意修改的错误请求,使send_buffer停止工作。如果可能的话,我想使用静态分析找到所有类似的错误。
  • 听起来很可怕。您可能需要修复的不仅仅是锁定:((

标签: c multithreading semaphore static-analysis


【解决方案1】:

yoyozi - 公平披露:我是 GrammaTech 的一名工程师,从事 CodeSonar 工作。

首先是一些一般性的东西。手册的相关部分在页面上:codesonar/doc/html/C_Module/LibraryModels/ConcurrencyModelsLocks.html。尤其是页面底部解决锁操作识别问题。

根据您的 cmets,我认为您已经阅读了此内容,因为您在配置设置中设置了名称。

那么问题是你有多少种不同的包装器?如果只是几个,那么配置文件中的设置是可行的。如果有很多,那会很乏味。如果有很多,这几乎是不可能的。

因此,了解对您拥有多少个包装器集的估计会有所帮助。

即使考虑到包装器,死锁和竞争检测器也可能不是您解决问题所需要的。

如果我正确理解您的问题,您的队列空间有限,并且意外地,格式错误的项目不会从队列中清除,因此队列已满,所有处理都停止了。虽然您可能在此实现中涉及多个线程,但问题本身仍然是基本串行设置中的问题。

处理此类问题的最佳方法是尝试制作一个更简单的示例来显示相同​​的核心问题。如果您可以通过 GrammaTech 共享的方式执行此操作,我们可以与您一起调整设置或提供分析提示,以便找到此问题。

如果您想更详细地讨论这个问题,并防止公开披露您的代码,请通过 support_at_grammatech_dot_com 与我们联系,其中 atdot应根据需要替换以形成格式良好的电子邮件地址。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2010-12-30
    • 1970-01-01
    • 2012-01-06
    • 1970-01-01
    • 2019-10-24
    • 1970-01-01
    • 2011-12-01
    • 1970-01-01
    相关资源
    最近更新 更多