std::lock_guard<std::mutex> 施工上的段错误?

std::lock_guard<std::mutex> segfaults on construction?

本文关键字:std 段错误 错误 gt lock guard lt 施工 mutex      更新时间:2023-10-16

我正试图使用std::mutex和std::lock_guard访问共享std::队列。互斥对象(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 Stacktrace:

(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

我在构造std::lock_guard时遇到了一个segfault,结果发现我的代码使用了一个未初始化的std::shared_ptr<my_object_with_mutex>。使用适当构造的my_object_with_mutex解决了这个问题。

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

我的案例中的问题根本原因:

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

在我的案例中,根本原因是相同的(互斥对象未初始化),但原因并非如此。

具有互斥对象的对象具有函数reset。你猜怎么着,shared_ptr还有一个名为reset的函数,我改为调用它!

避免使用reset作为名称,或者仔细检查是否使用obj.reset()而不是obj->reset()