0

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

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

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

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

在此处输入图像描述

4

2 回答 2

1

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

我在使用 Valgrind 寻找这类错误方面取得了一些成功。使用 安装它,然后在启动文件中apt install valgrind添加一个。它会非常慢,但它非常擅长查明这些问题。launch-prefix="valgrind"<node>

以这个有缺陷的程序为例:

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 对象的位置(test.cpp:10)以及最初创建的位置(test.cpp:8)。

祝您在寻找错误时好运!

于 2020-05-08T17:53:14.133 回答
1

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

    void lock()
    {
        BOOST_VERIFY(!posix::pthread_mutex_lock(&m));
    }

这意味着根据文档,或者:

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

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

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

    Boost 不处理这种情况,只是断言。scoped_lock如果您的所有线程都使用线程安全的锁守卫( , unique_lock, shared_lock, ),这也不太可能发生lock_guard。但是,如果您在某处手动使用lock()(and ) 函数并且线程在没有ing的情况下退出,它可能会发生unlock()unlock()

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

于 2020-05-07T22:55:10.710 回答