Tuesday, February 8, 2011

The case deserves your attention: incorrect checksum for freed object

When I port my free screen capture tool DuckCapure to Mac OS. I got an exception every time when I start to capture the screen. The error message is:
DuckCapture(10059,0x7fff7006aca0) malloc: *** error for object 0x103468168: incorrect checksum for freed object - object was probably modified after being freed.

*** set a breakpoint in malloc_error_break to debug

The program has unexpectedly finished.

I'm very confused with this assertion, the error happens when I use the data member from an internal class called DWidgetData, the constructor is as follows:
    DWidgetData()
        : m_pStyledContainer( NULL )
        , m_pContainerContainer( NULL )
        , m_pLayout( NULL )
        , m_pAnimationFading( NULL )
        , m_pEffectOpacity( NULL )
        , m_pEffectDropShadow( NULL )
    {}

The debugger shows a very strange content for a just initialized DWidgetData object:
Looks like the data corruption, or the constructor is never called. I have another test application which used the same component and passed the test, but DuckCapture failed. I spent hours on this issue, and finally resolved it:

Reason: In dynamic linked library DuckCore, I used forward declaration for DWidgetData in header file, and defined the class in source file. Looks reasonable, huh? However, I happened to define another DWidgetData in DuckCapture also. That's the nightmare. The code in DuckCore used the DWidgetData in DuckCapture instead of the one defined in the source file I used it.

This is another dangerous case on compiler compatibility: Visual Studio 2008/2010 on Windows works, but gcc 4.2 on Mac OS does not.

Monday, February 7, 2011

Qt Creator/qmake compiling issues on Mac and Windows

Qt Creator is the best tool for you to create/maintain cross platform (Mac, Windows, Linux) project files. You can use Qt Creator project file (*.pro) to handle the platform dependent files as well. In addition, there are also slight difference between Windows and Mac when you use qmake.

1. Add platform dependent configures in pro file.


Please refer to the code below:
mac {
ICON = images/app.icns
OBJECTIVE_SOURCES += utils.mm
LIBS += -framework Cocoa
QMAKE_INFO_PLIST = min.us.Info.plist
}
win32 {
SOURCES += \
    utils.cpp
RC_FILE = min.us.rc
}

You can use "mac { ... }" to include any information which is specific to Mac OS. For example, the application icon which is specific for Mac OS, framework, or an Objective-C source file. Someone may use the style "else:win32{ ... }". I prefer the condition without "else:". Please note that "unix { ... }" has already included the case that this is a Mac machine, so if you have something works only on unix, you can use one of the two styles: "unix:!mac { ... }", or "mac { ... } else:unix { ... }"

2. Use qmake to generate makefile or project files for Visual Studio / XCode


qmake is a great command line tool, I used it to generate project files for my favorite IDE on different platforms: Visual Studio on Windows, xCode on Mac OS. I use Qt Creator as my IDE on Ubuntu.

On Windows, the command "qmake -tp vc" can generate vcxproj for Visual Studio 2010 or vcproj file for Visual Studio 2008 depending on your command line environment, or you can specify the version explicit by "-spec" parameter or by setting environment variable "QMAKESPEC". The "qmake -tp vc" means, use the templat prefix "vc" when run qmake for pro file, actually template prefix "vc" means generate Visual C++ project file.

On Mac, you the default behavior of "qmake" just generate xcode project file. So just run "qmake" under the folder with "pro" file.

You may also need to generate make file to make an automated building script. qmake can also do it perfectly. On Windows, the default behavior of "qmake" is to generate makefiles, and then you can follow with "nmake" or "nmake debug"/"nmake release". On mac, if you run "make", you may get the error message "make: *** No targets specified and no makefile found. Stop.", just run the command "qmake -spec macx-g++" to generate makefile: use "spec" parameter to specify the make spec "macx-g++" which will help you to generate makefile.

3. Handle application icons on Mac OS / Windows


On Windows, you need to have an "rc" file, and add an icon file. Please include this rc file for Windows only. On Mac, use the qmake internal variable "ICON' to specify the application icon. Please refer to the sample code above for more details.

4. C/C++ Cocoa/Carbon mixed module:


Sometimes you need to handle mixed module on Mac, that is, you may include Objective-C files in your project file. In Qt 4.7, there is still an issue if you want to generate xcode file. The bug has been logged to Nokia here: QTBUG-7953. Read the details in the bug report to get a solution, or wait for a future release.