Re[13]: Ты не понял что это и для чего.
От: B0FEE664  
Дата: 19.12.18 13:22
Оценка:
Здравствуйте, Sheridan, Вы писали:

BFE>>Из всего этого следует, что объекты типа CDynamicMesh никогда сами не удаляются. Из этого следует, что на объекты CBlock указатели хранятся где-то снаружи CDynamicMesh и там же уничтожаются. Т.е. мы поняли архитектуру: элементы списка владеют своим списком. Они сами себя из списка удаляют, но добавляют их в список внешним образом:

S>Когда блок рождается — он спрашивает соседей про их свойства. При совпадении некоторых свойств блок понимает что самостоятельно отрисовываться будет тяжело и запрашивает у соседа ссылку на динамикмеш, в который добавляет себя. Динамикмеш занимается тем что создаёт одну ноду на множество блоков.
S>Время жизни блоков разное зависит от разных факторов. При удалении блока он сообщает мешу о своей смерти. И когда, сообщив, видит что меш осиротел — забирает его с собой.

Значит я всё правильно понял. Если block->m_dynamicMesh везде правильно установлен и сам динамикмеш нигде не удаляется, то может это и будет работать...
Какой, всё же, тип у CDynamicMesh::m_blocks?

BFE>>Вы видите, чтобы block->m_dynamicMesh устанавливался в this в этом методе? Не удивлюсь, если окажется, что recalculate() проходит по списку элементов им устанавливает каждому элементу m_dynamicMesh в this.

S>Нет. В recalculate расчитываются вершины и индексы получающейся фигуры и фигура закидывается в модель чтобы рендерилось.
А где m_dynamicMesh присваивается?
И каждый день — без права на ошибку...
Re[10]: Крашит в дебрях std при работе с ofstream
От: Sheridan Россия  
Дата: 19.12.18 13:50
Оценка:
Здравствуйте, Skorodum, Вы писали:

S>>
S>>class CSingleTone
S>...
S>>

S>FYI: Singleton
S>Ну и префикс "С" для классов это болезнь из 90х...
В следующий раз класс назову "горшок", чтобы вместо двух пертензий была одна.

Я хз какой доктор какие у вас болезни диагностирует.
У меня так:
class — C...
struct — S...
enum — E...
typedef — T...

private class member — m_...
Matrix has you...
Re[2]: Крашит в дебрях std при работе с ofstream
От: zongang  
Дата: 19.12.18 13:54
Оценка:
Здравствуйте, zongang, Вы писали:

Ну и, после исследования сорсов glibc в районе malloc, надо будет понять, какое место в памяти портится, при последующих запусках на более ранних этапах выяснить новый адрес потенциально интересного куска, и сделать в gdb watch *0x00fffe — этого адреса.

так же, интересна выдача valgrind — в С++ не бывает проблем в чужом коде, адресное пространство общее, в таком случае обязан был показать проблему valgrind.

Z>Здравствуйте, Sheridan, Вы писали:


Z>Тут без вариантов уничтожены внутренние структуры управления памятью, используемые malloc.


Z>Что делать дальше — использовать смарт-поинтеры везде, это может решить проблему с испорченной памятью.

Z>Если нет желания использовать смарт-поинтеры — надо понимать, что имея ту информацию, которая сейчас предоставлена — разрешить проблему невозможно. Нужно иметь и уметь следующие вещи:

Z>- В Вашем gentoo с дебаг-символами и исходниками надо собрать так же glibc.

Z>- Научиться пользоваться valgrind и прогнать программу с под ним.
Z>- Научится читать и понимать дизассемблированный код в gdb, анализировать регистры и память, адреса на которую могут лежать в регистрах, в данном случае неплохо было бы изучить код и память в районе malloc_consolidate — именно там срабатывает assertion в макросе unlink, подозреваю.

Z>Если нет большего желания разбираться с последними тремя пунктами, стоит вернуться к идее со смарт-поинтерами, либо сменить язык разработки.


S>>Камрады, ай нид хелп. Не могу понять в чом дело. У меня тут есть логгер, который крашится в рантайме но в дебаге но полезного нет почти.

S>>При запущенной валгринд с мемчеком — не крашится.
S>>Принцип такой: при добавлении строки оно открывает ofstream в файл, пишет туда строку, закрывает.
S>>Крашится как раз на открытии ofstream
S>>
S>>m_logstream.open(m_filename, std::ofstream::out | std::ofstream::ate | std::ofstream::app);
S>>


S>>m_filename — std::string

S>>m_logstream — std::ofstream

S>>Через раз показывает причину:

S>>
S>>malloc_consolidate(): invalid chunk size
S>>


S>>Я предполагал что это краш в другом потоке, но уже дважды всё там переписал — не должно

S>>Ну и крашится на вызове логгера из деструктора объекта. При этом оно к объекту самому разрушаемому не обращается
S>>сам логгер — синглтон, создаётся при первом обращении, удаляется при выходе из приложения

S>>Полный стек вызовов, крашится в Thread 1:

S>>

S>>Thread 7 (Thread 0x7fffc68e1700 (LWP 31402)):
S>>#0  0x00007ffff595b6c6 in ppoll () from /lib64/libc.so.6
S>>No symbol table info available.
S>>#1  0x00007ffff36ab901 in pa_mainloop_poll () from /usr/lib64/libpulse.so.0
S>>No symbol table info available.
S>>#2  0x00007ffff36abf10 in pa_mainloop_iterate () from /usr/lib64/libpulse.so.0
S>>No symbol table info available.
S>>#3  0x00007ffff780c2a7 in PULSEAUDIO_WaitDevice () from /usr/lib/Urho3D/libUrho3D.so.0
S>>No symbol table info available.
S>>#4  0x00007ffff779442e in SDL_RunAudio () from /usr/lib/Urho3D/libUrho3D.so.0
S>>No symbol table info available.
S>>#5  0x00007ffff779375c in SDL_RunThread () from /usr/lib/Urho3D/libUrho3D.so.0
S>>No symbol table info available.
S>>#6  0x00007ffff7809ac9 in RunThread () from /usr/lib/Urho3D/libUrho3D.so.0
S>>No symbol table info available.
S>>#7  0x00007ffff5c3296a in start_thread () from /lib64/libpthread.so.0
S>>No symbol table info available.
S>>#8  0x00007ffff59671af in clone () from /lib64/libc.so.6
S>>No symbol table info available.

S>>Thread 6 (Thread 0x7fffd72e2700 (LWP 31401)):
S>>#0  0x00007ffff5c3d30c in __lll_lock_wait () from /lib64/libpthread.so.0
S>>No symbol table info available.
S>>#1  0x00007ffff5c357a2 in pthread_mutex_lock () from /lib64/libpthread.so.0
S>>No symbol table info available.
S>>#2  0x00007ffff73401cf in Urho3D::WorkQueue::ProcessItems(unsigned int) () from /usr/lib/Urho3D/libUrho3D.so.0
S>>No symbol table info available.
S>>#3  0x00007ffff7339f1a in Urho3D::ThreadFunctionStatic(void*) () from /usr/lib/Urho3D/libUrho3D.so.0
S>>No symbol table info available.
S>>#4  0x00007ffff5c3296a in start_thread () from /lib64/libpthread.so.0
S>>No symbol table info available.
S>>#5  0x00007ffff59671af in clone () from /lib64/libc.so.6
S>>No symbol table info available.

S>>Thread 5 (Thread 0x7fffd7ae3700 (LWP 31400)):
S>>#0  0x00007ffff5c3d30c in __lll_lock_wait () from /lib64/libpthread.so.0
S>>No symbol table info available.
S>>#1  0x00007ffff5c357a2 in pthread_mutex_lock () from /lib64/libpthread.so.0
S>>No symbol table info available.
S>>#2  0x00007ffff73401cf in Urho3D::WorkQueue::ProcessItems(unsigned int) () from /usr/lib/Urho3D/libUrho3D.so.0
S>>No symbol table info available.
S>>#3  0x00007ffff7339f1a in Urho3D::ThreadFunctionStatic(void*) () from /usr/lib/Urho3D/libUrho3D.so.0
S>>No symbol table info available.
S>>#4  0x00007ffff5c3296a in start_thread () from /lib64/libpthread.so.0
S>>No symbol table info available.
S>>#5  0x00007ffff59671af in clone () from /lib64/libc.so.6
S>>No symbol table info available.

S>>Thread 4 (Thread 0x7fffd82e4700 (LWP 31399)):
S>>#0  0x00007ffff5c3d30c in __lll_lock_wait () from /lib64/libpthread.so.0
S>>No symbol table info available.
S>>#1  0x00007ffff5c357a2 in pthread_mutex_lock () from /lib64/libpthread.so.0
S>>No symbol table info available.
S>>#2  0x00007ffff73401cf in Urho3D::WorkQueue::ProcessItems(unsigned int) () from /usr/lib/Urho3D/libUrho3D.so.0
S>>No symbol table info available.
S>>#3  0x00007ffff7339f1a in Urho3D::ThreadFunctionStatic(void*) () from /usr/lib/Urho3D/libUrho3D.so.0
S>>No symbol table info available.
S>>#4  0x00007ffff5c3296a in start_thread () from /lib64/libpthread.so.0
S>>No symbol table info available.
S>>#5  0x00007ffff59671af in clone () from /lib64/libc.so.6
S>>No symbol table info available.

S>>Thread 3 (Thread 0x7fffdbfff700 (LWP 31398)):
S>>#0  0x00007ffff5c3e138 in nanosleep () from /lib64/libpthread.so.0
S>>No symbol table info available.
S>>#1  0x00000000004b0f90 in std::this_thread::sleep_for<long, std::ratio<1l, 1000l> > (__rtime=...) at /usr/lib/gcc/x86_64-pc-linux-gnu/7.3.0/include/g++-v7/thread:376
S>>        __s = {__r = 0}
S>>        __ns = {__r = 100000000}
S>>        __ts = {tv_sec = 0, tv_nsec = 36163799}
S>>#2  0x00000000004b06b5 in eing::world::CWorld::worldThread (this=0x7b4640) at ../../../src/world/cworld.cpp:89
S>>No locals.
S>>#3  0x00000000004b2e41 in std::__invoke_impl<void, void (eing::world::CWorld::*)(), eing::world::CWorld*> (__f=@0x839ac0: (void (eing::world::CWorld::*)(eing::world::CWorld * const)) 0x4b0660 <eing::world::CWorld::worldThread()>, __t=@0x839ab8: 0x7b4640) at /usr/lib/gcc/x86_64-pc-linux-gnu/7.3.0/include/g++-v7/bits/invoke.h:73
S>>No locals.
S>>#4  0x00000000004b2d52 in std::__invoke<void (eing::world::CWorld::*)(), eing::world::CWorld*> (__fn=@0x839ac0: (void (eing::world::CWorld::*)(eing::world::CWorld * const)) 0x4b0660 <eing::world::CWorld::worldThread()>, __args=@0x839ab8: 0x7b4640) at /usr/lib/gcc/x86_64-pc-linux-gnu/7.3.0/include/g++-v7/bits/invoke.h:95
S>>No locals.
S>>#5  0x00000000004b2d12 in std::thread::_Invoker<std::tuple<void (eing::world::CWorld::*)(), eing::world::CWorld*> >::_M_invoke<0ul, 1ul> (this=0x839ab8) at /usr/lib/gcc/x86_64-pc-linux-gnu/7.3.0/include/g++-v7/thread:234
S>>No locals.
S>>#6  0x00000000004b2cc5 in std::thread::_Invoker<std::tuple<void (eing::world::CWorld::*)(), eing::world::CWorld*> >::operator() (this=0x839ab8) at /usr/lib/gcc/x86_64-pc-linux-gnu/7.3.0/include/g++-v7/thread:243
S>>No locals.
S>>#7  0x00000000004b2a99 in std::thread::_State_impl<std::thread::_Invoker<std::tuple<void (eing::world::CWorld::*)(), eing::world::CWorld*> > >::_M_run (this=0x839ab0) at /usr/lib/gcc/x86_64-pc-linux-gnu/7.3.0/include/g++-v7/thread:186
S>>No locals.
S>>#8  0x00007ffff6142f0e in std::execute_native_thread_routine (__p=0x839ab0) at /data/tmp/portage/sys-devel/gcc-7.3.0-r3/work/gcc-7.3.0/libstdc++-v3/src/c++11/thread.cc:83
S>>        __t = {_M_t = {_M_t = {<std::_Tuple_impl<0, std::thread::_State*, std::default_delete<std::thread::_State> >> = {<std::_Tuple_impl<1, std::default_delete<std::thread::_State> >> = {<std::_Head_base<1, std::default_delete<std::thread::_State>, true>> = {<std::default_delete<std::thread::_State>> = {<No data fields>}, <No data fields>}, <No data fields>}, <std::_Head_base<0, std::thread::_State*, false>> = {_M_head_impl = 0x839ab0}, <No data fields>}, <No data fields>}}}
S>>#9  0x00007ffff5c3296a in start_thread () from /lib64/libpthread.so.0
S>>No symbol table info available.
S>>#10 0x00007ffff59671af in clone () from /lib64/libc.so.6
S>>No symbol table info available.

S>>Thread 2 (Thread 0x7ffff7fed700 (LWP 31397)):
S>>#0  0x00007ffff595b6c6 in ppoll () from /lib64/libc.so.6
S>>No symbol table info available.
S>>#1  0x00007ffff36ab901 in pa_mainloop_poll () from /usr/lib64/libpulse.so.0
S>>No symbol table info available.
S>>#2  0x00007ffff36abf10 in pa_mainloop_iterate () from /usr/lib64/libpulse.so.0
S>>No symbol table info available.
S>>#3  0x00007ffff36abfa0 in pa_mainloop_run () from /usr/lib64/libpulse.so.0
S>>No symbol table info available.
S>>#4  0x00007ffff780c40f in HotplugThread () from /usr/lib/Urho3D/libUrho3D.so.0
S>>No symbol table info available.
S>>#5  0x00007ffff779375c in SDL_RunThread () from /usr/lib/Urho3D/libUrho3D.so.0
S>>No symbol table info available.
S>>#6  0x00007ffff7809ac9 in RunThread () from /usr/lib/Urho3D/libUrho3D.so.0
S>>No symbol table info available.
S>>#7  0x00007ffff5c3296a in start_thread () from /lib64/libpthread.so.0
S>>No symbol table info available.
S>>#8  0x00007ffff59671af in clone () from /lib64/libc.so.6
S>>No symbol table info available.

S>>Thread 1 (Thread 0x7ffff7f830c0 (LWP 31391)):
S>>#0  0x00007ffff589976b in raise () from /lib64/libc.so.6
S>>No symbol table info available.
S>>#1  0x00007ffff589afb1 in abort () from /lib64/libc.so.6
S>>No symbol table info available.
S>>#2  0x00007ffff58e02e7 in __libc_message () from /lib64/libc.so.6
S>>No symbol table info available.
S>>#3  0x00007ffff58e8038 in malloc_printerr () from /lib64/libc.so.6
S>>No symbol table info available.
S>>#4  0x00007ffff58e83be in malloc_consolidate () from /lib64/libc.so.6
S>>No symbol table info available.
S>>#5  0x00007ffff58eb1d8 in _int_malloc () from /lib64/libc.so.6
S>>No symbol table info available.
S>>#6  0x00007ffff58eceaa in malloc () from /lib64/libc.so.6
S>>No symbol table info available.
S>>#7  0x00007ffff6116418 in operator new (sz=8192) at /data/tmp/portage/sys-devel/gcc-7.3.0-r3/work/gcc-7.3.0/libstdc++-v3/libsupc++/new_op.cc:50
S>>        p = <optimized out>
S>>#8  0x00007ffff61164c5 in operator new[] (sz=<optimized out>) at /data/tmp/portage/sys-devel/gcc-7.3.0-r3/work/gcc-7.3.0/libstdc++-v3/libsupc++/new_opv.cc:32
S>>No locals.
S>>#9  0x00007ffff617b6f8 in std::basic_filebuf<char, std::char_traits<char> >::_M_allocate_internal_buffer (this=0x794ec8) at /data/tmp/portage/sys-devel/gcc-7.3.0-r3/work/build/x86_64-pc-linux-gnu/libstdc++-v3/include/bits/fstream.tcc:55
S>>        this = 0x794ec8
S>>#10 0x00007ffff617fd12 in std::basic_filebuf<char, std::char_traits<char> >::open (this=0x794ec8, __s=0x795800 "logs/cube_helper/2018-12-16_18-12-02.application.log", __mode=19) at /data/tmp/portage/sys-devel/gcc-7.3.0-r3/work/build/x86_64-pc-linux-gnu/libstdc++-v3/include/bits/fstream.tcc:187
S>>        __ret = 0x0
S>>        __s = 0x795800 "logs/cube_helper/2018-12-16_18-12-02.application.log"
S>>        __mode = 19
S>>        this = 0x794ec8
S>>        __ret = <optimized out>
S>>        __ret = 0x0
S>>#11 0x00007ffff617fe43 in std::basic_filebuf<char, std::char_traits<char> >::open (__mode=<optimized out>, __s=..., this=0x794ec8) at /data/tmp/portage/sys-devel/gcc-7.3.0-r3/work/build/x86_64-pc-linux-gnu/libstdc++-v3/include/fstream:308
S>>No locals.
S>>#12 std::basic_ofstream<char, std::char_traits<char> >::open (this=0x794ec0, __s=..., __mode=<optimized out>) at /data/tmp/portage/sys-devel/gcc-7.3.0-r3/work/build/x86_64-pc-linux-gnu/libstdc++-v3/include/fstream:823
S>>No locals.
S>>#13 0x00000000004aef98 in eing::tools::logger::CLogger::start (this=0x794e80) at ../../../src/tools/logger/clogger.cpp:63
S>>        time = {static npos = 18446744073709551615, _M_dataplus = {<std::allocator<char>> = {<__gnu_cxx::new_allocator<char>> = {<No data fields>}, <No data fields>}, _M_p = 0x7958d0 "P\223\330\367\377\177"}, _M_string_length = 7949920, {_M_local_buf = "\320\\y\000\000\000\000\000\200\006\365\000\000\000\000", _M_allocated_capacity = 7953616}}
S>>#14 0x00000000004cc16d in eing::graphic::world::CDynamicMesh::~CDynamicMesh (this=0x1073aa0) at ../../../src/graphic/world/cdynamicmesh.cpp:40
S>>No locals.
S>>#15 0x000000000049692e in eing::graphic::world::CBlock::~CBlock (this=0x105d070) at ../../../src/graphic/world/cblock.cpp:48
S>>No locals.
S>>#16 0x0000000000496c89 in eing::graphic::world::CBlock::~CBlock (this=0x105d070) at ../../../src/graphic/world/cblock.cpp:41
S>>No locals.
S>>#17 0x000000000045c05f in eing_helper::cube::AppCubeHelper::redrawTestCube (this=0x77cee0) at ../../../src/applications/cube_helper/main.cpp:350
S>>        e = @0xae6100: {_vptr.exception = 0xae61b0}
S>>#18 0x000000000045d2af in eing_helper::cube::AppCubeHelper::HandleUpdate (this=0x77cee0, eventType=..., eventData=...) at ../../../src/applications/cube_helper/main.cpp:289
S>>        yaw_ = 0
S>>        pitch_ = 0
S>>        timeStep = 0.00499999989
S>>        MOVE_SPEED = 10
S>>        MOUSE_SENSITIVITY = 0.100000001
S>>#19 0x0000000000460bc7 in Urho3D::EventHandlerImpl<eing_helper::cube::AppCubeHelper>::Invoke (this=0x106aff0, eventData=...) at /usr/include/Urho3D/Physics/../Core/Object.h:315
S>>        receiver = 0x77cee0
S>>#20 0x00007ffff732d642 in Urho3D::Object::OnEvent(Urho3D::Object*, Urho3D::StringHash, Urho3D::HashMap<Urho3D::StringHash, Urho3D::Variant>&) () from /usr/lib/Urho3D/libUrho3D.so.0
S>>No symbol table info available.
S>>#21 0x00007ffff732e93f in Urho3D::Object::SendEvent(Urho3D::StringHash, Urho3D::HashMap<Urho3D::StringHash, Urho3D::Variant>&) () from /usr/lib/Urho3D/libUrho3D.so.0
S>>No symbol table info available.
S>>#22 0x00007ffff734d1d7 in Urho3D::Engine::Update() () from /usr/lib/Urho3D/libUrho3D.so.0
S>>No symbol table info available.
S>>#23 0x00007ffff735013a in Urho3D::Engine::RunFrame() () from /usr/lib/Urho3D/libUrho3D.so.0
S>>No symbol table info available.
S>>#24 0x00007ffff7342e45 in Urho3D::Application::Run() () from /usr/lib/Urho3D/libUrho3D.so.0
S>>No symbol table info available.
S>>#25 0x000000000045d44a in main (argc=1, argv=0x7fffffffe018) at ../../../src/applications/cube_helper/main.cpp:378
S>>        graphic_result = 0

S>>


S>>Накидайте идей что это может быть? Может уже встречалось такое?...
Re[14]: Ты не понял что это и для чего.
От: Sheridan Россия  
Дата: 19.12.18 14:14
Оценка:
Здравствуйте, B0FEE664, Вы писали:

S>>Время жизни блоков разное зависит от разных факторов. При удалении блока он сообщает мешу о своей смерти. И когда, сообщив, видит что меш осиротел — забирает его с собой.


BFE>Значит я всё правильно понял. Если block->m_dynamicMesh везде правильно установлен и сам динамикмеш нигде не удаляется, то может это и будет работать...

BFE>Какой, всё же, тип у CDynamicMesh::m_blocks?
std::list<cblock *>

BFE>>>Вы видите, чтобы block->m_dynamicMesh устанавливался в this в этом методе? Не удивлюсь, если окажется, что recalculate() проходит по списку элементов им устанавливает каждому элементу m_dynamicMesh в this.

S>>Нет. В recalculate расчитываются вершины и индексы получающейся фигуры и фигура закидывается в модель чтобы рендерилось.
BFE>А где m_dynamicMesh присваивается?
В кострукторе cblock. Точнее в методе, который вызывается исключительно из конструктора, но это уже детали реализации.
Matrix has you...
Re[5]: Крашит в дебрях std при работе с ofstream
От: Sheridan Россия  
Дата: 19.12.18 16:55
Оценка:
Здравствуйте, AleksandrN, Вы писали:


AN>m_dynamicMesh объявлена как static?

Нет.
AN>m_dynamicMesh инициализируется в CBlock::CBlock()?
Да.
AN>Работа с CBlock потокобезопасная? Может ли CBlock::CBlock() и CBlock::~CBlock() дёрнуться из разных потоков?
Нет.
Matrix has you...
Re: Похоже, починил.
От: Sheridan Россия  
Дата: 20.12.18 19:50
Оценка:
Дело было не в бобине.
Похоже, внутри urho3d отсутствуют проверки внутри их "умных" указателей. Причём они, похоже, это монго встроили везде куда могли дотянуться.
Что делаю:
class cobject
{
  cobject () { buf = new urho3d::vertexbyffer(); }
  ~cobject () { delete buf; }
  urho3d::vertexbyffer *buf;
}

Казалось бы — валидный код. Ан нет, нифига подобного. У них почти любой объект — refcounted, в том числе и этот вертексбуффер. В результате валится в ReleaseRef(); внутри urho
Далее, интерфейсы SetVertexBuffer и SetIndexBuffer явно указывают на утечки памяти, если не удалять самостоятельно. Собственно вот поэтому и рулил сам.
И на самом деле я до сих пор сомневаюсь что там нет утечек.
Matrix has you...
Отредактировано 20.12.2018 19:56 Sheridan . Предыдущая версия . Еще …
Отредактировано 20.12.2018 19:55 Sheridan . Предыдущая версия .
Отредактировано 20.12.2018 19:53 Sheridan . Предыдущая версия .
Re[2]: Похоже, починил.
От: rg45 СССР  
Дата: 20.12.18 20:12
Оценка: +5
Здравствуйте, Sheridan, Вы писали:

S>Дело было не в бобине.

S>Похоже, внутри urho3d отсутствуют проверки внутри их "умных" указателей. Причём они, похоже, это монго встроили везде куда могли дотянуться.
S>Что делаю:
S>
S>class cobject
S>{
S>  cobject () { buf = new urho3d::vertexbyffer(); }
S>  ~cobject () { delete buf; }
S>  urho3d::vertexbyffer *buf;
S>}
S>

S>Казалось бы — валидный код. Ан нет, нифига подобного. У них почти любой объект — refcounted, в том числе и этот вертексбуффер. В результате валится в ReleaseRef(); внутри urho
S>Далее, интерфейсы SetVertexBuffer и SetIndexBuffer явно указывают на утечки памяти, если не удалять самостоятельно. Собственно вот поэтому и рулил сам.
S>И на самом деле я до сих пор сомневаюсь что там нет утечек.

Правильно, потому, что у них любой класс, в том числе и этот вертексбуффер, заточен на использование с их умным указателем: Urho3D::SharedPtr. И выглядеть это, по их задумке, должно бы примерно так:

class cobject
{
public:

  cobject() : m_vertex_buffer_ptr(new Urho3D::VertexBuffer()) {}
  virtual ~cobject() { /*nothing to do*/ }

private:
  Urho3D::SharedPtr<Urho3D::VertexBuffer> m_vertex_buffer_ptr;
};


Сделай ты так сразу, сэкономил бы кучу времени. Но ты же легких путей не ищещь и, вместо того, чтобы воспользоваться готовым умным указателем, ты, по факту, каждый свой класс превратил в умный указатель. Вот только подсчетом ссылок заморачиваться не стал. Вот и получил заслуженную "награду".
--
Re[3]: Похоже, починил.
От: Sheridan Россия  
Дата: 20.12.18 20:56
Оценка:
Здравствуйте, rg45, Вы писали:

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

Потому что это монго к коду лучше не подпускать. В чём я лишний раз убедился на практике.

R>ты, по факту, каждый свой класс превратил в умный указатель. Вот только подсчетом ссылок заморачиваться не стал. Вот и получил заслуженную "награду".

С каких пор инкапсуляция стала "умным указателем"? Подсчёт ссылок мне не нужен, потому что у меня указателей ровно один (на каждый нужный тип), и он либо указатель, либо nullptr
А урхопрограммеры даже не удосужились проверять на nullptr.
Matrix has you...
Re[4]: Похоже, починил.
От: rg45 СССР  
Дата: 20.12.18 21:12
Оценка: +2
Здравствуйте, Sheridan, Вы писали:

S>С каких пор инкапсуляция стала "умным указателем"? Подсчёт ссылок мне не нужен, потому что у меня указателей ровно один (на каждый нужный тип), и он либо указатель, либо nullptr


Просто инкапсуляция, конечно, нет. А вот для того, чтобы обеспечить совместное владение объектом ПРАВИЛЬНО, у тебя нет другого выхода, кроме как продублировать всю люгику работы умного указателя в каждом своем классе.

S>А урхопрограммеры даже не удосужились проверять на nullptr.


А как они могут проверить, что ты обнулил где-то там какой-то свой указатель? У них на этот же самый объект одновременно указывает еще дюжина других указателей. И удалить объект можно, только вместе с инвалидацией последнего указателя. И добиться этого можно, только через совместный подсчет ссылок.

Но у тебя иная ситуация — ты создал объект и в какой-то момент передаешь его в библиотечную функцию (на отрисовку, например). Библиотека сразу же захватывает владение этим объектом при помощи умного указателя (увеличивает счетчит ссылок). А по окончании работы освобождает объект от владения, уменьшает счетчик ссылок и, при достиженни счетчиком нуля грохает объект. Ты ведь счетчик ссылок не нарастил, поэтому про твое владение объектом никто ничего не знает.
--
Отредактировано 20.12.2018 21:25 rg45 . Предыдущая версия . Еще …
Отредактировано 20.12.2018 21:17 rg45 . Предыдущая версия .
Re[2]: Похоже, починил.
От: rg45 СССР  
Дата: 20.12.18 21:54
Оценка:
Здравствуйте, Sheridan, Вы писали:

S>
S>class cobject
S>{
S>  cobject () { buf = new urho3d::vertexbyffer(); }
S>  ~cobject () { delete buf; }
S>  urho3d::vertexbyffer *buf;
S>}
S>


И я хочу привести еще один довод в пользу умных указателей. Представь, что в каком-то классе у тебя оказалось два инкапсулированных указателя. Может такое быть? И вот, ты успешно создаешь первый объект, а при создании второго летит исключение. И приехали, первый объект никто никогда не освободит, потому, что деструктор в таких случаях не вызывается.

P.S. Ты вот, не поленись, почитай вот эту книжку: https://doc.lagout.org/programmation/C/CPP101.pdf, хотя бы выборочно.
--
Отредактировано 20.12.2018 21:59 rg45 . Предыдущая версия .
Re[5]: Похоже, починил.
От: Sheridan Россия  
Дата: 20.12.18 22:55
Оценка: -1
Здравствуйте, rg45, Вы писали:

S>>С каких пор инкапсуляция стала "умным указателем"? Подсчёт ссылок мне не нужен, потому что у меня указателей ровно один (на каждый нужный тип), и он либо указатель, либо nullptr

R>Просто инкапсуляция, конечно, нет. А вот для того, чтобы обеспечить совместное владение объектом ПРАВИЛЬНО, у тебя нет другого выхода, кроме как продублировать всю люгику работы умного указателя в каждом своем классе.
У меня совместное владение ровно одно пока что на проект и там всё ровно.

S>>А урхопрограммеры даже не удосужились проверять на nullptr.

R>А как они могут проверить, что ты обнулил где-то там какой-то свой указатель?
if(!rawptr) { /*оппа, указателя больше нет!*/ }


R>Но у тебя иная ситуация — ты создал объект и в какой-то момент передаешь его в библиотечную функцию (на отрисовку, например). Библиотека сразу же захватывает владение этим объектом при помощи умного указателя (увеличивает счетчит ссылок). А по окончании работы освобождает объект от владения, уменьшает счетчик ссылок и, при достиженни счетчиком нуля грохает объект. Ты ведь счетчик ссылок не нарастил, поэтому про твое владение объектом никто ничего не знает.

Понимаеш ли, у них есть специальный SharedPtr и они всегда явно создают объект с ним например так
SharedPtr<Node> node = scene->createChild();


И чтобы догадаться что
Node *node = scene->createChild();

не совсем и указатель нормальный, а половина умного, то нужно ну я не знаю, телепатом быть, чтоли. Или сорцы библиотеки сначала почитать.

Нормальный человек смотрит на код в первом примере и думает "А, ну тут шаред. Чтобы получить обычный указатель, нужно просто без шаред обёртки" и бинго, креш на ровном месте.
Вот как так можно было написать, а? Хотите шаред сделать — да магистры с вам, делайте. Но нафига в шаред реализовывать первую часть и в остальных объектах вторую часть умных указателей блин?
Matrix has you...
Re[3]: Похоже, починил.
От: Sheridan Россия  
Дата: 20.12.18 22:57
Оценка:
Здравствуйте, rg45, Вы писали:


R>И я хочу привести еще один довод в пользу умных указателей. Представь, что в каком-то классе у тебя оказалось два инкапсулированных указателя. Может такое быть? И вот, ты успешно создаешь первый объект, а при создании второго летит исключение.


== авария. Дебаг, разборки, починка. Больше не летит исключение или перехвачено и обработано.
Matrix has you...
Re[4]: Похоже, починил.
От: rg45 СССР  
Дата: 20.12.18 22:59
Оценка:
Здравствуйте, Sheridan, Вы писали:

R>>И я хочу привести еще один довод в пользу умных указателей. Представь, что в каком-то классе у тебя оказалось два инкапсулированных указателя. Может такое быть? И вот, ты успешно создаешь первый объект, а при создании второго летит исключение.


S>== авария. Дебаг, разборки, починка. Больше не летит исключение или перехвачено и обработано.


Да ясное дело, что перехвачено и обработано. Но объект ведь подвис, память утекла.
--
Re[5]: Похоже, починил.
От: Sheridan Россия  
Дата: 20.12.18 23:02
Оценка:
Здравствуйте, rg45, Вы писали:

R>Да ясное дело, что перехвачено и обработано. Но объект ведь подвис, память утекла.

Я же написал — такое поведение это авария, которую надо починить. Если неочевидно, то починка такой аварии по умолчанию включает в себя устранение утечек. Это значит мимо ничего не утекло.
Matrix has you...
Re[6]: Похоже, починил.
От: rg45 СССР  
Дата: 20.12.18 23:48
Оценка:
Здравствуйте, Sheridan, Вы писали:

R>>Да ясное дело, что перехвачено и обработано. Но объект ведь подвис, память утекла.

S>Я же написал — такое поведение это авария, которую надо починить. Если неочевидно, то починка такой аварии по умолчанию включает в себя устранение утечек. Это значит мимо ничего не утекло.

По-твоему, в отлаженной, правильно работающей программе исключения возникать не могут? Посмотри хотя бы на список исключений стандартной библиотеки: https://en.cppreference.com/w/cpp/error/exception — далеко не все из них связываются с ошибками в программе. Большая группа иссключений — runtime_error существет как раз для реакции на ощибки, возникающие за пределами программы. А как ты собираешься "чинить" исключения, бросаемые сторонними библиотеками?
--
Отредактировано 20.12.2018 23:57 rg45 . Предыдущая версия .
Re[2]: Похоже, починил.
От: night beast СССР  
Дата: 21.12.18 06:55
Оценка: +1
Здравствуйте, Sheridan, Вы писали:

S>Дело было не в бобине.

S>Похоже, внутри urho3d отсутствуют проверки внутри их "умных" указателей. Причём они, похоже, это монго встроили везде куда могли дотянуться.

проверка чего? того что кто-то самостоятельно удаляет объекты, которые используются?

S>Что делаю:

S>
S>class cobject
S>{
S>  cobject () { buf = new urho3d::vertexbyffer(); }
S>  ~cobject () { delete buf; }
S>  urho3d::vertexbyffer *buf;
S>}
S>

S>Казалось бы — валидный код. Ан нет, нифига подобного. У них почти любой объект — refcounted, в том числе и этот вертексбуффер. В результате валится в ReleaseRef(); внутри urho
это валидный код до тех пор пока ты не передал его куда-то.

S>Далее, интерфейсы SetVertexBuffer и SetIndexBuffer явно указывают на утечки памяти, если не удалять самостоятельно. Собственно вот поэтому и рулил сам.


они указывают на то, что Geometry этими объектами не владеет.
по хорошему, они должны быть WeakPtr.

S>И на самом деле я до сих пор сомневаюсь что там нет утечек.


если ты самостоятельно следишь за сырыми указателями, то вполне обоснованно сомневаешься.
Re[3]: Похоже, починил.
От: PM  
Дата: 21.12.18 07:13
Оценка: +4 :))) :)
Здравствуйте, night beast, Вы писали:

S>>Далее, интерфейсы SetVertexBuffer и SetIndexBuffer явно указывают на утечки памяти, если не удалять самостоятельно. Собственно вот поэтому и рулил сам.


NB>они указывают на то, что Geometry этими объектами не владеет.

NB>по хорошему, они должны быть WeakPtr.

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

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

Шеридану спасибо!
Re[4]: Похоже, починил.
От: night beast СССР  
Дата: 21.12.18 07:25
Оценка:
Здравствуйте, PM, Вы писали:

S>>>Далее, интерфейсы SetVertexBuffer и SetIndexBuffer явно указывают на утечки памяти, если не удалять самостоятельно. Собственно вот поэтому и рулил сам.


NB>>они указывают на то, что Geometry этими объектами не владеет.

NB>>по хорошему, они должны быть WeakPtr.

PM>Совместно владеет, просто Sheridan, как обычно, делает заявления не разобравшись в сути вопроса.


тьфу блин. смотрел Graphics.h, там эти переменные -- сырые указатели.

PM>PS. Было занято наблюдать оживление здесь и в КСВ на тему сырых указателей и двойного удаления в конце 2018 года. Всего 5 дней потребовалось, чтобы найти ошибку, но выводы, похоже, еще не сделаны


+1
Re[4]: Похоже, починил.
От: rg45 СССР  
Дата: 21.12.18 07:36
Оценка: +1
Здравствуйте, PM, Вы писали:

PM>PS. Было занято наблюдать оживление здесь и в КСВ на тему сырых указателей и двойного удаления в конце 2018 года. Всего 5 дней потребовалось, чтобы найти ошибку, но выводы, похоже, еще не сделаны


Сходил в КСВ, развернул обсуждение и почувствовал, что силы покидают меня...
--
Re[7]: Похоже, починил.
От: Sheridan Россия  
Дата: 21.12.18 08:03
Оценка:
Здравствуйте, rg45, Вы писали:

R>>>Да ясное дело, что перехвачено и обработано. Но объект ведь подвис, память утекла.

S>>Я же написал — такое поведение это авария, которую надо починить. Если неочевидно, то починка такой аварии по умолчанию включает в себя устранение утечек. Это значит мимо ничего не утекло.

R>По-твоему, в отлаженной, правильно работающей программе исключения возникать не могут? Посмотри хотя бы на список исключений стандартной библиотеки: https://en.cppreference.com/w/cpp/error/exception — далеко не все из них связываются с ошибками в программе. Большая группа иссключений — runtime_error существет как раз для реакции на ощибки, возникающие за пределами программы.

Ты имеешь в виду ошибки типа "память кончилась"? Ну явно их надо перехватывать не в каждой из функций программы и вообще желательно повыше и в одном месте. А уж там то можно сделать всё без утечек памяти.

R>А как ты собираешься "чинить" исключения, бросаемые сторонними библиотеками?

Практически ровно так же.
Matrix has you...
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.