Memory corruption with libtorrent-rasterbar and QGuiApplication - qt

I'm trying to use libtorrent in my Qt5 application but keep getting segfaults
with messages like malloc(): memory corruption. After hours of debbuging I come up with this small piece of code which triggers this problem:
int main(int argc, char *argv[])
{
QGuiApplication app(argc, argv);
std::string filename = "fedora.torrent";
libtorrent::error_code ec;
libtorrent::add_torrent_params parameters;
std::cerr << "111\n";
parameters.ti = new libtorrent::torrent_info(filename, ec);;
std::cerr << "222\n";
return app.exec()
}
In this case constructor of torrent_info produce segfault. But if I move libtorrent related code before creation of QGuiApplication like this:
int main(int argc, char *argv[])
{
std::string filename = "fedora.torrent";
libtorrent::error_code ec;
libtorrent::add_torrent_params parameters;
std::cerr << "111\n";
parameters.ti = new libtorrent::torrent_info(filename, ec);;
std::cerr << "222\n";
QGuiApplication app(argc, argv);
return app.exec()
}
then it works just fine. Also this problem exist only in 32-bit build, in 64-bit build both variants work the same.

This is most likely caused by building libtorrent with one set of TORRENT_* defines and linking against it with a different set. Some of those defines affect layouts of some structs used in the public API and when differing between the calling application and the library introduce ABI incompatibility issues.

Related

QThreadStorage double free

Qt5.12.12 with msvc 2017 x64.
I create a QThreadStorage object at the beginning of my app, when I close my app, it crashs. After debug, I find it is caused by double free of the data in QThreadStorage. Here is my code. Am I use it wrong?
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
QThreadStorage<QString> data;
data.setLocalData("TEst");
QMainWindow window;
window.show();
return a.exec();
}
And here is error information and trace stack.
Error information
trace stack

Getting different values from std::stod() and QString::toDouble() in Qt5

I started a Qt project and linked to it some C++ code I wrote to parse a file. This code is using std::stod() to parse double values, and works fine in a plain c++ project, but when used with a Qt application, std::stod() returns only the integer part of the number.
I wrote and ran some test code, one compiled with g++ 6.1, and the other with qmake 5.6 and the same g++. The results are the same as my projects results.
code compiled with g++ :
#include <iostream>
int main(int argc, char ** argv)
{
const std::string number("3.14");
double dbl = std::stod(number);
std::cout << dbl << '\n'; // 3.14
return 0;
}
It shows the good value : 3.14
code compiled with Qt :
#include <QCoreApplication>
#include <QDebug>
#include <iostream>
int main(int argc, char *argv[])
{
QCoreApplication a(argc, argv);
const std::string snumber("3.14");
const QString qnumber = QString::fromStdString("3.14");
double std_d = std::stod(snumber);
double qt_d = qnumber.toDouble();
qDebug() << std_d << qt_d; // 3 3.14
std::cout << std_d << ' ' << qt_d << '\n'; // 3 3.14
return a.exec();
}
Can you tell me why std::stod() behaves like this ?
Because std::stod is broken beyond repair and should burn in hell is implemented in terms of std::strtod, which interprets doubles according to the current locale. QString instead always uses the C locale (use QLocale for locale-specific conversions).
Creating the QCoreApplication instance causes a call to setlocale(LC_ALL, ""), which sets the process' locale according to the environment, thus changing std::stod behavior.

how to read QByteArray and run as Detached process in qt?

I'm trying to run the hardcoded base64 .exe file in a Detached process.
What I'm trying now is:
void Read(QString file){
QProcess process;
process.startDetached(file);
}
int main(int argc, char *argv[])
{
QCoreApplication a(argc, argv);
QByteArray exe = QByteArray::fromBase64("TVqQAAMAAAAEAAAA...."); //base64 of .exe file
QString s = exe.data();
qDebug() << s ;
Read(s);
return a.exec();
}
not working, debug shows : "MZ?"

How to restart a qt application after crashing?

Is it possible to restart a qt application after its crashing? Just like those windows service which will restart on its own. If so, how could I do it? I have tried code like this:
#define RESTART_CODE 1000
int main(int argc, char *argv[])
{
int return_from_event_loop_code;
QPointer<QApplication> app;
QPointer<MainWindow> main_window;
do
{
if(app) delete app;
if(main_window) delete main_window;
app = new QApplication(argc, argv);
main_window = new MainWindow(app);
return_from_event_loop_code = app->exec();
}
while(return_from_event_loop_code==RESTART_CODE)
return return_from_event_loop_code;
}
But it is not working...
What should I do now?
create another qt application that runs your application.
#include <QApplication>
#include "QProcess"
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
QProcess aProcess;
QString exe = "Your process name with exact path";
QByteArray myOut;
while(1)
{
aProcess.start(exe);
//aProcess.waitForStarted();
//myOut = aProcess.readAllStandardOutput();
//printf("%s",myOut.constData());
aProcess.waitForFinished(-1);
//QString output(aProcess.readAllStandardOutput());
myOut = aProcess.readAllStandardOutput();
printf("%s",myOut.constData());
}
return a.exec();
}
this program will restart your app when it crashed or closed
You can use my open source library:
https://marketplace.qt.io/products/main-loop-wdt-for-qt-qml
It is a watchdog timer for the main loop and only works if the main loop freezes (double mutex lock, infinite loop, etc.), but it would not work in an application crash.

QX11EmbedWidget and QX11EmbedContainer

Can one place an arbitrary program (firefox, openoffice, etc...) in a QX11EmbedContainer? The fllowing seems, to work
int main(int argc, char *argv[])
{
QApplication app(argc, argv);
QX11EmbedContainer container;
container.show();
QProcess * process = new QProcess(&container);
QString executable("xterm");
QStringList arguments;
arguments << "-into";
arguments << QString::number(container.winId());
process->start(executable, arguments);
int status = app.exec();
process->close();
return status;
}
but the next snippet launches a new window, not what I want
int main(int argc, char *argv[])
{
QApplication app(argc, argv);
QX11EmbedContainer container;
container.show();
QProcess * process = new QProcess(&container);
QString executable("konsole");
process->start(executable);
int status = app.exec();
process->close();
return status;
}
The first example work because xterm is able to reparent its top level widget (an X11 window). You tell it to do so with the argument -into <WinId>.
I don't know if Konsole can do that, i don't use it and the man page doesn't seem to talk about this.
But that doesn't mean it is not doable, the X Window system is very flexible and anyone can reparent another window (that's how windows managers add decorations to windows).
Take a look at man 3 XReparentWindow ;-)

Resources