Welcome, Guest. Please login or register. Did you miss your activation email?

Author Topic: [SOLVED] SFML jams (gcc) or raise assert (vc++) in sf::ResourcePtr  (Read 2185 times)

0 Members and 1 Guest are viewing this topic.

Quedr

  • Guest
Note: I placed this question in the graphics sub-forum, but I am not sure the problem actually comes from  a graphic element.

My program copies instances of sf::sprite quite heavily between two threads (one thread sets the sprites, copy these into a std::multimap, and then swaps its std::multimap whith the rendering thread's, and the other thread renders all the items of the std::multimap).

The program starts running fine for a few frames on ubuntu (gcc), and on windows (vc++ 2008),
but after a few seconds, the program hangs (gcc) or raises an assert (vc++).

Here is the gdb stack trace when I hit ^C, a few seconds after the program hangs.
(gdb) bt
#0  0x00007ffff7297acd in std::_Rb_tree_insert_and_rebalance(bool, std::_Rb_tree_node_base*, std::_Rb_tree_node_base*, std::_Rb_tree_node_base&) () from /usr/lib/x86_64-linux-gnu/libstdc++.so.6
#1  0x000000000040a90e in std::_Rb_tree<sf::ResourcePtr<sf::Image>*, sf::ResourcePtr<sf::Image>*, std::_Identity<sf::ResourcePtr<sf::Image>*>, std::less<sf::ResourcePtr<sf::Image>*>, std::allocator<sf::ResourcePtr<sf::Image>*> >::_M_insert_ (this=0xdc82d0, __x=0x0, __p=0xde5130, __v=@0x7fffffffd338: 0x7fffffffd568)
    at /usr/include/c++/4.6/bits/stl_tree.h:973
#2  0x000000000040a447 in std::_Rb_tree<sf::ResourcePtr<sf::Image>*, sf::ResourcePtr<sf::Image>*, std::_Identity<sf::ResourcePtr<sf::Image>*>, std::less<sf::ResourcePtr<sf::Image>*>, std::allocator<sf::ResourcePtr<sf::Image>*> >::_M_insert_unique (this=0xdc82d0, __v=@0x7fffffffd338: 0x7fffffffd568)
    at /usr/include/c++/4.6/bits/stl_tree.h:1291
#3  0x000000000040a191 in std::set<sf::ResourcePtr<sf::Image>*, std::less<sf::ResourcePtr<sf::Image>*>, std::allocator<sf::ResourcePtr<sf::Image>*> >::insert (this=0xdc82d0, __x=@0x7fffffffd338: 0x7fffffffd568)
    at /usr/include/c++/4.6/bits/stl_set.h:410
#4  0x000000000040a129 in sf::Resource<sf::Image>::Connect (this=0xdc82d0, Observer=...)
    at /usr/include/SFML/System/Resource.inl:77
#5  0x000000000040a066 in sf::ResourcePtr<sf::Image>::ResourcePtr (this=0x7fffffffd568, Copy=...)
    at /usr/include/SFML/System/ResourcePtr.inl:57
#6  0x0000000000409d62 in sf::Sprite::Sprite (this=0x7fffffffd4b8) at /usr/include/SFML/Graphics/Sprite.hpp:45

 

Then follows my code stack trace, where I set the sprite image.

Here is the message in visual studio.
Debug assertion failed!

Program: ...
File: c:\program files (x86)\microsoft visual studio 9.0/vc/include/xtree
Line: 304

Expression: map/set iterators incompatible

For information ...

(Press Retry to debug the application)
 

And the visual studio stack trace.
        msvcp90d.dll!std::_Debug_message(const wchar_t * message=0x01432988, const wchar_t * file=0x014325d8, unsigned int line=304)  Line 24   C++
>       ***.exe!std::_Tree<std::_Tset_traits<sf::ResourcePtr<sf::Image> *,std::less<sf::ResourcePtr<sf::Image> *>,std::allocator<sf::ResourcePtr<sf::Image> *>,0> >::const_iterator::operator==(const std::_Tree<std::_Tset_traits<sf::ResourcePtr<sf::Image> *,std::less<sf::ResourcePtr<sf::Image> *>,std::allocator<sf::ResourcePtr<sf::Image> *>,0> >::const_iterator & _Right=0xfeeefeee {myResource=??? })  Line 304 + 0x17 bytes C++
        ***.exe!std::_Tree<std::_Tset_traits<sf::ResourcePtr<sf::Image> *,std::less<sf::ResourcePtr<sf::Image> *>,std::allocator<sf::ResourcePtr<sf::Image> *>,0> >::const_iterator::operator!=(const std::_Tree<std::_Tset_traits<sf::ResourcePtr<sf::Image> *,std::less<sf::ResourcePtr<sf::Image> *>,std::allocator<sf::ResourcePtr<sf::Image> *>,0> >::const_iterator & _Right=0xfeeefeee {myResource=??? })  Line 316 + 0xc bytes  C++
        ***.exe!std::_Tree<std::_Tset_traits<sf::ResourcePtr<sf::Image> *,std::less<sf::ResourcePtr<sf::Image> *>,std::allocator<sf::ResourcePtr<sf::Image> *>,0> >::erase(std::_Tree<std::_Tset_traits<sf::ResourcePtr<sf::Image> *,std::less<sf::ResourcePtr<sf::Image> *>,std::allocator<sf::ResourcePtr<sf::Image> *>,0> >::const_iterator _First=0xfeeefeee {myResource=??? }, std::_Tree<std::_Tset_traits<sf::ResourcePtr<sf::Image> *,std::less<sf::ResourcePtr<sf::Image> *>,std::allocator<sf::ResourcePtr<sf::Image> *>,0> >::const_iterator _Last=0xfeeefeee {myResource=??? })  Line 942 + 0xc bytes       C++
        ***.exe!std::_Tree<std::_Tset_traits<sf::ResourcePtr<sf::Image> *,std::less<sf::ResourcePtr<sf::Image> *>,std::allocator<sf::ResourcePtr<sf::Image> *>,0> >::erase(sf::ResourcePtr<sf::Image> * const & _Keyval=0x0036f64c)  Line 953 + 0x57 bytes      C++
        ***.exe!sf::Resource<sf::Image>::Disconnect(sf::ResourcePtr<sf::Image> & Observer={...})  Line 88       C++
        ***.exe!sf::ResourcePtr<sf::Image>::operator=()  + 0x39 bytes  
        ***.exe!sf::Sprite::SetImage()  + 0x89 bytes
 

Then my stack trace.

I could not find much on how the sf::Resource works, and why it is used here.

Attempts to see something with valgrind+memcheck were unsuccessful, due to lots of errors comming from the ati drivers library.

Any ideas on what could cause this problem ?
« Last Edit: August 15, 2012, 06:51:44 pm by Quedr »

Laurent

  • Administrator
  • Hero Member
  • *****
  • Posts: 32504
    • View Profile
    • SFML's website
    • Email
Re: SFML jams (gcc) or raise assert (vc++) in sf::ResourcePtr
« Reply #1 on: August 15, 2012, 04:05:00 pm »
You should first try to reproduce this problem with a complete and minimal code. It's hard to debug a big code with threads (do you even know if the threads are part of the problem?).
Laurent Gomila - SFML developer

eXpl0it3r

  • SFML Team
  • Hero Member
  • *****
  • Posts: 10823
    • View Profile
    • development blog
    • Email
Re: SFML jams (gcc) or raise assert (vc++) in sf::ResourcePtr
« Reply #2 on: August 15, 2012, 04:09:19 pm »
From the assert "Expression: map/set iterators incompatible" I'd say that your iterator somehow gets unvalid. Since you're talking about two threads could it be that the content of the container gets swap while you're iterating over it? Also how do you manage the synchronization? Are there no race conditions etc.?

As Laurent said without a complete and minimal example that reproduces the error, we can only guess and wonder. :)
Official FAQ: https://www.sfml-dev.org/faq.php
Official Discord Server: https://discord.gg/nr4X7Fh
——————————————————————
Dev Blog: https://duerrenberger.dev/blog/

Quedr

  • Guest
Re: SFML jams (gcc) or raise assert (vc++) in sf::ResourcePtr
« Reply #3 on: August 15, 2012, 04:33:06 pm »
A given sprite can only be accessed by only one thread at a time. But an image may very well be accessed by several threads at once, if sf::Sprite::SetImage(sf::Image&), sf::Sprite::Draw(sf::RenderTarget&), sf::Sprite::~Sprite(), and/or sf::Sprite::Sprite() alter the image or one of its internal components.

If this is the case, then it is extremely likely to be the problem, and I will have to change part of my architecture.

If it isn't, then I have no idea of the problem origin, and I will have an hard time figuring out a minimal code...

So may I have some information on the inner workings and thread-safeness of the sf::Ressource ?

eXpl0it3r

  • SFML Team
  • Hero Member
  • *****
  • Posts: 10823
    • View Profile
    • development blog
    • Email
Re: SFML jams (gcc) or raise assert (vc++) in sf::ResourcePtr
« Reply #4 on: August 15, 2012, 04:38:03 pm »
I didn't even notice... You should defently switch to SFML 2.
SFML 1.6 has a so called ATI bug which either lets the application crash at exit or just doesn't show a window.

It's quite easy to create a complete minimal example, just strip down piece by piece and everytime check if the problem still occures. With that method you'll probably even find out which part of the code is causing the issue (i.e. if you remove that part the problem doesn't happen anymore). ;)

Also the source of SFML is completly open, so you can check out the sf::Resource on your own. :)
Official FAQ: https://www.sfml-dev.org/faq.php
Official Discord Server: https://discord.gg/nr4X7Fh
——————————————————————
Dev Blog: https://duerrenberger.dev/blog/

Quedr

  • Guest
Re: SFML jams (gcc) or raise assert (vc++) in sf::ResourcePtr
« Reply #5 on: August 15, 2012, 05:47:00 pm »
Sorry for the rubber ducking :-[ , the issue was that the Image ressourceptr was changing in multiple threads at the same time, and because the sf::Resource is not thread safe, especially the std::set part, the program crashed.

Now, I am on my way to make a sprite class from scratch, so that only plain data is moved around. Probably a copy-paste of most of the sf::Sprite.

Thanks.

Also, for the SFML 2.0, I will probably wait for it to be in the ubuntu packages, it will be simpler to get the project compilation up and running.