LINUX.ORG.RU

C++ и аллокаторы std::vector

 ,


1

1

Нужен направляющий пинок. Имеется вектор, с переопределенным аллокатором tbb::tbb_allocator. Переопределены операторы new и delete на использование scalable_malloc/free из того же tbb. И со всем этим добром творится непонятная хрень: push_back в этот вектор приводит к сегфолту, но не всегда, и каждый раз в разных местах. Подозреваю, что есть некая гонка в разных потоках, но понять где именно, не могу. Минимальный пример для воспроизведения тоже не смог сделать - 1М элементов в 8 потоков прекрасно добавились и ни разу не упали. Подскажите, куда еще можно копать, у меня идеи кончились вообще, а понимание происходящего кончилось еще раньше.

★★★★★

Добавлю, раньше падений было сильно больше, после выпила tbbmalloc_proxy стало сильно лучше, но почему так, нет ни малейшего представления.

eagleivg ★★★★★
() автор топика

Я не специалист, но вроде бы стандартные контейнеры в STL - не потокобезопасны на модификацию. Надо руками синхронизировать.

Deleted
()
Ответ на: комментарий от slovazap

В тесте обмазал parallel_for. В коде потоки синхрятся через мутексы. И самое главное, под виндой эта хрень работает!:(

eagleivg ★★★★★
() автор топика
Ответ на: комментарий от anonymous

Конкурентный еще не пробовал, спасибо. Хотя и хотелось бы понять, что вообще происходит. Пока только ясно, что проблема связана с аллокацией, причем даже не tbb-шной, замена на std не приводит к изменению поведения. Правда, под виндой почему-то при этом ломается...

eagleivg ★★★★★
() автор топика
Последнее исправление: eagleivg (всего исправлений: 1)
Ответ на: комментарий от hizel

Ахрененно! аллокаторы тут не при чем, тут стэк рвет в клочья. Во-первых, старый знакомый LuaJIT со своим кривым str_fastcmp() и во вторых:

==20141==ERROR: AddressSanitizer: stack-buffer-overflow on address 0x7ffc5a8a534c at pc 0x7f2f6107f88c bp 0x7ffc5a8a51c0 sp 0x7ffc5a8a51b0
READ of size 4 at 0x7ffc5a8a534c thread T0 (X-RAY Primary t)
    #0 0x7f2f6107f88b in dJointSetFixedQuaternionPos /home/builder/workspace/xray-16/Externals/ode/ode/src/joint.cpp:2802
    #1 0x7f2f639005d1 in CPhysicsShellAnimator::OnFrame() /home/builder/workspace/xray-16/src/xrPhysics/PhysicsShellAnimator.cpp:101
    #2 0x7f2f3a68ede6 in CPhysicObject::UpdateCL() /home/builder/workspace/xray-16/src/xrGame/PhysicObject.cpp:333
    #3 0x7f2f65d2e449 in CObjectList::SingleUpdate(IGameObject*) /home/builder/workspace/xray-16/src/xrEngine/xr_object_list.cpp:142
    #4 0x7f2f65d36df2 in CObjectList::Update(bool) /home/builder/workspace/xray-16/src/xrEngine/xr_object_list.cpp:275
    #5 0x7f2f65d0311d in IGame_Level::OnFrame() /home/builder/workspace/xray-16/src/xrEngine/IGame_Level.cpp:178
    #6 0x7f2f3a393fb2 in CLevel::OnFrame() /home/builder/workspace/xray-16/src/xrGame/Level.cpp:462
    #7 0x7f2f65de115f in MessageRegistry<pureFrame>::Process() /home/builder/workspace/xray-16/src/xrEngine/pure.h:103
    #8 0x7f2f65de115f in CRenderDevice::FrameMove() /home/builder/workspace/xray-16/src/xrEngine/device.cpp:503
    #9 0x7f2f65de5531 in CRenderDevice::on_idle() /home/builder/workspace/xray-16/src/xrEngine/device.cpp:256
    #10 0x7f2f65df2877 in CRenderDevice::message_loop() /home/builder/workspace/xray-16/src/xrEngine/device.cpp:408
    #11 0x7f2f65df3a8c in CRenderDevice::Run() /home/builder/workspace/xray-16/src/xrEngine/device.cpp:444
    #12 0x7f2f65e219db in Startup() /home/builder/workspace/xray-16/src/xrEngine/main.cpp:200
    #13 0x7f2f65e23be2 in RunApplication() /home/builder/workspace/xray-16/src/xrEngine/main.cpp:290
    #14 0x401f70 in entry_point(char const*) /home/builder/workspace/xray-16/src/xr_3da/entry_point.cpp:45
    #15 0x40174b in main /home/builder/workspace/xray-16/src/xr_3da/entry_point.cpp:102
    #16 0x7f2f64c2482f in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x2082f)
    #17 0x401c88 in _start (/home/builder/workspace/xray-16-build/src/xr_3da/xr_3da+0x401c88)

Address 0x7ffc5a8a534c is located in stack of thread T0 (X-RAY Primary t) at offset 300 in frame
    #0 0x7f2f638ffdef in CPhysicsShellAnimator::OnFrame() /home/builder/workspace/xray-16/src/xrPhysics/PhysicsShellAnimator.cpp:79

  This frame has 8 object(s):
    [32, 40) '__for_begin'
    [96, 104) '__for_end'
    [160, 168) '<unknown>'
    [224, 232) '<unknown>'
    [288, 300) 'mc' <== Memory access at offset 300 overflows this variable
    [352, 368) 'target_obj_quat_dQuaternionS'
    [416, 464) 'ph_mat'
    [512, 576) 'target_obj_posFmatrixS'


В общем, огромное спасибо за наводку!

eagleivg ★★★★★
() автор топика
Ответ на: комментарий от hizel

Блин, рано радовался:(

==27054==ERROR: AddressSanitizer: SEGV on unknown address 0x000000000008 (pc 0x7f6c97dd0231 bp 0x7ffccebb5e70 sp 0x7ffccebb5c40 T0)
==27054==The signal is caused by a READ memory access.
==27054==Hint: address points to the zero page.
    #0 0x7f6c97dd0230 in std::_Hashtable<STextureList*, std::pair<STextureList* const, R_dsgraph::mapNormalItems>, tbb::tbb_allocator<std::pair<STextureList* const, R_dsgraph::mapNormalItems> >, std::__detail::_Select1st, std::equal_to<STextureList*>, std::hash<STextureList*>, std::__detail::_Mod_range_hashing, std::__detail::_Default_ranged_hash, std::__detail::_Prime_rehash_policy, std::__detail::_Hashtable_traits<false, false, true> >::_M_find_before_node(unsigned long, STextureList* const&, unsigned long) const /usr/include/c++/7/bits/hashtable.h:1545
    #1 0x7f6c97dd0230 in std::_Hashtable<STextureList*, std::pair<STextureList* const, R_dsgraph::mapNormalItems>, tbb::tbb_allocator<std::pair<STextureList* const, R_dsgraph::mapNormalItems> >, std::__detail::_Select1st, std::equal_to<STextureList*>, std::hash<STextureList*>, std::__detail::_Mod_range_hashing, std::__detail::_Default_ranged_hash, std::__detail::_Prime_rehash_policy, std::__detail::_Hashtable_traits<false, false, true> >::_M_find_node(unsigned long, STextureList* const&, unsigned long) const /usr/include/c++/7/bits/hashtable.h:642
    #2 0x7f6c97dd0230 in std::__detail::_Map_base<STextureList*, std::pair<STextureList* const, R_dsgraph::mapNormalItems>, tbb::tbb_allocator<std::pair<STextureList* const, R_dsgraph::mapNormalItems> >, std::__detail::_Select1st, std::equal_to<STextureList*>, std::hash<STextureList*>, std::__detail::_Mod_range_hashing, std::__detail::_Default_ranged_hash, std::__detail::_Prime_rehash_policy, std::__detail::_Hashtable_traits<false, false, true>, true>::operator[](STextureList*&&) /usr/include/c++/7/bits/hashtable_policy.h:746
    #3 0x7f6c97dc1c08 in std::unordered_map<STextureList*, R_dsgraph::mapNormalItems, std::hash<STextureList*>, std::equal_to<STextureList*>, tbb::tbb_allocator<std::pair<STextureList* const, R_dsgraph::mapNormalItems> > >::operator[](STextureList*&&) /usr/include/c++/7/bits/unordered_map.h:980
    #4 0x7f6c97dc1c08 in D3DXRenderBase::r_dsgraph_insert_static(dxRender_Visual*) /home/builder/workspace/xray-16/src/Layers/xrRender/r__dsgraph_build.cpp:297
    #5 0x7f6c97dc467e in CRender::add_Static(dxRender_Visual*, unsigned int) /home/builder/workspace/xray-16/src/Layers/xrRender/r__dsgraph_build.cpp:727
    #6 0x7f6c97dc568b in CRender::add_Static(dxRender_Visual*, unsigned int) /home/builder/workspace/xray-16/src/Layers/xrRender/r__dsgraph_build.cpp:672
    #7 0x7f6c97dc568b in CRender::add_Static(dxRender_Visual*, unsigned int) /home/builder/workspace/xray-16/src/Layers/xrRender/r__dsgraph_build.cpp:672
    #8 0x7f6c979c7266 in CRender::render_main(_matrix<float>&, bool) /home/builder/workspace/xray-16/src/Layers/xrRenderPC_GL/gl_R_render.cpp:89
    #9 0x7f6c979cba50 in CRender::Render() /home/builder/workspace/xray-16/src/Layers/xrRenderPC_GL/gl_R_render.cpp:323
    #10 0x7f6c7f03d7d8 in CLevel::OnRender() /home/builder/workspace/xray-16/src/xrGame/Level.cpp:595
    #11 0x7f6caef51250 in MessageRegistry<pureRender>::Process() /home/builder/workspace/xray-16/src/xrEngine/pure.h:103
    #12 0x7f6caef51250 in CRenderDevice::on_idle() /home/builder/workspace/xray-16/src/xrEngine/device.cpp:301
    #13 0x7f6caef5c7b7 in CRenderDevice::message_loop() /home/builder/workspace/xray-16/src/xrEngine/device.cpp:411
    #14 0x7f6caef5da2a in CRenderDevice::Run() /home/builder/workspace/xray-16/src/xrEngine/device.cpp:447
    #15 0x7f6caf0151be in Startup() /home/builder/workspace/xray-16/src/xrEngine/main.cpp:200
    #16 0x7f6caf017496 in RunApplication() /home/builder/workspace/xray-16/src/xrEngine/main.cpp:290
    #17 0x55e2636635c8 in entry_point(char const*) /home/builder/workspace/xray-16/src/xr_3da/entry_point.cpp:45
    #18 0x55e263662d28 in main /home/builder/workspace/xray-16/src/xr_3da/entry_point.cpp:102
    #19 0x7f6caddb6b96 in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x21b96)
    #20 0x55e263663289 in _start (/home/builder/workspace/build-xray-16/src/xr_3da/xr_3da+0x2289)

AddressSanitizer can not provide additional info.
SUMMARY: AddressSanitizer: SEGV /usr/include/c++/7/bits/hashtable.h:1545 in std::_Hashtable<STextureList*, std::pair<STextureList* const, R_dsgraph::mapNormalItems>, tbb::tbb_allocator<std::pair<STextureList* const, R_dsgraph::mapNormalItems> >, std::__detail::_Select1st, std::equal_to<STextureList*>, std::hash<STextureList*>, std::__detail::_Mod_range_hashing, std::__detail::_Default_ranged_hash, std::__detail::_Prime_rehash_policy, std::__detail::_Hashtable_traits<false, false, true> >::_M_find_before_node(unsigned long, STextureList* const&, unsigned long) const
==27054==ABORTING

eagleivg ★★★★★
() автор топика
Ответ на: комментарий от eagleivg

Вот это место:

        auto &Nstate = Ncs[&*pass.state];
        auto &Ntex = Nstate[pass.T._get()];
        Ntex.push_back(item);
maxis11 ты вроде что-то упоминал про tbb? И Meyer?

eagleivg ★★★★★
() автор топика
Последнее исправление: eagleivg (всего исправлений: 3)
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.