2012-03-30 3 views
1

(EDIT) Окружающая среда SIGSEGV Сегментация Fault:повышение :: weak_ptr <T> .lock() Сбои с

[email protected]:/usr/local/include/boost$ lsb_release -a 
No LSB modules are available. 
Distributor ID: Ubuntu 
Description: Ubuntu 11.10 
Release:  11.10 
Codename:  oneiric 

[email protected]:/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 
[email protected]:/usr/local/include/boost$ 

[email protected]:/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, такие как, boost::asio, boost::shared_ptr и boost::weak_ptr.

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

замок

shared_ptr замок() Const; Возвращает: expired()? shared_ptr(): shared_ptr (* this).

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

Однако в моем приложении, он даже упал:

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, что она не будет уничтожена, потому что тип возврата boost::shared_ptr<RtmpConnection>?
+0

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

+0

@David, но сам метод 'lock()' НЕ должен быть сбой, не так ли? Если он уже уничтожен, он должен вернуть пустой 'shared_ptr <>', правильно? Кстати, какой вариант можно включить для компиляции потокобезопасного кода в Boost? –

+0

Метод блокировки будет сбой, если объект был * неправильно * уничтожен. Например, если он был уничтожен, в то время как сильный указатель все еще ссылался на него или ссылался на более чем одну цепочку интеллектуальных указателей. Нет возможности компилировать потокобезопасный код в Boost - это будет вариант в компиляторе для любой платформы, которую вы используете. –

ответ

1

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

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

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

  3. Нельзя уничтожать объект, вызывая delete, в то время как к нему относится смарт-указатель. В идеале вы никогда не будете звонить delete на объект, который когда-либо имел какой-либо умный указатель.

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

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

+0

Я очень тщательно проверил правила, которые, возможно, нарушил, насколько мне известно, я не нарушил ни одно из правил, о которых вы говорили. Так что теперь я делаю чек. Меня волнует, что valgrind значительно замедляет работу приложения, и эта ошибка может быть воспроизведена (иногда также) при тестировании нагрузки 50 или 100 клиентов. –

+0

вы уверены, что valgrind выполняется действительно параллельно? valgrind может сериализовать выполнение через превентивный планировщик, встроенный в его виртуальную машину C++. –

Смежные вопросы