Boost pthread_recursive_mutex-断言失败

Boost pthread_recursive_mutex-断言失败,boost,pthreads,ros,recursive-mutex,Boost,Pthreads,Ros,Recursive Mutex,我正在使用ROS(机器人操作系统)框架。如果您熟悉ROS,在我的代码中,我没有使用活动服务器。明确使用出版商、订阅者和服务。不幸的是,我面临pthread\u recursive\u互斥错误的问题。以下是错误及其回溯 如果有人熟悉ROS stack,请分享可能导致此运行时错误的潜在原因 我可以提供有关运行时错误的更多信息。非常感谢你的帮助。谢谢 /usr/include/boost/thread/pthread/recursive_mutex.hpp:113: void boost::recur

我正在使用ROS(机器人操作系统)框架。如果您熟悉ROS,在我的代码中,我没有使用活动服务器。明确使用出版商、订阅者和服务。不幸的是,我面临pthread\u recursive\u互斥错误的问题。以下是错误及其回溯

如果有人熟悉ROS stack,请分享可能导致此运行时错误的潜在原因

我可以提供有关运行时错误的更多信息。非常感谢你的帮助。谢谢

/usr/include/boost/thread/pthread/recursive_mutex.hpp:113: void boost::recursive_mutex::lock(): Assertion `!pthread_mutex_lock(&m)' failed.

锁的
方法实现仅断言pthread返回值:

    void lock()
    {
        BOOST_VERIFY(!posix::pthread_mutex_lock(&m));
    }
这意味着,根据文件,可以:

  • EAGAIN
    )无法获取互斥,因为 已超过互斥锁的递归锁

    这表明您的锁(不是这个调用站点,因为
    unique\u lock
    确保不会发生这种情况)中存在某种不平衡,或者只是在安装等待相同锁的线程

  • EOWNERDEAD
    )互斥体是一个健壮的互斥体,进程包含 持有互斥锁时,先前拥有的线程终止。互斥 锁由调用线程获取,由新线程决定 所有者要使状态一致

    Boost不处理这个案例,只是断言。如果所有线程都使用线程安全锁保护(
    作用域锁
    唯一锁
    共享锁
    锁保护
    )。但是,如果您在某个位置手动使用
    lock()
    (和
    unlock()
    )函数,并且线程退出时没有
    unlock()
    ,则可能会发生这种情况


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

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

    void lock()
    {
        BOOST_VERIFY(!posix::pthread_mutex_lock(&m));
    }
这意味着,根据文件,可以:

  • EAGAIN
    )无法获取互斥,因为 已超过互斥锁的递归锁

    这表明您的锁(不是这个调用站点,因为
    unique\u lock
    确保不会发生这种情况)中存在某种不平衡,或者只是在安装等待相同锁的线程

  • EOWNERDEAD
    )互斥体是一个健壮的互斥体,进程包含 持有互斥锁时,先前拥有的线程终止。互斥 锁由调用线程获取,由新线程决定 所有者要使状态一致

    Boost不处理这个案例,只是断言。如果所有线程都使用线程安全锁保护(
    作用域锁
    唯一锁
    共享锁
    锁保护
    )。但是,如果您在某个位置手动使用
    lock()
    (和
    unlock()
    )函数,并且线程退出时没有
    unlock()
    ,则可能会发生这种情况


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

这看起来像是一个释放后使用的问题,其中互斥已被销毁,可能是因为其所属对象被删除

我使用Valgrind成功地找到了这种类型的bug。使用
apt Install valgrind
安装它,并将
launch prefix=“valgrind”
添加到启动文件中的
。这将是非常缓慢的,但它非常善于指出这些问题

以这个错误程序为例:

struct Test
{
    int a;
};

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

==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


祝你在找虫子的过程中好运

这看起来像是一个释放后使用的问题,其中一个互斥已被销毁,可能是因为其所属对象已被删除

我使用Valgrind成功地找到了这种类型的bug。使用
apt Install valgrind
安装它,并将
launch prefix=“valgrind”
添加到启动文件中的
。这将是非常缓慢的,但它非常善于指出这些问题

以这个错误程序为例:

struct Test
{
    int a;
};

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

==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


祝你在找虫子的过程中好运

你找到解决办法了吗?那么请把它贴出来,你能找到解决办法吗?那么请把它寄出去,谢谢