[QXmpp] Trying to use sendMessage to a MUC crashes my app.
-
I’m using a global pointer for the active game room (QXmppMucRoom* room_ptr) so that I don’t have to recreate it every time. I create the room once when a game is accepted or created and connect all the relevant signals like joined, messageReceived, left, and kicked.
The problem is, even though room_ptr is valid and I haven’t left the room, calling sendMessage() from a different function always crashes my app.
I’ve tried removing checks like isJoined(), and even then it crashes. If I create a new room inside the sending function, it works, but that’s not correct — I want to use the same room.
in header file:
QXmppClient *m_client; QXmppMucManager *m_mucManager; QXmppMucRoom* room_ptr;
In Contructor:
m_client = new QXmppClient(this); m_mucManager = new QXmppMucManager; m_client->addExtension(m_mucManager);
in_function 1:
room_ptr = m_mucManager->addRoom(roomJid); room_ptr->setNickName("Player 1"); room_ptr->join(); connect(room_ptr, &QXmppMucRoom::left, this, [this]() { std::cout << "You left the room: " << room_ptr->jid().toStdString() << std::endl; room_ptr = nullptr; }); connect(room_ptr, &QXmppMucRoom::kicked, this, [this](const QString &jid, const QString &reason){ std::cout << "Kicked from room: " << room_ptr->jid().toStdString() << ", by: " << jid.toStdString() << ", reason: " << reason.toStdString() << std::endl; room_ptr = nullptr; }); connect(room_ptr, &QXmppMucRoom::messageReceived, this, &EstablishXMPP::handleMucMessage); connect(room_ptr, &QXmppMucRoom::joined, this, [this, player, board]() { std::cout << "Joined room: " << room_ptr->jid().toStdString(); std::cout << "room: " << room_ptr << std::endl; if(room_ptr->isJoined()) { std::cout << "STILL JOINED" << std::endl << std::flush; // it says still joined in logs } emit gameInviteAccepted("Sender", player, board); room_ptr->sendMessage("THIS IS A TEST MESSAGE"); //sends successfully });
in function_2:
room_ptr->sendMessage("SOME MESSAGE"); //triggers crash
I have my entire code here,
https://invent.kde.org/srisharanvs/mankalanextgen/-/tree/muc-bug
In src/component/MainMenu/EstablishXMPP.cpp
->handleMessage()
->sendGameMove()If you are gonna try replicating it, then follow below commands,
/setup-m-desktop.sh mkdir tbuild && cd tbuild cmake .. make cd src/app ./MankalaNextGen
Inside the app, You will need to visit profile and login through some xmpp account and send an invite to someone rhrough "Play Online", and accept it through another instance of the app, I use QSettings, so if you try to clone it in a different directory for a second account, then it refers the same document for credentials, you will have to edit src/components/MainMenu/SettingsManager.cpp for it.
Then once you accept the invite through a different account, then you click on one of the bottom row pits in the new screen, that u will be redirect to, on accepting invite, this click triggers the crash. -
I’m using a global pointer for the active game room (QXmppMucRoom* room_ptr) so that I don’t have to recreate it every time. I create the room once when a game is accepted or created and connect all the relevant signals like joined, messageReceived, left, and kicked.
The problem is, even though room_ptr is valid and I haven’t left the room, calling sendMessage() from a different function always crashes my app.
I’ve tried removing checks like isJoined(), and even then it crashes. If I create a new room inside the sending function, it works, but that’s not correct — I want to use the same room.
in header file:
QXmppClient *m_client; QXmppMucManager *m_mucManager; QXmppMucRoom* room_ptr;
In Contructor:
m_client = new QXmppClient(this); m_mucManager = new QXmppMucManager; m_client->addExtension(m_mucManager);
in_function 1:
room_ptr = m_mucManager->addRoom(roomJid); room_ptr->setNickName("Player 1"); room_ptr->join(); connect(room_ptr, &QXmppMucRoom::left, this, [this]() { std::cout << "You left the room: " << room_ptr->jid().toStdString() << std::endl; room_ptr = nullptr; }); connect(room_ptr, &QXmppMucRoom::kicked, this, [this](const QString &jid, const QString &reason){ std::cout << "Kicked from room: " << room_ptr->jid().toStdString() << ", by: " << jid.toStdString() << ", reason: " << reason.toStdString() << std::endl; room_ptr = nullptr; }); connect(room_ptr, &QXmppMucRoom::messageReceived, this, &EstablishXMPP::handleMucMessage); connect(room_ptr, &QXmppMucRoom::joined, this, [this, player, board]() { std::cout << "Joined room: " << room_ptr->jid().toStdString(); std::cout << "room: " << room_ptr << std::endl; if(room_ptr->isJoined()) { std::cout << "STILL JOINED" << std::endl << std::flush; // it says still joined in logs } emit gameInviteAccepted("Sender", player, board); room_ptr->sendMessage("THIS IS A TEST MESSAGE"); //sends successfully });
in function_2:
room_ptr->sendMessage("SOME MESSAGE"); //triggers crash
I have my entire code here,
https://invent.kde.org/srisharanvs/mankalanextgen/-/tree/muc-bug
In src/component/MainMenu/EstablishXMPP.cpp
->handleMessage()
->sendGameMove()If you are gonna try replicating it, then follow below commands,
/setup-m-desktop.sh mkdir tbuild && cd tbuild cmake .. make cd src/app ./MankalaNextGen
Inside the app, You will need to visit profile and login through some xmpp account and send an invite to someone rhrough "Play Online", and accept it through another instance of the app, I use QSettings, so if you try to clone it in a different directory for a second account, then it refers the same document for credentials, you will have to edit src/components/MainMenu/SettingsManager.cpp for it.
Then once you accept the invite through a different account, then you click on one of the bottom row pits in the new screen, that u will be redirect to, on accepting invite, this click triggers the crash.@SrisharanVS said in [QXmpp] Trying to use sendMessage to a MUC crashes my app.:
room_ptr->sendMessage("SOME MESSAGE"); //triggers crash
How is room_ptr initialized in function_2?
There is also debugger to debug such issues. -
@SrisharanVS said in [QXmpp] Trying to use sendMessage to a MUC crashes my app.:
room_ptr->sendMessage("SOME MESSAGE"); //triggers crash
How is room_ptr initialized in function_2?
There is also debugger to debug such issues.@jsulm Do I need to,
room_ptr = m_mucManager->addRoom(roomJid); room_ptr->setNickName("Player 1"); room_ptr->join();
in every different funcion before trying sendMessage()? Can you be more specific about initialization?
This was the error I got and also,
-
@jsulm Do I need to,
room_ptr = m_mucManager->addRoom(roomJid); room_ptr->setNickName("Player 1"); room_ptr->join();
in every different funcion before trying sendMessage()? Can you be more specific about initialization?
This was the error I got and also,
@SrisharanVS said in [QXmpp] Trying to use sendMessage to a MUC crashes my app.:
Can you be more specific about initialization?
You need to make sure room_ptr is a valid pointer before you use it. You did not post the code of the function_2, so nobody knows whether it is initialised. In function_1 you assign something to room_ptr, but we do not know whether room_ptr is a local variable in that function or class member. Yeasiest way to share something inside a class is to make it class member (in that case make room_ptr class member).
-
@jsulm Do I need to,
room_ptr = m_mucManager->addRoom(roomJid); room_ptr->setNickName("Player 1"); room_ptr->join();
in every different funcion before trying sendMessage()? Can you be more specific about initialization?
This was the error I got and also,
@SrisharanVS
As @jsulm has said. And as he wrote before you should look at this in a debugger yourself. You absolutely need to learn to do debugging for C++ programs, and the sooner you learn to use and are confident with a debugger the better, it will be you who benefits from it over time.Here we don't know, but the first thing is see the stack trace from the crash/signal and look at the value of
room_ptr
if it's dying onroom_ptr->sendMessage()
. -
Hi,
Beside using a debugger to pinpoint where your application fails, you should also check whether your
room_ptr
is null before using it. You might be calling things out of the order you think they are happening. -
You set room_ptr to nullptr in various branches of your code - so I would guess it's a nullptr in your second call.
-
You set room_ptr to nullptr in various branches of your code - so I would guess it's a nullptr in your second call.
I tried to print the value of room->ptr before room_ptr->sendMessage(), and its zero, I not sure how it becomes 0 though..
I set room->ptr to nullptr on ::left, ::kicked. That was me trying to debug things, the problem existed without it too.. I added those to see if and when my user disconnects from the MUC, but there were never triggered.
-
Then you never set it to something! = nullptr
-
But I do the below,
room_ptr = m_mucManager->addRoom(roomJid); room_ptr->setNickName("Player 1"); room_ptr->join(); connect(room_ptr, &QXmppMucRoom::joined, this, [this, player, board]() { std::cout << "Joined room: " << room_ptr->jid().toStdString(); std::cout << "room: " << room_ptr << std::endl; if(room_ptr->isJoined()) { std::cout << "STILL JOINED" << std::endl << std::flush; } emit gameInviteAccepted("Sender", player, board); room_ptr->sendMessage("THIS IS A TEST MESSAGE"); });
And room_ptr is a class member. Only when gameInviteAccepted is emitted, then I am pushed into a screen, where I am able to trigger sendGameMove(), so sendGameMove is definitely happening after the above code, since emit is inside connect.
Here, I get some address for room_ptr, but then in the other function, I get a 0
-
Thank you everyone for taking your time to reply me. The mistake was that, the invokation of the functions were in different qml files, and I had used different instances of the class in the 2 files. I finally fixed it :)