So, one more attempt. Previous articles (part1, part2) mentioned possible solutions to fix crash insinde the QTreeWidget and QAccessibleTableCell.
Unfortunately, deselecting current item still doesn't fix all issues. The problem with deselection is that it's not handled correctly via QAccessibleTableCell:
If current index isn't valid, QAccessible doesn't correctly update currect QAccessibleTableCell object which caused all this evil crashes.
So there are two ways how to fix it. One is to manually set QAccessibleTableCell but I didn't find a way how to do that. The second way is to disable QAccessible for Property editor. Unfortunately it's not an easy task. In QAccessible exists method setActive:
But this method works only with AccessibleObserver class but not with QPlatformAcessibility which handles real QAcessible::isActive result. Because of this it's necessary to update setActive method in file qacessible.cpp inside the Qt.
and updated version:
In case you will find better way how to turn off accessibility, please let me know.
But there is still one more problem. Occasionally OS X decides to switch accessible back on:
And this is probably the reason why everything works ok on older OS X but not on 10.10. Because OS X 10.10 randomly turns accessible on which causes this crash. Accessible is usually turned on when opening some modal dialog.
This explains why opening an empty dialog increased the probability to crash the application. The only solution I have found is to disable QAccessible every time the PropertyEditor is cleared up.
This is very interesting crash and I think it should be considered as Qt bug. This problem arise only under very special circumstances. But one after another.
You will identify this problem when your application stopped/exited immediately after the start without any visible error message. It looks like the application isn't executed at all. When you check application log (Computer -> manage -> Event viewer -> Windows logs -> Application), you will see Error logs:
The most interesting part of this log is crash location: ntdll.dll
At first sight it seems like some problem inside the windows. But the opposite is true, the problem (as almost always) is inside your app ;-).
As the next step, you can try to debug this executable via Visual Studio to see what happens inside. Simply open executable as project together with .pdb files and execute it. Now you can see that application is correctly executed but crashes as soon as it touches Qt library. The location of crash is inside ntdll.dll in RtlHeapFree() function.
So the problem is inside the Qt, right? Almost true, but not for the 100%. When I tried to run this application on computers of my colleagues, everything works ok. So why the application doesn't work on my computer too?
The problem is in new Qt5 plugin system. Besides the common Qt5*.dll files which are loaded immediately after the application start, Qt5 is also loading plugins/platform-plugins dynamically when the application is executed. To locate this plugins, Qt5 uses following method to identify directories where to search for plugins:
For some strange reason this library returns as first directory path where Qt5 libraries were compiled and after that location based on the executable. So if your Qt5 path is C:\Qt5, this will be the first path where all plugins are searched for, no matter if the correct version of plugin is located in APP\plugins or APP\platforms. **I think this is serious bug in Qt5**.
Where is the problem?
And here we're getting to the core of the whole problem.
**If application is compiled on computer with one compiler and used on second computer which contains the same path to which original computer has installed Qt, the application will load all plugins from your folder instead of itself folder.**
In case your computer will contain different version of Qt, different compiler or different platform, application loads incorrect libraries and crashes. Completely, silently and without easy way to determine what's wrong.
The solution is simple, but it isn't achievable from outside of the Qt library. It would be necessary to Qt as first tried to load libraries from application directory. And only if no plugins were found in application directory, the application would try to search for plugins in Qt directory.
Qt change solution
The simplest way how to fix this issue inside the Qt library would be to rename/update appendApplicationPathToLibraryPaths function to prependApplicationPathToLibraryPaths and change
Unfortunately it isn't possible to simply change this behavior from your app. All of these operations happen directly in QCoreApplication constructor so if you try to change it after, it's too late.
The temporary solution before this problem will be resolved is to reinitialize library paths before QCoreApplication is initialized. It's necessary to clean libray paths, compute new paths and re-initialize QCoreApplication::libraryPaths before QCoreApplication object is initialized. This can be done in main.cpp of your application before you will create QApplication/QCoreApplication object.
It's not a nice solution, but it works. I tried to report this issue also to bugreports.QtProject, so maybe in later version this will be fixed.
For debugging purposes it's a good idea to keep .pdb files also for release version of your libraries. Unfortunately in default configuration Qt library doesn't generate .pdb files. It's a not big deal, create .pdb files for release version it's pretty simple.
1) Add compilation flags to .pro file
The easiest way how to create pdb files is pass /Zi switch to compiler and /Debug to linker.
2) Solution via mkspec
As pointed out in this QtProject article, another way is to edit mkspec so any future compilations will have this option turned on. It's necessary to modify correct mkspec file, for example
and add following lines (it should be sufficient to add only /Zi and /Debug switch):
Our reporting tool occasional crashed on MacOs when was executed with several command line params. Command looked like this:
When inspecting exception report, we found following stack trace:
After some google-searching I found out that the problem is in core of our application. When subclassing Qt QApplication, it's necessary to pass argc with reference, not by value. So after adding one little &, everything works like charm!
My VS2010 on every build always recreate all .moc files and associated .cpp files. Problem was in incredibuild clausule during compilation of my Qt libraries.
Although qmake added all these incredibuild defines to my VS project, Incredibuild still doesn't compile it in parallel so it was totally useless. The most simply way is edit incredibuild_xge.prf and turn-off it.
The problem is that starting with OSX 10.9 Apple changed default standard c++ library from libstdc++ to libc++.
Qt binary distribution compile with -stdlib=libstdc++ to be compatible with 10.6, Xcode 5 on 10.9 will select -stdlib=libc++ by default (for OS X 10.7 and better only). So symbol using classes from the standard library (like std::string in this case) will not resolve correctly at link time.
So it's necessary to compile all libraries with one type of libstdc++ (or libc++). Because I need to keep 10.6 compatibility, it's necessary to compile boost and other libraries with libstdc++ dependency.
To check which library is used, use otool tool:
As result you will get something like this (check /libc++1.dylib):
How to fix it for boost
it's necessary to recompile boost (and don't forget to remove ./bin.v2 directory) with these params:
and run otool again:
How to fix it for CMake libraries
In case you're using library which is built by CMake system, you need to add following flag:
How to fix other libraries
For any other library it's necessary to pass libstdc++ flag in any available way, for example modify makefile and add :
Second way how to fix it, compile app using latest compiler
Another way is to update mkspecs to compile for latest MacOS version, after that, compiler will be the same like compiler used on all other libraries. To do that, it's necessary to update file:
[caption id="" align="aligncenter" width="637"] The procedure entry point GetTickCount64 could not be located in the dynamic link library KERNEL32.dll[/caption]
Today we received report from one of our customers about problem with our ORM Designer on WindowsXP - 32bit. Our latest version returns following error:
The procedure entry point GetTickCount64 could not be located in the dynamic link library KERNEL32.dll
**The problem is that GetTickCount64 doesn't exists in XP system**.
It's necessary to compile your application (and any library which uses GetTickCount64) with correct **WINVER** and **_WIN32_WINNT **defines value. List of WINVER values for all Windows version can be found here.
You can define these values in your resource.h file:
#define WINVER 0x0501
#define _WIN32_WINNT 0x0501
or add it to a project property -> C/C++ -> Preprocessor -> Preprocessor Definitions:
If you want to define these values automatically in Qt project, add following lines to your .pro file:
#Windows XP compatability
DEFINES += "WINVER=0x0501"
DEFINES += "_WIN32_WINNT=0x0501"
Integration of Google breakpad on any platform is really challenge. I didn't figure out how to do it by using recommended ways. So I did it my way ;-)
Create your own Qt project
As first thing I did when integrating Qt and Breakpad is creation of my own .pri file. I manually add all required files from Breakpad one-by-one, starting with src/platform/exception_handler continuing with all files included in previous ones. The complete .pri file you will find at end of this post.
After that I created simple CCrashHandler (inspired by qt-breakpad project) class which register exception handler. It's necessary to implement this handler for each platform separately because each platform have different parameters in google_breakpad::ExceptionHandler() constructor. CrashHandler source code you can find also at end of this post.
Do almost all steps like on Linux integration. There is one exception, because you can't compile Breakpad tools using linux-like configure&make. You have to build these tools with XCode.
Compile google_breakpad/src/tools/mac/dump_syms/dump_syms.xcodeproj with XCode
Before I managed to successfully compile dump_syms in XCode, I have to update Architectures Debug/Release to 64-bit Intel and BaseSDK to "Latest Mac OS X". I also fix all issues displayed in the left part of XCode window.
Next step is change compilation type from Debug to Release. After a short searching I found a way in "Schema->Edit schema->Build configuration".
To be honest, I was not sure what I did, but it worked ;-). Maybe there is some easier way how to compile dump_syms in xcode, but I don't know how. This was my first contact with XCode ;-).
The application is compiled to path "/Users/User/Library/Developer/Xcode/DerivedData/dump_syms-bjvr/Build/Products/Release/dump_syms". Now copy dump_syms to safe location from where you will use it.
The most amazing thing I found about dump_syms is their platform independence. If you correctly extract symbol file on each platform and store it in one location, you can analyze any crashdump on one location. No matter what is source platform, you will analyze .dmp file by using **minidump_stackwalk ./crash.dmp ./symbols**.
How to include CrashHandler directly to your project
This is what I get when I follow all includes from **.h** and **.cpp** files starting with exception_handler.h for all platforms. With small modification you can include it to your project and your application will be fully breakpad-able ;-).
And this is the minimal implementation of your new CrashHandler. My ownd crash handler is much more sophisticate to perform reporting, sending crash dump etc. But for purposes of this article this is what you need (And also I don't want to share my whole know-how here ;-)))
Today I encounter this error after applying **macdeployqt** to my application. There is a lot of questions about this topic on google but not very answers.
The most important thing is setup following variable.
Using this you will se which libraries are loaded during execution of your application. The interesting thing is, that I see loading a libraries from their original directories instead of Application.app. But when I temporary moved these libraries from their location, libraries begin to load from then bundle location.
The reason for my "QWidget: Must construct a QApplication before a QPaintDevice" was executing an older version of QTitanRibbon from shared libraries path instead of the newest one compiled directly to /usr/lib.
The second reason for this issue was caused by another path in "export DYLD_LIBRARY_PATH". It seems that application search for libraries first in DYLD_LIBRARY_PATH and after in paths from their inner records.
In first part of this article I introduced a manual way how to deploy MacOS application. Because doing all these stuff manually was a lot of hand work, Qt introduced small tool called **macdeployqt**.
This utility looks very good, but also have some drawbacks. As first I will show you how utility works:
That's all ;-). This command should do all the hard work for you. But in some cases it didn't.
The problem is that libraries mentioned in the previous list doesn't has included absolute path. If you inspecit this library, you will se this:
And this is the problem. Inner path in library is only filename without full path, so when we link library with our executable, our executable also has only relative path. And when macdeployqt try to find this library, automatically try to search in /usr/lib.
One possible solution is copy libraries to /usr/lib. Second solution is update paths in libraries to absolute paths. The third way is fix library linker to include full paths in libraries.
I found out that the simplies way how to fix it is call install_name_tool after library compilation and fix the path (don't forget to update library paths inside other library paths!)
So, now when we have updated all libraries, we can try to create application bundle again
And if we did everything correctly, now we should have a working app ;-).
In some cases you can get error "Permission defined", "Bad file descriptor" or other similar errors when using macdeployqt.
The reason is insufficient permissions for modifying copied libraries. Simple execute
and everything should work ok. Another workaround for this issue is using newer version of Qt. I figured out that on MacOS I wrongly use Qt 4.7.4. When I correct this to version Qt 4.8.2 this issue was solved.
If you want to create simply DMG file, simply call macdeployqt with param --dmg. But this dmg doesn't look so good:
This will need more investigation how to make DMG files nicer ;-).
Everytime you run macdeployqt run it on clean folder. The best way is to call rm -rf Application, compile app and than run macdeployqt
Notes to bug in macdeployqt
The problem is caused by invalid permissions. Copied libraries have the same permissions like in the source location. There are three different solutions:
Use sudo and execute macdeployqt with root permissions
Update external libraries permissions to rw, so also copies will have a correct permissions
Update macdeployqt script. In file shared.cpp on line 91 is method copyFilePrintStatus. Here is a necessary to update copied files permissions to correct rw
In my case the problem was in file liblzma.5.dylib
The first usefull command for tracking dependencies between your application and other shared libraries is otool:
Now we can see paths to our libraries. The bad news is that MacOS doesn't have any -RPATH and $ORIGIN. The good news is utility install_name_tool and variable @executable_path which works similar like $ORIGIN. Note: For newer versions of MacOS there are more variables like @executable_path. On version 10.4 was introduced @loader_path and on version 10.5 apple introduce @rpath variable.
The step-by-step solution
As first step it's necessary to upload all dependent libraries directly to the Application.app/Contents/MacOS/. For list all required files use otool:
When we have copied all libraries, we need to change paths **for** and **in** all libraries.
Here is example how to set libxml2 library. As first step we will check how is library referred.
When we checked libxml2.2.dylib library with otool, we can see that library has hardocoded our development path. This isn't good ;-). So we now change this value to path relative to the executable and again verify this inner path.
As you can see, now is path (first line) set up to reffer @loader_path/libxml2.2.dylib. It's correct now. As second step we have to update path in our executable, because also there is path hardcoded to our library repository.
So, now we have changed also path in our executable. And now we need to do all these steps for all libraries..... ;-).
To follow the MacOS application convention it's better to place libraries to folder Application.app/Contents/Frameworks. Here is a directory schema for Qt example application plugAndPaint.
This short post will show you how to resolve following error during Qt compilation on 64-bit windows:
This error is caused by bug in **QMAKE_HOST** variable used in WebCore.pro file. This variable is tested to determine destination platform (x86 or x64).
This variable contains x86 value also on 64-bit builds instead of x86_64 value. This value is tested on the following line in a WebCore.pro file:
If you want to fix this error, simply replace **QMAKE_HOST** by **QMAKE_TARGET** variable. Updated line should look like this:
After this update all required asm defines are correctly included and build of WebKit will be successful.
Update for this error
In newer versions of Qt there is already applied fix the error with QMAKE_HOST / QMAKE_TARGET, but also there is a new problem ;-(.
The Problem is in the following "if" definition:
When you compile your project for MSVC 2010, .asm file isn't included. It's necessary to add win32-msvc2010 to this definition. So updated WebCore.pro for Qt 4.8 will look like this:
Next problem solution
Next problem which I found during compilation is wrongly set QMAKE_TARGET.arg. For unspecified reason, when I compile 64bit library in 64bit system in 64bit VS command line, this variable has value x86 instead of x86_64.
The problem is in the qmake project.cpp file. QMAKE trying to determine 64/32 bit version based on the %PATH% configuration. Qmake search for VS-PATH\bin\amd64 of \bin\x86_amd64 string. Unfortunately there is a bug in concating searched string. This is how looks original project.cpp file at line 3177:
The problem is, that VCINSTALLDIR contains \ at the end of the string, and then we append \ again. So, result is:
Now, QMake correctly determine 32/64 bit compilation and then correctly include PaintHooks.asm and your Qt WebCore will be sucesfully compiled.
If your application using some externals dynamic libraries (called .dylib in MacOs system), you have to provide all these libraries. The simplest way is to provide these libraries into the Application.app directory.
Find out which libraries are used
Qt provide really useful tool called **"otool"** which serves to lots of purpose. One of them is to detect which shared libraries are required by our application. For this purpose otool has parameter -L. The usage is following:
Output could looks like this:
Output from "otool" is simmilar to linux tool "ldd".
The Mac Deployment Tool
Because manual copying and configuring all shared libraries to our application could be difficult, Qt have deployment tool which do all work for us. Tool is called "macdeployqt" and can be found in /Developer/Tools/Qt/macdeployqt.
**Note:** Every time when you call macdeployqt tool, project have to be build from scratch. But is sufficient when whole result directory is removed and linked again:
One of big disadvantage when creating Visual studio project from .pro files using qmake is missing support for hierachical folders. All files are stored in in four folders (filters) named "Source Files", "Header Files", "Generated Files" and "Form Files". When you have large project, this arrangement is really hard to use.
qmake has undocumented setting parameter "flat". Using this switch, you can tell qmake to create filters in Visual studio dependent to directory structures of files. Only drawback of this solution is continuing sorting to "Source files","Header files",...
So result of this solution will look like this:
To achieve this behaviour, only thing what have to be done is add following line to your .pro file:
But what to do when you want to have all files stored together in structure dependent on directory structure? Only solution which I found is update qmake project for myself. This update is simply and here is what is need to be done:
Add new method initHeaderAndSourceFiles to file msvc_vcproj.cpp and .h with following content
and update method VcprojGenerator::initProject() in msvc_vcproj.cpp file. Replace following two lines (currently located on line 762)
with following code:
Now you can add new flag "grouped" to your .pro file. After that, source and header files will be merged in the visual studio project tree.
Command line for generating Visual studio project file from Qt .pro file.
Missing moc_*.cpp file
When some of moc file isn't properly generated and getting following error:
Select corresponding .h file (for moc_xxx.cpp select xxx.h) in a project tree and select **Compile** from context menu. If the file is marked as "up-to-date", try to change something in this file and repeat a compilation. If in the output window will be "up-to-date" again, you found a problem.
Use context menu on the corresponding .h file, select properties and edit "Configuration properties |Custom build steps|General|Outputs" to any value (add some char to the end of value), confirm change by Ok button and then return value back to original (remove added char). After that, compilation on correspond file will be successfully performed.