Почему я получаю сегфолты случайно? - PullRequest
3 голосов
/ 21 мая 2009

Это довольно странно для меня, но я получаю неожиданную и случайную ошибку сегментации при запуске моей программы. Иногда это работает, иногда - происходит сбой. Отладчик Dev-C ++ указывает мне на строку файла: stl_construct.h

/**
   * @if maint
   * Constructs an object in existing memory by invoking an allocated
   * object's constructor with an initializer.
   * @endif
   */
  template<typename _T1, typename _T2>
    inline void
    _Construct(_T1* __p, const _T2& __value)
    {
      // _GLIBCXX_RESOLVE_LIB_DEFECTS
      // 402. wrong new expression in [some_]allocator::construct
     -> ::new(static_cast<void*>(__p)) _T1(__value);
    }

Кстати, я широко использую STL. Что мне делать, чтобы определить происхождение сегфо? Есть ли инструменты, которые могут помочь? Каковы причины, которые могут привести к случайным сбоям, подобным этому.

Edit:

Моя программа насчитывает около 5000 строк кода. Я не знаю, какой фрагмент кода мне нужно показать, чтобы получить некоторую помощь, поскольку я понятия не имею о происхождении проблемы, все, что я получил от отладчика, - это то, что он имеет отношение к STL.

Edit:

Я перешел на Code::Blocks сейчас, вот стек вызовов:

#0 00464635 std::_Construct<std::pair<double const, int>, std::pair<double const, int> >(__p=0xb543e8, __value=@0x10) (C:/Program Files/CodeBlocks/MinGW/bin/../lib/gcc/mingw32/3.4.5/../../../../include/c++/3.4.5/bits/stl_construct.h:81)
#1 00462306 std::_Rb_tree<double, std::pair<double const, int>, std::_Select1st<std::pair<double const, int> >, std::less<double>, std::allocator<std::pair<double const, int> > >::_M_create_node(this=0x406fe50, __x=@0x10) (C:/Program Files/CodeBlocks/MinGW/bin/../lib/gcc/mingw32/3.4.5/../../../../include/c++/3.4.5/bits/stl_tree.h:367)
#2 00461DA7 std::_Rb_tree<double, std::pair<double const, int>, std::_Select1st<std::pair<double const, int> >, std::less<double>, std::allocator<std::pair<double const, int> > >::_M_clone_node(this=0x406fe50, __x=0x0) (C:/Program Files/CodeBlocks/MinGW/bin/../lib/gcc/mingw32/3.4.5/../../../../include/c++/3.4.5/bits/stl_tree.h:379)
#3 004625C6 std::_Rb_tree<double, std::pair<double const, int>, std::_Select1st<std::pair<double const, int> >, std::less<double>, std::allocator<std::pair<double const, int> > >::_M_copy(this=0x406fe50, __x=0x0, __p=0x406fe54) (C:/Program Files/CodeBlocks/MinGW/bin/../lib/gcc/mingw32/3.4.5/../../../../include/c++/3.4.5/bits/stl_tree.h:1029)
#4 00462A9D std::_Rb_tree<double, std::pair<double const, int>, std::_Select1st<std::pair<double const, int> >, std::less<double>, std::allocator<std::pair<double const, int> > >::_Rb_tree(this=0x406fe50, __x=@0xb59a7c) (C:/Program Files/CodeBlocks/MinGW/bin/../lib/gcc/mingw32/3.4.5/../../../../include/c++/3.4.5/bits/stl_tree.h:559)
#5 0045A928 std::map<double, int, std::less<double>, std::allocator<std::pair<double const, int> > >::map(this=0x406fe50, __x=@0xb59a7c) (C:/Program Files/CodeBlocks/MinGW/bin/../lib/gcc/mingw32/3.4.5/../../../../include/c++/3.4.5/bits/stl_map.h:166)
#6 0040B7E2 VehicleManager::get_vehicles_distances(this=0xb59a50) (C:/Program Files/CodeBlocks/MinGW/projects/AHS/VehicleManager.cpp:232)
#7 00407BDA Supervisor::IsMergeInstruction(id_vehicle=1) (C:/Program Files/CodeBlocks/MinGW/projects/AHS/Supervisor.cpp:77)
#8 00408430 CheckingInstructionsThread(arg=0x476100) (C:/Program Files/CodeBlocks/MinGW/projects/AHS/Supervisor.cpp:264)
#9 00413950 _glfwNewThread@4() (??:??)
#10 75A24911    KERNEL32!AcquireSRWLockExclusive() (C:\Windows\system32\kernel32.dll:??)
#11 00476100    std::__ioinit() (??:??)
#12 0406FFD4    ??() (??:??)
#13 76E5E4B6    ntdll!RtlInitializeNtUserPfn() (C:\Windows\system32\ntdll.dll:??)
#14 00476100    std::__ioinit() (??:??)
#15 70266582    ??() (??:??)
#16 00000000    ??() (??:??)

Еще несколько точностью:

1 / Это многопоточное приложение. 2 / Метод: get_vehicles_distances (); возвращает карту. 3 / Возможно, карта не инициализируется к тому времени, когда она вызывается IsMergeInstruction ();

Edit:

Видимо, строка, вызывающая ошибку segault:

vehicles_distances_.erase(vehicles_distances_.begin(), vehicles_distances_.end());

Где vehicle_distances_ - Карта. Эта строка является частью метода: VehicleManager :: MoveAllVehicles ();

void VehicleManager::MoveAllVehicles() {

     vehicles_distances_.erase(vehicles_distances_.begin(), vehicles_distances_.end());

     vector<Vehicle>::iterator iter_end = VehicleManager::vehicles_.end();
     for(vector<Vehicle>::iterator iter = VehicleManager::vehicles_.begin();
     iter != iter_end; ++iter) {

          (*iter).MoveVehicle();

          vehicles_distances_[(*iter).get_vec_vehicle_position().y] = (*iter).get_id_vehicle();

     }

}

Что с этим не так?

Edit:

Я пытался использовать map :: clear (); в качестве замены для сопоставления :: erase (); но такая же проблема возникает!

Edit:

Я думаю, я понял ... Поток пытается использовать Vehicles_distances_, пока он очищен .. (?)

Edit:

Проблема решена! Так оно и было с карты :: erase (); как и ожидалось. я обошел проблему, создав другую переменную карты, где пара <key, value> была инвертирована, чтобы я мог обновить карту. (поскольку ключ, который мне нужен, это расстояние, а расстояние не уникально, так как оно меняется каждый раз, но id_vehicle уникален!). В конце я просто взял эту карту, снова инвертировал <key, value> и перенес ее на исходную карту, которую можно повторно объявить в каждом цикле ...

Спасибо всем!

Ответы [ 13 ]

1 голос
/ 21 мая 2009

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

1 голос
/ 21 мая 2009

о чем говорит трассировка стека после запуска отладчика с файлом core? запустить GDB нормальным способом GDB a.out

затем изучите файл ядра

core a.out.core

И взгляните на стопку

Ь

0 голосов
/ 21 мая 2009

Отладчик должен позволить вам подняться в стек вызовов. Таким образом, вы сможете увидеть место в своем собственном коде, которое вызывает ошибку сегмента.

...