Bonjour !
Je suis assez déconcerté par un bug que j'ai eu assez subitement avec la SFML : je travaillais sous Linux, ai porté mon projet sous Windows, et à mon retour sous Linux après relativement peu de modifications, je fais une segfault sur pollEvent(...) alors que je n'ai rien modifié du bout de code qui plante. Une ancienne version compilée marche toujours, mais pas la nouvelle...
Voici le bout de code qui plante :
/* Project : Particules
* Version : 0.31
*/
#include "fenetre.h"
using namespace std;
Fenetre::Fenetre()
: m_pause(false), m_continue(true), m_fullscreen(true) {
cfg = ConfigParser::get();
cfgWindowTitle = cfg->readString("windowTitle");
cfgWindowWidth = cfg->readInt("windowWidth");
cfgWindowHeight = cfg->readInt("windowHeight");
// mode fenetre
m_window = new sf::RenderWindow(sf::VideoMode(cfgWindowWidth, cfgWindowHeight, 32), cfgWindowTitle);
// mode plein ecran
//m_window = new sf::RenderWindow(sf::VideoMode::getFullscreenModes()[0], cfgWindowTitle, sf::Style::Fullscreen);
m_window->setVerticalSyncEnabled(true);
m_font.loadFromFile("Square.ttf");
particleSystem = new ParticleSystem(m_window->getSize().x, m_window->getSize().y, m_font);
textFps.setFont(m_font);
textFps.setCharacterSize(10);
textFps.setStyle(sf::Text::Bold);
textFps.setColor(sf::Color::Red);
textFps.setPosition(m_window->getSize().x - 100, 10);
clock.restart();
clockText.restart();
}
Fenetre::~Fenetre() {
delete m_window;
delete particleSystem;
}
int Fenetre::exec() {
while (m_continue && m_window->isOpen()) {
dt = clock.restart().asSeconds();
handleEvents();
if (!m_pause)
update();
display();
}
return EXIT_SUCCESS;
}
void Fenetre::handleEvents() {
sf::Event event;
/*************** ICI **************/
while (m_window->pollEvent(event))
{
// ...
}
}
void Fenetre::update() {
if (clockText.getElapsedTime().asSeconds() >= 1.) {
std::ostringstream oss;
oss << "FPS : " << (int) (1/dt);
textFps.setString(oss.str());
clockText.restart();
}
particleSystem->update(dt);
}
void Fenetre::display() {
m_window->clear();
particleSystem->display(m_window);
m_window->draw(textFps);
m_window->display();
}
void Fenetre::updateWindowSize(const int width, const int height) {
sf::View view(sf::FloatRect(0, 0, width, height));
m_window->setView(view);
particleSystem->setWindowSize(sf::Vector2f(width, height));
textFps.setPosition(width - 100, 10);
}
Ce que gdb en dit :
61 while (m_window->pollEvent(event))
(gdb) s
sf::Window::pollEvent (this=0x808a090, event=...)
at /home/adrien/Sources/SFML2.0/src/SFML/Window/Window.cpp:183
183 if (m_impl && m_impl->popEvent(event, false))
(gdb) bt
#0 sf::Window::pollEvent (this=0x808a090, event=...)
at /home/adrien/Sources/SFML2.0/src/SFML/Window/Window.cpp:183
#1 0x0804d79e in Fenetre::handleEvents (this=0xbffff300)
at ./fenetre.cpp:61
#2 0x0804d499 in Fenetre::exec (this=0xbffff300) at ./fenetre.cpp:47
#3 0x0804c542 in main (argc=1, argv=0xbffff514) at ./main.cpp
Je suis sous Ubuntu 10.04 avec Awesome comme gestionnaire de fenetres. Je ne pense pas que ca soit très utile sachant que mon précédent projet marche très bien sous cette configuration (j'ai pas essayé de le recompiler cela dit, je fais ca de suite)
J'ai lu que ce genre de problème pouvait venir d'un conflit entre versions de la SFML (j'avais effectivement la version des dépots installée avant ca). J'ai désinstallé le paquet, supprimé toute trace de la SFML dans /usr/, et recompilé en suivant les indications de ce tuto : http://sfmlcoder.wordpress.com/2011/08/16/building-sfml-2-0-with-make-for-gcc/ (http://sfmlcoder.wordpress.com/2011/08/16/building-sfml-2-0-with-make-for-gcc/).
Merci d'avance pour votre aide ! :)
Edit :
En réinstallant SFML2.0 que je viens de télécharger depuis le site officiel, je vois que sf::Keyboard::Back n'existe plus mais est remplacé par sf::Keyboard::BackSpace. C'est pas noté dans la doc...
Ca m'a l'air bien compliqué cette histoire au final...
J'ai poussé le debug plus loin avec gdb et au final il semblerait que ca soit carrément la stl qui merde sur un ostringstream dans la fonction sf::priv::JoystickImpl::isConnected (index=0)
Voilà l'output de gdb :
sf::priv::JoystickImpl::isConnected (index=0) at /home/adrien/Sources/SFML2.0/src/SFML/Window/Linux/JoystickImpl.cpp:42
42 std::ostringstream oss;
(gdb) n
43 oss << "/dev/input/js" << index;
(gdb) s
Program received signal SIGSEGV, Segmentation fault.
0x003c147a in ?? () from /lib/tls/i686/cmov/libc.so.6
(gdb) bt
#0 0x003c147a in ?? () from /lib/tls/i686/cmov/libc.so.6
#1 0x003c36cd in ?? () from /lib/tls/i686/cmov/libc.so.6
#2 0x003c5b6c in malloc () from /lib/tls/i686/cmov/libc.so.6
#3 0x002d9c07 in operator new(unsigned int) () from /usr/lib/libstdc++.so.6
#4 0x002b3d06 in std::string::_Rep::_S_create(unsigned int, unsigned int, std::allocator<char> const&) () from /usr/lib/libstdc++.so.6
#5 0x002b4978 in std::string::_Rep::_M_clone(std::allocator<char> const&, unsigned int) () from /usr/lib/libstdc++.so.6
#6 0x002b57ad in std::string::reserve(unsigned int) () from /usr/lib/libstdc++.so.6
#7 0x002ae93d in std::basic_stringbuf<char, std::char_traits<char>, std::allocator<char> >::overflow(int) () from /usr/lib/libstdc++.so.6
#8 0x002b319d in std::basic_streambuf<char, std::char_traits<char> >::xsputn(char const*, int) () from /usr/lib/libstdc++.so.6
#9 0x002a8c32 in std::basic_ostream<char, std::char_traits<char> >& std::__ostream_insert<char, std::char_traits<char> >(std::basic_ostream<char, std::char_traits<char> >&, char const*, int) () from /usr/lib/libstdc++.so.6
#10 0x002a8ebc in std::basic_ostream<char, std::char_traits<char> >& std::operator<< <std::char_traits<char> >(std::basic_ostream<char, std::char_traits<char> >&, char const*) () from /usr/lib/libstdc++.so.6
#11 0x001fd11d in sf::priv::JoystickImpl::isConnected (index=0) at /home/adrien/Sources/SFML2.0/src/SFML/Window/Linux/JoystickImpl.cpp:43
#12 0x001f5801 in sf::priv::JoystickManager::update (this=0x209780) at /home/adrien/Sources/SFML2.0/src/SFML/Window/JoystickManager.cpp:80
#13 0x001f96a8 in sf::priv::WindowImpl::processJoystickEvents (this=0x8150200) at /home/adrien/Sources/SFML2.0/src/SFML/Window/WindowImpl.cpp:148
#14 0x001f9590 in sf::priv::WindowImpl::popEvent (this=0x8150200, event=..., block=false) at /home/adrien/Sources/SFML2.0/src/SFML/Window/WindowImpl.cpp:105
#15 0x001f8ae5 in sf::Window::pollEvent (this=0x808a090, event=...) at /home/adrien/Sources/SFML2.0/src/SFML/Window/Window.cpp:183
#16 0x0804d79e in Fenetre::handleEvents (this=0xbffff350) at ./fenetre.cpp:61
#17 0x0804d499 in Fenetre::exec (this=0xbffff350) at ./fenetre.cpp:47
#18 0x0804c542 in main (argc=1, argv=0xbffff564) at ./main.cpp:20
J'ai vu quelques posts intéressants sur internet, dont celui-ci : http://stackoverflow.com/questions/7038124/weird-sigsegv-segmentation-fault-in-stdstringassign-method-from-libstdc (http://stackoverflow.com/questions/7038124/weird-sigsegv-segmentation-fault-in-stdstringassign-method-from-libstdc)
Mais ca dépasse de loin mon entendement... Qui plus est il ne s'agirait plus vraiment d'une erreur de la SFML du coup, tout à fait de mon code...
Encore plus incompréhensible le meme code fonctionne sur une autre projet, comme je l'ai dit plus haut...
Enfin, si vous y comprenez quelque chose ca serait avec plaisir que j'écouterai vos explications !
EDIT :
J'ai édité ma classe ParticleSystem et mon bug venait en effet d'une mauvaise allocation mémoire dans un endroit qui n'avait rien à voir avec les events... Bizarre. Si ca intéresse quelqu'un je peux vous expliquer mais je doute que ca vaille la peine.
Merci quand même Laurent, keep up the good work ! :)