【问题标题】:std::lock_guard<std::mutex> segfaults on construction?std::lock_guard<std::mutex> 构造中的段错误?
【发布时间】:2013-08-24 08:47:17
【问题描述】:

我正在尝试使用 std::mutex 和 std::lock_guard 访问共享的 std::queue。互斥体(pending_md_mtx_)是另一个对象(其地址有效)的成员变量。我的代码似乎在 lock_guard 的构造上出现了段错误。

有什么想法吗?我应该改用 std::unique_lock (或其他对象)吗?在 Ubuntu Linux 下运行 GCC 4.6 (--std=c++0x)。我不能发布整个课程,但只能访问下面列出的互斥锁和队列。

template <typename ListenerT>
class Driver
{
public:
    template <typename... Args>
    Driver(Args&&... args) :
        listener_(std::forward<Args>(args)...) {}

    void enqueue_md(netw::Packet* packet)
    {
        std::lock_guard<std::mutex> lock(pending_md_mtx_);
        pending_md_.push(packet);
    }

    void process_md()
    {
        std::lock_guard<std::mutex> lock(pending_md_mtx_);
        while (pending_md_.size())
        {
            netw::Packet* pkt=pending_md_.front();
            pending_md_.pop();
            process_md(*pkt);
        }
    }
    //... Other code which I can't post...

private:
    ListenerT listener_;
    std::mutex pending_md_mtx_;
    std::queue<netw::Packet*> pending_md_;
};

GDB 堆栈跟踪:

(gdb) bt
#0  __pthread_mutex_lock (mutex=0x2f20aa75e6f4000) at pthread_mutex_lock.c:50
#1  0x000000000041a2dc in __gthread_mutex_lock (__mutex=0xff282ceacb40) at /usr/include/c++/4.6/x86_64-linux-gnu/./bits/gthr-default.h:742
#2  lock (this=0xff282ceacb40) at /usr/include/c++/4.6/mutex:90
#3  lock_guard (__m=..., this=0x7f2874fc4db0) at /usr/include/c++/4.6/mutex:445
#4  driver::Driver<Listener, false>::enqueue_md (this=0xff282ceac8a0, packet=...) at exec/../../driver/Driver.hpp:95

【问题讨论】:

  • 您需要更多地说明如何声明和访问pending_md_mtx_
  • 错误不在显示的代码中:coliru.stacked-crooked.com/…
  • 您使用的Driver&lt;T&gt;instance 是否可能无效?例如,Driver&lt;MyType&gt; *p; p-&gt;enqueue_md(param); 肯定会编译,但同样肯定会调用未定义的行为,因为实例完全无效。
  • 是否可以从process_md(*pkt) 调用enqueue_md,从而尝试锁定该线程已经持有的互斥锁?
  • 有趣的问题。什么情况下可能无效?其他几个方法调用顺利进行,而且这种崩溃似乎是不确定的。我做了一个干净的构建,但仍然会遇到崩溃......有时。

标签: c++ c++11 segmentation-fault mutex


【解决方案1】:

我在构建std::lock_guard 时遇到了段错误,结果我的代码使用了未初始化的std::shared_ptr&lt;my_object_with_mutex&gt;。使用正确构造的 my_object_with_mutex 可以解决问题。

【讨论】:

    【解决方案2】:

    我最近遇到了这个问题。这是由获取锁后导致缓冲区溢出的代码行引起的。锁定下方的一行代码在前几行引起问题似乎很奇怪,但我认为缓冲区溢出会导致一些损坏,从而导致第二次调用该函数时出现问题。

    【讨论】:

      【解决方案3】:

      我的问题根源:

      1. 对象 A 引用对象 B
      2. 调用对象 B.func() 我在 lock_guard 上看到了 SegFault
      3. 从未为对象 A 设置对象 B(未初始化,NULL 指针),导致访问字段时出现 SegFault(在我的情况下为互斥体)。

      通过注意到this=0x0,可以从 GDB 诊断错误:

      ...
      #4  0x000055e3a9e14a3c in B<C>::write (this=0x4e2280, msg=0x55e3aac03be0) at /proj/B.hpp:35
      #5  0x000055e3a9e206e6 in A::write (this=0x0, msg=0x55e3aac03be0) at /proj/A.cpp:286
      #6  0x000055e3a9e2069a in A::write (this=0x7f21eae64010, msg=0x55e3aac03be0) at /proj/A.cpp:277
      ...
      

      【讨论】:

        猜你喜欢
        • 2013-12-29
        • 2017-03-28
        • 1970-01-01
        • 1970-01-01
        • 2018-05-11
        • 1970-01-01
        • 2011-11-25
        • 1970-01-01
        • 2018-07-08
        相关资源
        最近更新 更多