UML tools and c++ code generators

List of UML modellers

UML tools

Windows 8.1 tuning (to look and behave like win7)

Use Windows 8.1 in default configuration as developer machine is hell on the earth. So, here are the steps how to turn Windows 8.1 back to classic…

 

  • Configure your user as TRUE administrator (link)
  • Replace metro by classic start menu (link)
  • split monitor to more areas (WinSplit revolution, alternative ownload link)
  • Windows firewall extension to notify about outgoing connections (link)
  • Disable local http server on port 80 (after visual studio installation!!) (link) HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\HTTP\start =  4
  • Enable administrative sharing for c$,d$, … (superuserHKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System\LocalAccountTokenFilterPolicy=
  • Disable top left/right corner clip HKEY_CURRENT_USER\Control Panel\Desktop\MouseCornerClipLength=0

Qt5 application hangs-up when QNetworkAccessManager and QEventLoop is used on Mac OS

To be more specific, problem occurs only in very specific circumstances. It’s in situation, when application is compiled as console-app and it’s compiled on Mac OS X version older than 10.9:

CONFIG -= gui
CONFIG -= console

and when you’re using QEventLoop::exec in mode processing all events except user events (QEventLoop::ExcludeUserInputEvents):

//it's only demonstration, not full code...
QNetworkAccessManager manager; ...
QNetworkRequest request; ...
QNetworkReply *reply = manager->post(request,arData);
...

eventLoop.exec(QEventLoop::ExcludeUserInputEvents);

In this situation, application hangs-up. When the application is compiled with GUI mode or when application is compiled on Linux/Windows (no matter if gui or console), everything works find. To fix this problem, it’s necessary to implement hack similar to this (simplified version):

   bool bAllowUserInputEvents = false;

#if defined(PLATFORM_MACOS) && defined(AX_APP_CONSOLE)
   bAllowUserInputEvents = true;
#endif

  if ( bAllowUserInputEvents == false )
    eventLoop.exec(QEventLoop::ExcludeUserInputEvents);
  else
    eventLoop.exec(QEventLoop::AllEvents);

Qt5 application crashed with error 0xc0000005

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:

Windows applications logs

The most interesting part of this log is crash location: ntdll.dll

Faulting application name: Skipper.exe, version: 3.0.1.1120, time stamp: 0x53e9c8d7
Faulting module name: ntdll.dll, version: 6.1.7601.18247, time stamp: 0x521ea8e7
Exception code: 0xc0000005
Fault offset: 0x0002e3be
Faulting process id: 0x1c88
Faulting application start time: 0x01cfb606553e594b
Faulting application path: T:\S2\Skipper.exe
Faulting module path: C:\Windows\SysWOW64\ntdll.dll
Report Id: 98cc8228-21f9-11e4-ab5d-005056c00008

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.

Debuging crash in VisualStudio 2013

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?

Resolution

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:

QStringList QCoreApplication::libraryPaths()

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.

Solution?

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

void QCoreApplicationPrivate::prependApplicationPathToLibraryPaths()
{
#ifndef QT_NO_LIBRARY
    QStringList *app_libpaths = coreappdata()->app_libpaths;
    if (!app_libpaths)
        coreappdata()->app_libpaths = app_libpaths = new QStringList;
    QString app_location = QCoreApplication::applicationFilePath();
    app_location.truncate(app_location.lastIndexOf(QLatin1Char('/')));
#ifdef Q_OS_WINRT
    if (app_location.isEmpty())
        app_location.append(QLatin1Char('/'));
#endif
    app_location = QDir(app_location).canonicalPath();
    if (QFile::exists(app_location) && !app_libpaths->contains(app_location))
        //CHANGE THIS ROW: app_libpaths->append(app_location);
        //TO FOLLOWING
        app_libpaths->prepend(app_location);
#endif
}

InApp solution

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.

  QString executable = argv[0];
  QString executablePath = executable.mid(0,executable.lastIndexOf("\\"));
  QString installPathPlugins = QLibraryInfo::location(QLibraryInfo::PluginsPath);
  QCoreApplication::removeLibraryPath(installPathPlugins);
  QCoreApplication::addLibraryPath(installPathPlugins);
  QCoreApplication::addLibraryPath(executablePath);

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.

How to create .pdb files also for Release version of Qt library

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.

QMAKE_CXXFLAGS+=/Zi
QMAKE_LFLAGS+= /INCREMENTAL:NO /Debug

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

Qt</span>\mkspecs\win32-msvc2005\qmake.conf

and add following lines (it should be sufficient to add only /Zi and /Debug switch):

QMAKE_CFLAGS_RELEASE += /Zi
QMAKE_LFLAGS_RELEASE += /INCREMENTAL:NO /DEBUG

Visual Studio 2013 – Visualizers

One of very useful feature of Visual Studio is custom variables views. It’s possible to configure own views to each of your class. For this, VS2013 (and VS2012) uses .natvis files located in following directories:

%VSINSTALLDIR%\Common7\Packages\Debugger\Visualizers
%USERPROFILE%\My Documents\Visual Studio 2013\Visualizers

Files are stored in common .xml format and has following format:

<AutoVisualizer xmlns="http://schemas.microsoft.com/vstudio/debugger/natvis/2010">
  <Type Name="String::CStringHolder&lt;String::string_trait&lt;char&gt; &gt;">
    <DisplayString>{m_pszData,s8}</DisplayString>
    <StringView>m_pszData</StringView>
    <Expand>
      <Item Name="[m_pszData]">m_pszData</Item>
      <Item Name="[nDataLength]">m_pStringData->nDataLength</Item>
      <Item Name="[nAllocLength]">m_pStringData->nAllocLength</Item>
      <Item Name="[nRefs]">m_pStringData->nRefs</Item>
    </Expand>
  </Type>
</AutoVisualizer>

Debugging .natvis files

Visual studio contains a way how to catch syntax and logical errors in natvis format. All warnings/errors can be displayed to Visual Studio output panel by specifying following registry key to “1”.

HKEY_CURRENT_USER\Software\Microsoft\VisualStudio\12.0_Config\Debugger
"EnableNatvisDiagnostics"=dword:00000001

Note: It’s necessary to restart Visual studio to turn on this feature

Other usefull links

Code signing certificate for windows

We encounter several problems when we tried to deploy our new version of ORM Designer – Skipper to our new web site skipper18.com. Although new Skipper installer is very simmilar to ORM Designer installer, when downloading this exe-file from the new site  we are getting this error:

installer.exe is not commonly downloaded and could harm your computer

IE_No_Digital_Signature

 

The problem is somewhere in chrome/IE when evaluating downloaded file. Probably combination of new site, new executable and new name of product is the problem.

To fix this issue, we decided to sign-in installer and application executable by Code-signing certificate. There are a lot of certificate providers and the costs are very different. A lot of providers are selling these certificate for around $500/year. Fortunately it’s possible to found certificates also for $75 – $95/year. The cheapest one is from tucows.com but based on the site and additional tools I decided for ksoftware.net, The price $95/year isn’t so different but they offer also command line and GUI signing tool for their certificates called kSign.

Order process

Fill your company details, pay with paypal and wait until someone from Comodo will contact you with additional details. It’s necessary to have the same contact information on the domain registration as on certificate registration. It is also necessary to have company registered in one of publicly available lists with the same company information as on certificate registration.

Next step is a validation through phone call. It is a quick call when you confirm registration info through the call in order to verify your phone number. Phone call is the last necessary step and then you receive email with certificate:

Windows developer certificate

Usage

Signing of the application and installer is pretty easy. K-Software offers two applications for this purposes. The first one is with GUI, second one is command line based. Both applications need only few parameters like where the certificate is stored, certificate password, application description, link and executable location:

kSign

Command line application is executed through following command:

kSignCMD.exe /d "Skipper application" /du "http://www.skipper18.com" /f PATH\certificate.pfx /p PASSWORD PATH\Skipper.exe

And that’s all. Now if you checked your executable through properties in Windows explorer, you see that your application is correctly signed:

Signed application

External links

How to configure S3 domain alias on web with cloudflare

We’re using S3 as a storage for releases of Skipper (originally ORM Designer). It’s a good and fast solution, but links to downloads aren’t so pretty:

https://s3.amazonaws.com/downloads.skipper18.com/Skipper-3.0.0.1024-Windows-all-32bit.exe

but what we want is something like this :

https://downloads.skipper18.com/Skipper-3.0.0.1094-Windows-all-32bit.exe

The solution is pretty simply. The only necessary thing is to create bucket on S3 with the same name link domain where the downloads will be available:

S3 bucket

and then configure new CNAME in cloudflare:

S3 alias

type: CNAME
name: downloads.skipper18.com
alias: downloads.skipper18.com.s3.amazonaws.com

And that’s all. Domain should be ready within fews seconds.

External links:

 

How to fix Lenovo R61 graphics card? With FIRE! ;-)

Last night my Lenovo R61 seemed to be dead. It doesn’t want to boot up and the only thing I saw was this screen with some black/white lines:

R61 broken graphics card

I started googling this problem and it looks like this issue is quite common for this type. But then in the middle of the night I found the solution that I hadn’t believed it could work. But as the notebook still wasn’t running, I said to myself that there is nothing to lose.

Here is the magic. It’s sufficient to heat nvidia chip by a flame for about 15sec.

First of all, it’s necessary to disassemble notebook and detach heatpipe:

Lenovo R61 dissasembled

R61 dissasembled

After that you need to cover the rest of notebook except nvidia chip:

R61 nvidia fix

And as last step use any torch to heat chip to 700C for about 15s:

R61 fix tool - torch

And that’s it. Now assemble notebook back (if it is possible :-)) and run it:

R61 assembled and back online

Here are two videos from youtube:


How to change plist value on MacOS 10.9+

When .plist file is manually updated on MacOS 10.9+, changes are not directly applied to plist cache. This means that  these changes aren’t visible to executed application (even if you run it after plist change).

It’s necessary to tell plist change to reload this settings. There are two ways how to do it. First one is simpler but doesn’t work if you completely remove .plist file:

defaults read ~/Library/Preferences/com.xxx.xxx.xxx

Second method is much more efficient, but requires to completely kill plist cache. This cache is immediately executed again and during this launch all plist files are scanned and loaded again:

kill cfprefsd

Qt app crash on mac when executed with parameters

Our reporting tool occasional crashed on MacOs when was executed with several command line params. Command looked like this:

/app-path/OrmDesigner2 -crash-report -dump-directory /var/folders/4z/k1r35jnn4v77mzl7hzf8wvvw0000gn/T/OrmDesigner2/CrashReports

When inspecting exception report, we found following stack trace:

Thread 0 Crashed:  Dispatch queue: com.apple.main-thread
0   QtCore                         0x0000000100d671da QString::fromLocal8Bit(char const*, int) + 42
1   QtCore                         0x0000000100e72dac QCoreApplication::arguments() + 124
2   QtGui                          0x00000001000de8ef -[QCocoaApplicationDelegate application:openFiles:] + 223
3   com.apple.AppKit               0x00007fff805f3b52 -[NSApplication(NSAppleEventHandling) _handleAEOpenDocumentsForURLs:] + 505
4   com.apple.AppKit               0x00007fff804c0065 -[NSApplication(NSAppleEventHandling) _handleCoreEvent:withReplyEvent:] + 217
5   com.apple.Foundation           0x00007fff800f90d6 -[NSAppleEventManager dispatchRawAppleEvent:withRawReply:handlerRefCon:] + 360
6   com.apple.Foundation           0x00007fff800f8f06 _NSAppleEventManagerGenericHandler + 114
7   com.apple.AE                   0x00007fff82b1c32b aeDispatchAppleEvent(AEDesc const*, AEDesc*, unsigned int, unsigned char*) + 162
8   com.apple.AE                   0x00007fff82b1c224 dispatchEventAndSendReply(AEDesc const*, AEDesc*) + 32
9   com.apple.AE                   0x00007fff82b1c12b aeProcessAppleEvent + 210
10  com.apple.HIToolbox            0x00007fff875ed619 AEProcessAppleEvent + 48
11  com.apple.AppKit               0x00007fff803c5095 _DPSNextEvent + 1191
12  com.apple.AppKit               0x00007fff803c4801 -[NSApplication nextEventMatchingMask:untilDate:inMode:dequeue:] + 155
13  com.apple.AppKit               0x00007fff8038a68f -[NSApplication run] + 395
14  QtGui                          0x00000001000e7c04 QEventDispatcherMac::processEvents(QFlags) + 1588
15  QtCore                         0x0000000100e70774 QEventLoop::processEvents(QFlags) + 68
16  QtCore                         0x0000000100e70a94 QEventLoop::exec(QFlags) + 180
17  QtCore                         0x0000000100e720bc QCoreApplication::exec() + 188
18  com.inventic.ormdesigner       0x0000000100003447 main + 46 (main.cpp:31)
19  com.inventic.ormdesigner       0x00000001000032e0 start + 52

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!

//construct application object
CApplication(int& argc, char **argv);

External links