boost :: weak_ptr <T>.lock () Сбои с ошибкой сегментации SIGSEGV - PullRequest
1 голос
/ 30 марта 2012

(РЕДАКТИРОВАТЬ) Окружающая среда:

plee@sos-build:/usr/local/include/boost$ lsb_release -a
No LSB modules are available.
Distributor ID: Ubuntu
Description:    Ubuntu 11.10
Release:        11.10
Codename:       oneiric

plee@sos-build:/usr/local/include/boost$ uname -a
Linux sos-build 3.0.0-12-generic #20-Ubuntu SMP Fri Oct 7 14:56:25 UTC 2011 x86_64 x86_64 x86_64 GNU/Linux
plee@sos-build:/usr/local/include/boost$

plee@sos-build:/usr/local/include/boost$ cat version.hpp
//  BOOST_LIB_VERSION must be defined to be the same as BOOST_VERSION
#define BOOST_LIB_VERSION "1_47"

Я работал над проектом на стороне сервера. Я использую библиотеки повышения, например, boost::asio, boost::shared_ptr и boost::weak_ptr.

В документации Boost (http://www.boost.org/doc/libs/1_47_0/libs/smart_ptr/weak_ptr.htm#lock) сказано, что weak_ptr<T>.lock никогда не выбрасывает:

замок

shared_ptr lock () const; Возвращает: истек ()? shared_ptr (): shared_ptr (* это).

Броски: ничего.

Тем не менее, в моем приложении это даже сбой:

Program received signal SIGSEGV, Segmentation fault.
[Switching to Thread 0x7fffeffff700 (LWP 5102)]
0x000000000066fe08 in boost::detail::atomic_conditional_increment (pw=0x800000000007)
    at /usr/local/include/boost/smart_ptr/detail/sp_counted_base_gcc_x86.hpp:92
92      );
(gdb) 
(gdb) bt
#0  0x000000000066fe08 in boost::detail::atomic_conditional_increment (pw=0x800000000007)
    at /usr/local/include/boost/smart_ptr/detail/sp_counted_base_gcc_x86.hpp:92
#1  0x000000000066fe5c in boost::detail::sp_counted_base::add_ref_lock (this=0x7fffffffffff)
    at /usr/local/include/boost/smart_ptr/detail/sp_counted_base_gcc_x86.hpp:138
#2  0x000000000068009b in boost::detail::shared_count::shared_count (this=0x7fffefffe658, r=...)
    at /usr/local/include/boost/smart_ptr/detail/shared_count.hpp:518
#3  0x0000000000691599 in boost::shared_ptr<RtmpConnection>::shared_ptr<RtmpConnection> (
    this=0x7fffefffe650, r=...) at /usr/local/include/boost/smart_ptr/shared_ptr.hpp:216
#4  0x000000000068db48 in boost::weak_ptr<RtmpConnection>::lock (this=0x7fffe0e87e68)
    at /usr/local/include/boost/smart_ptr/weak_ptr.hpp:157

Я проверил сбой линии в /usr/local/include/boost/smart_ptr/detail/sp_counted_base_gcc_x86.hpp

 69 inline int atomic_conditional_increment( int * pw )
 70 {
 71     // int rv = *pw;
 72     // if( rv != 0 ) ++*pw;
 73     // return rv;
 74
 75     int rv, tmp;
 76
 77     __asm__
 78     (
 79         "movl %0, %%eax\n\t"
 80         "0:\n\t"
 81         "test %%eax, %%eax\n\t"
 82         "je 1f\n\t"
 83         "movl %%eax, %2\n\t"
 84         "incl %2\n\t"
 85         "lock\n\t"
 86         "cmpxchgl %2, %0\n\t"
 87         "jne 0b\n\t"
 88         "1:":
 89         "=m"( *pw ), "=&a"( rv ), "=&r"( tmp ): // outputs (%0, %1, %2)
 90         "m"( *pw ): // input (%3)
 91         "cc" // clobbers
 92     );
 93
 94     return rv;
 95 }

Строка 92 - это код сборки. Я действительно не знаю, что это значит.

Я всегда проверяю, возвращен ли boost::weakptr<RtmpConnection>.lock() (тип boost::shared_ptr<RtmpConnection> пуст, прежде чем я его использовал.

Так что я погуглил, я увидел это http://wiki.inkscape.org/wiki/index.php/Boost_shared_pointers

Слабые указатели не могут быть разыменованы по соображениям безопасности потоков. Если какой-то другой поток уничтожил объект после того, как вы проверили слабый указатель на срок действия, но прежде чем использовать его, вы получите сбой

  1. Так что мне делать, чтобы с этим справиться, почему он падает (кажется, boost::weakptr<RtmpConnection>.lock() никогда не должен падать)?
  2. Так как моя программа многопоточная. Возможно, что после того, как я получу и проверим возвращаемое значение boost::weakptr<RtmpConnection>.lock(), RtmpConnection может быть уничтожен другим потоком, гарантирует ли Boost Library, что оно не будет уничтожено, поскольку тип возвращаемого значения boost::shared_ptr<RtmpConnection>?

1 Ответ

1 голос
/ 30 марта 2012

Скорее всего, вы нарушаете одно из правил для правильного использования умных указателей.Вот наиболее распространенные нарушения правил интеллектуальных указателей:

  1. На объект можно ссылаться только через одну цепочку интеллектуальных указателей.В идеале создайте умный указатель с объектом, используя make_shared, и никогда не используйте необработанный указатель.Но в противном случае создайте умный указатель из обычного указателя только один раз.

  2. Создайте только слабый указатель из сильного указателя объекта.(Или вы можете использовать shared_from_this, если объект поддерживает его.)

  3. Объект не должен быть уничтожен путем вызова delete, пока на него ссылается умный указатель.В идеале, вы бы никогда не вызвали delete для объекта, который когда-либо имел какой-либо умный указатель, ссылающийся на него.Во-первых, у вас есть ошибка, приводящая к повреждению памяти, например, перезапись границ массива, двойное освобождение, доступ после освобождения и так далее.Вы можете проверить ошибку повреждения памяти с помощью такого инструмента, как valgrind.

    Наконец, вы, возможно, неправильно скомпилировали свой код или неправильно скомпилировали Boost.Например, ваша платформа может иметь параметры компилятора, которые необходимо включить для компиляции поточно-ориентированного кода.(Вы не упомянули свою платформу, поэтому я не могу дать вам подробности.)

...