Qt5 app crashes when run from outside Qt - c++

I have a strange issue that appeared only recently.
When I acces an external binary from inside my Qt app, the app crashes with the error:
Exception Type: EXC_CRASH (SIGABRT)
But when I run it from the "build and run" inside Qt Creator, everything runs fine when I acces the point in my application where I hit an exetrnal binary.
This is the function I hit when the app crashes from outside Qt creator
QString Api::getVideoFrame(QString filename, QString position)
{
const QString ffmpeg = QDir::currentPath()+"/ffmpeg"; //mac version
QProcess process;
QStringList args;
args << "-ss" << position
<< "-i" << filename
<< "-f" << "image2"
<< "-vframes" << "1"
//<< "-vcodec" << "bmp"
<< "pipe:1";
process.start(ffmpeg, args);
process.waitForFinished();
return QString(process.readAllStandardOutput().toBase64());
}
It also crashes when accessing other external binaries, not only ffmpeg in this case.
I have the feeling it has something to do with the QDir::currentPath() because when I mess up the path, It also crashes from inside Qt Creator.
obviously I added the corresponding binaries next to the executable file in the Contents/MacOS/ folder
I don't really know how to debug this.. any clue how to solve this?

I actually found out why this happens and it is quite interresting to note that
QDir::currentPath()
has to be used with care on mac osX.
When an app is executed from within Qt Creator it returns :
/Volumes/LSPRO/Build/LSPRO.app/Contents/MacOS
including the path to te binary inside the .app package
But when you run it as a standalone app, it returns
/Volumes/LSPRO/Build
At least on my configuration...

I don't really know how to debug this.. any clue how to solve this?
Yes, I have some clue.
You could try using QCoreApplication::applicationDirPath() for this scenario to get this working properly on MAC as also asserted by a user in the comment.
Here you can find the filesystem engine source code though if you wanna further track the issue down with your suspect as a bug. In short, there is not much Mac specific code in there rather than Unix.
Also, in the future you may wanna consider QtMultimedia rather than dealing with QProcess and external execution.

Related

osx: external program (qprocess) crash if parent run with open, but works fine if parent run directly

I faced the strange situation on MacOS 10.13 and can't find what is the root of it.
I have 32-bit Qt application packed in a bundle. Because of MacOS limitation for one of the operations I need to start small 64-bit console binary that does a trick. This console binary placed in Contents/MacOS and I start it using QProcess.
Everything works fine if I run the main application from IDE. Also, everything fine if I open a terminal, cd to Contents/MacOS and run the main application directly.
But once I use "open myApp.app" or start it via UI, then QProcess exitCode() returns 255, which seems to mean crash.
Code for starting subprocess:
QProcess p;
p.start("./papply", QStringList() << osid << filepath);
p.waitForFinished(5000);
qDebug() << p.readAllStandardOutput();
qDebug() << p.readAllStandardError();
qDebug() << p.state();
if(p.state()==QProcess::Running)
{
qDebug() << "peapply freezed - kill";
p.kill();
return false;
}
qDebug() << "Apply" << osid << filepath << "=" << p.exitCode();
return p.exitCode()==0;
Any help will be very appreciated.
I have 32-bit Qt application packed in a bundle.
Firstly, just in-case you missed this, Apple have stated that the next version of the OS (10.14) will not support 32-bit applications, so you'll need to change this if you want to run this application on future versions of macOS.
If you use the debugger, or run a binary from a bundle's Contents/MacOS folder, it executes directly. In contrast, if you double-click on a binary, or use the open keyword from the terminal, a request is sent to Launch Services, to open the application on your behalf.
Launch Services (LS) maintains an association to an application's Bundle Identifier, which is located in the application bundle's Info.plist file.
When a request to open an application with LS occurs, LS is presented with the Bundle Identifier, from the application's plist and LS will execute the application that has been registered, with that identifier.
In the plist, we also have the key CFBundleExecutable, which is defined as the "(Recommended) Name of the bundle's executable file". This is the name of the binary that will likely be executed, residing in the Contents/MacOS folder.
Note, since LS launches the application associated with the given identifier, if there is a copy of the same application on your machine, with the same version number and identifier, it may not be necessarily executing the application you double-clicked, to run.
Therefore, the reason for the crash is most likely due to a different application being launched by LS and not the one you think is being executed. Ensure you have no other copies of the application residing on the machine.
If a crash report is generated, you should be able to see the path to the application, at the start of the images section, where it includes paths to dynamic libraries and frameworks.
While #TheDarkKnight provided great information that is not exactly an answer.
For people who will face the same situation:
In macOS bundle application has working directory related to bundle, but not to the execution file itself as it happens in Windows.
So in my case next code works:
QString path = qApp->applicationDirPath();
if(!path.endsWith("/"))
path += "/";
QProcess p;
p.start(path + "papply", QStringList() << osid << filepath);

Qt Creator - Code is running but I get an error message from the IDE

As soon as I run my code (note that I'm using C only, no QT and no C++) I get the following message from the application output inside the IDE:
Cannot obtain a handle to the inferior: The parameter is incorrect.
When I delete the makefiles and debug/release folders it's running but after some time I still get the error. It's not that much of a problem though, the code runs and everything is fine but this error pops up and it's quite annoying.
The content of the .pro file is:
TEMPLATE = app
CONFIG += console
CONFIG -= app_bundle
CONFIG -= qt
QMAKE_CC = gcc -std=c99
SOURCES += main.c
Thanks in advance!
edit: I have added C++ tag, because this error occurs also for C++ console application as in my case.
I have met same problem. Tips and advices on forums are rather clueless, so I investigated problem myself and I have found that it's a bug in QtCreator.
There is dirty little program called qtcreator_process_stub. Whenever you run your program within IDE, IDE first runs qtcreator_process_stub and passes your program name as parameter (among some other parameters). qtcreator_process_stub then starts your program as separate process and prints its PID (and on windows also thread id). Information is printed to the pipe and then it is read by ConsoleProcess::readStubOutput(), which is part of Utils.dll library used by QtCreator.
The problem occurs when "inferior" process (your application) finishes execution before whole communication has been processed. ConsoleProcess::readStubOutput() attempts to use OpenProcess() on non-existing process with closed handle. OpenProcess() fails hence error "Cannot obtain a handle to the inferior: The parameter is incorrect.". Whole error is not handled very gently (Uhm, and now what?)... :-/
Solution:
When you add some user input action, pause, sleep, delay or just some loops, so that execution of your application is a bit longer error vanishes. There is enough time for ConsoleProcess::readStubOutput() to execute OpenProcess(), before your application quits. So as a workaroud I suggest to do that until the bug is fixed.
I got the same error repeatedly while working on a C++ project in Qt. I was able to solve it by copying one of the shared libraries(.dll) I was using in to the build folder.
So, if you are using any shared external libraries that are needed at runtime, make sure they are in the builds folder.

Qt not building project file

I'm getting started with C++ and I use Qt Creator (I run Lubuntu 13.04).
Today, as any good start with programming, I wrote my Hello World program to see if things work after installing Qt5 and Qt Creator.
I created a new Console Application project and wrote:
#include <iostream>
using namespace std;
int main()
{
cout<<"Hello World!";
return 0;
}
Saved my project as Test, and tried to run it.
I just keep getting
Starting /home/MYUSERNAME/Qt Programming/Test/Test...
Cannot change to working directory '/home/MYUSERNAME/Qt Programming/Test': No such file or directory
/home/MYUSERNAME/Qt Programming/Test/Test exited with code -1
Any ideas on how to fix this?
Thanks in advance.
Just maybe problem is a space in 'MYUSERNAME/Qt Programming/Test'.
Anyway take a look in project build settings. Something is wrong with path where compiler is looking for your project
Are you sure there is a "Test" directory in the "/home/MYUSERNAME/Qt Programming/Test" directory ?
Using my qt4 installation I've tried starting a new Qt Console Application, chosen the folder to create project in, typed out Test for the Project name hit next, deselected Debug, but kept release. Hit next. chose none for version control, hit finish.
Program skeleton shows up. Must delete the include statement for QCoreApplication. Replace it with iostream. Deleted "QCoreapplication a" and "return a.exec". put in std::cout<<"Hello World \n"; and return 0;. Then I saved everything hit the play button and xterm is opened and displays hello world. No problems here. I even tried with spaces in directory names. Again no problems.
Then I tried creating project non-qt-project->plain c++ project. After the same menus as above, found a skeleton with exactly your code except with an endl at the end of cout statement. Hit the play button. Again no problems here. Again it opened up xterm and printed out Hello World!
Don't know what else to tell you. If you changed the name to Test AFTER you created the project, I would say, start again and this time don't change the name.
I may install qt5 on my opensuse 12.3 x86_64 installation and will be able to see if there are problems with it.

How to launch the associated application for a file / directory / URL?

Linux seems to be easy: xdg-open <file/directory/URL>.
Apparently, Mac is similar: open should be used instead of xdg-open. I don't have access to a Mac so I couldn't test it.
For Windows, I found 4 different suggestions and those that I have tried failed.
Is there a non-java, cross platform way to launch the associated application for a certain file type?
suggests start
How to give focus to default program of shell-opened file, from Java? suggests
cmd /c start ...
How to open user system preferred editor for given file?
How to Find Out Default File Opener with Java?
suggest RUNDLL32.exe
What is the correct way to use ShellExecute() in C to open a .txt
Open file with Windows' native program within C++ code
How to use ShellExecute to open html files in Windows using C++? suggest
ShellExecute
I have tried the first 3 with system() and QProcess::startDetached() and "http://www.stackoverflow.com" as argument but they all failed; start works just fine from the command line though. I haven't tried ShellExecute yet.
What is the Windows equivalent of xdg-open? It seem to me, it is start but why did my attempts with start fail?
Is ShellExecute my only option?
EDIT I thought QDesktopServices::openUrl() was for web pages only because it did not work for files or directories.
After some debugging I figured out that if I replace \\ with / in the path on Windows, it works for files but the directories are still not opened. Any ideas what I am doing wrong?
QDir dir("C:/Documents and Settings/ali");
qDebug() << "Exists? " << dir.exists();
qDebug() << dir.absolutePath();
QDesktopServices::openUrl(QUrl(dir.absolutePath()));
qDebug() << "External app called";
Application Output:
Exists? true
"C:/Documents and Settings/ali"
External app called
But nothing happens, the directory is not opened. On Linux, directories are opened with the default file manager as expected.
SOLUTION: Due to the Qt bug and Windows quirks (malformed application window), I ended up using ShellExecute. That gives me enough flexibility to achieve exactly what I want at some expense...
Why don't you just use Qt's support for this? For example:
QDesktopServices::openUrl(QUrl("/home/realnc/test.pdf"));
This opens the document in Acrobat Reader. In general, it obeys the preferred application settings in my OS for all file types that have one or more applications associated with them. Best of all, it's platform-independent.
Edit:
The fact that it opens directories on Linux but not on Windows smells like a bug. It might be best to report this on Qt's bug tracker. In the meantime, you could have a workaround for Windows for when the file is a directory:
#ifdef Q_WS_WIN
if (QFileInfo(path).isDir())
QProcess::startDetached("explorer", QStringList(path));
else
#endif
QDesktopServices::openUrl(QUrl(path));
You can also do it with cmd.exe's start command, but you'll get an ugly terminal pop up for a few fractions of a second:
QProcess::startDetached("cmd", QStringList() << "/C" << "start"
<< QDir::toNativeSeparators(path));

Issue with QCA (Qt C++ Encryption Library) run on windows 7

I am using Qt 4.8.1, MinGW compiler and Qt Creator, all on windows 7. I want to add an encryption/ decryption library to my project. After searching the web for couple days I found QCA. Fortunately I found a pre-built version using the same C++ compiler I am using, and a pre-built version of the needed plugins.
I followed the instructions to add the QCA library to my project. I used a code like this to encrypt using AES:
QCA::Initializer init = QCA::Initializer();
//Here where the execution stops
QCA::SymmetricKey key = QCA::SymmetricKey(16);
QCA::InitializationVector iv = QCA::InitializationVector(16);
QCA::Cipher cipher = QCA::Cipher(QString("aes128"), QCA::Cipher::CBC,
QCA::Cipher::DefaultPadding, QCA::Encode,
key, iv);
if (!QCA::isSupported("aes128-cbc-pkcs7"))
{
qDebug() << "AES128 is not supported";
return;
}
The code compiles just fine but when I run the application stops with unknown reason.
I really got tired from this bug, if anybody can help it will be very very very appreciated.
For future programmers that might get stuck on this
QCA loads the plugins at runtime, so even if it compiles fine, if the plugin is not in a searchable folder, it won't load.
You can check if that's the problem by calling qDebug() << QCA::supportedFeatures();. If the plugins are not being loaded, you'll get something like:
("random", "md5", "sha1", "keystorelist")
You should be able to see the folders QCA is looking up by calling:
qDebug("%s", QCA::pluginDiagnosticText().toUtf8().constData());
Apparently, plugins must be placed in a subdirectory called crypto in the libs root directory.
You can check for all the paths where Qt looks for libraries using:
qDebug() << QCoreApplication::instance()->libraryPaths();
This documentation might have some useful information: http://doc.qt.io/qt-4.8/qpluginloader.html