首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >pthread_recursive_mutex -断言失败

pthread_recursive_mutex -断言失败
EN

Stack Overflow用户
提问于 2020-05-07 06:21:30
回答 2查看 472关注 0票数 0

我使用的是ROS (机器人操作系统)框架。如果您熟悉ROS,在我的代码中,我没有使用活动服务器。简单地使用发布者、订阅者和服务。不幸的是,我面临着pthread_recursive_mutex错误的问题。以下是错误及其回溯。

如果有人熟悉ROS堆栈,您能分享一下可能导致此运行时错误的潜在原因吗?

我可以给出更多关于我的运行时错误的信息。非常感谢您的帮助。谢谢

代码语言:javascript
复制
/usr/include/boost/thread/pthread/recursive_mutex.hpp:113: void boost::recursive_mutex::lock(): Assertion `!pthread_mutex_lock(&m)' failed.

EN

回答 2

Stack Overflow用户

发布于 2020-05-08 06:55:11

lock方法实现只断言pthread返回值:

代码语言:javascript
复制
    void lock()
    {
        BOOST_VERIFY(!posix::pthread_mutex_lock(&m));
    }

这意味着,根据文档,要么:

  • (EAGAIN)无法获取互斥锁,因为已超过互斥锁的最大递归锁数量。

这将表明您的锁中存在某种不平衡(不是这个调用点,因为unique_lock<>确保不会发生这种情况),或者只是在堆积所有正在等待同一lock

  • (EOWNERDEAD)的线程。互斥锁是一个健壮的互斥锁,并且包含前一个拥有互斥锁的线程的进程在持有互斥锁时终止。互斥锁将由调用线程获取,并由新的所有者负责使状态保持一致。

Boost不处理这种情况,只是断言。如果您的所有线程都使用线程安全锁保护(scoped_lockunique_lockshared_locklock_guard),这也不太可能发生。但是,如果您在没有unlock()ing的情况下手动使用lock() (和unlock())函数而线程退出,则可能会发生这种情况

还有其他一些(特别是经过检查的)互斥锁可能失败的方式,但这些方式不适用于boost::recursive_mutex

票数 1
EN

Stack Overflow用户

发布于 2020-05-09 01:53:14

这看起来像是释放后使用的问题,互斥锁已经被销毁了,可能是因为它拥有的对象被删除了。

我使用Valgrind成功地找到了这种类型的bug。使用apt install valgrind安装它,并将launch-prefix="valgrind"添加到启动文件中的<node>中。它将会非常慢,但它在定位这些问题上相当熟练。

以这个有buggy的程序为例:

代码语言:javascript
复制
struct Test
{
    int a;
};

int main()
{
    Test* test = new Test();
    test->a = 42;
    delete test;
    test->a = 0; // BUG!
}

valgrind ./testprog收益率

代码语言:javascript
复制
==8348== Invalid write of size 4
==8348==    at 0x108601: main (test.cpp:11)
==8348==  Address 0x5b7ec80 is 0 bytes inside a block of size 4 free'd
==8348==    at 0x4C3168B: operator delete(void*, unsigned long) (in /usr/lib/x86_64-linux-gnu/valgrind/vgpreload_memcheck-amd64-linux.so)
==8348==    by 0x108600: main (test.cpp:10)
==8348==  Block was alloc'd at
==8348==    at 0x4C303EF: operator new(unsigned long) (in /usr/lib/x86_64-linux-gnu/valgrind/vgpreload_memcheck-amd64-linux.so)
==8348==    by 0x1085EA: main (test.cpp:8)

注意,它不仅会告诉您错误访问发生在哪里(test.cpp:11),而且还会告诉您测试对象是在哪里删除的(test.cpp:10),以及它最初创建的位置(test.cpp:8)。

祝你在寻找bug的过程中好运!

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/61646433

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档