FastCGI c++ library for all platforms (Windows, Mac and Linux)

List of existing libraries

Snippets

Stackoverflow articles

Tutorials

Other links

CGICC – how to update it for VS2010 COMPILATION

  •  error C2668: ‘cgicc::copy_if’ : ambiguous call to overloaded function – add cgicc:: to all cgicc::copy_if instances
  •  error LNK2019: unresolved external symbol – add compiled .lib path (…Debug\cgicc.lib) to all dependend projects

C++ Code coverage tools for Windows and Linux (DRAFT)

Linux

  • CovTool – Free test coverage analyzer for C++
  • ggcov –  GTK+ GUI for exploring test coverage data produced by C and C++ programs compiled with gcc –coverage.
  • lcov – graphical front-end for GCC’s coverage testing tool gcov. Creates HTML pages containing the source code annotated with coverage information.
  • Trucov – open source program that works with the GCC compiler to display the control flow of a program and its test coverage information

STEPS:

1) add CXX, CFD + LINKER FLAGS

2) remove OBJS output dir and generate .o .gcov,… to root project directory

3)remove MOC directory output for Qt app

3)run gcov xx.cpp

— generate html

sudo apt-get install lcov (http://ltp.sourceforge.net/coverage/lcov.php)

lcov --capture --directory ~/dev/Applications/AtomixApp/AtomixApp --output-file coverage.info

How to use articles

How to integrate with jenkins

StackOverflow questions

Slow execution of application from Visual studio

Today my Visual Studio 2010 started to execute my application super slowly. When I tried to execute my application (without any changes in source-code) the delay between “Start Debugging” and application start was about one minute.

I know that too many breakpoints or breakpoints in templates could caused this, but I don’t see any breakpoint in my Breakpoints window.

Breakpoint window

But as I have found that the problem was really caused by breakpoints. In some special cases – when you’re using some external tools to modified your project file (.sln/.vcxproj) – breakpoints can disappear and begin to make a trouble (I’m using Qt qmake to update my project based on .pro files.)

The solution is pretty easy. Use Delete All Breakpoins from Debug menu:

Delete all breakpoints

And your problem will be solved ;-).

GetTickCount64 problem on WindowsXP

The procedure entry point GetTickCount64 could not be located in the dynamic link library KERNEL32.dll
The procedure entry point GetTickCount64 could not be located in the dynamic link library KERNEL32.dll

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.

Solution:

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:

2013-08-29_15-45-10

Qt Solution:

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"

External links:

Problem with msdia80.dll

One of tool we’re using requires msdia80.dll file. Unfortunately this DLL is available only inside the VS2005 installation / redistributable pack. When you execute dump_syms.exe without this file, you will receive following message:

CoCreateInstance CLSID_DiaSource failed (msdia80.dll unregistered?)

One solution is to install Visual C++ 2005 Redistributable Package. Another way is download only msdia80.dll file and register it manually by using:

regsrv32 msdia80.dll

Find out what wakes up your Windows 7/Vista from its sleep

@rem Get info about last wake
powercfg -lastwake

@rem Which device caused the wake up
powercfg -devicequery wake_armed

@rem More detailed info including time of sleep and wake
cmd /k wevtutil qe System /q:"*[System[Provider[@Name='Microsoft-Windows-Power-Troubleshooter']]]" /rd:true /c:1 /f:text

External Links

List of C++ profilers for windows (commercial and non-commercial)

Commercial

Free

System performance tools

Linux test tools (not tested yet)

External resources

 

How to fix “The device, \Device\Ide\iaStor0, did not respond within the timeout period.”

Link with detailed description of this problem.

Short how to fix:

regedit
open HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\iaStor\Parameters\Port[0-n]\
set LPM=0, LPMDSTATE=0, and DIPM = 0

if your registry doesn’t contain this key, you have to add them.

Add new key "Port0".
Add new "DWORD" value named "LPM" and value leave 0.
Add next two "DWORD" values named "LPMDSTATE" and "DIPM".

Another advise how to fix this error

This method is originally referred in MS Technet forum:

Also the issue may be the result of Aggressive Link State Power Management (ALPM) on the PCI-Express bus negotiating a lower power state for the link between the controller and disk when there is no activity. When ALPM works, disk requests are queued, the serial link revived, and the queued requests are sent to the relevant disk; this requires a disk that supports ALPM.

1.       Click Start button, choose Control Panel.
2.       Move to Control Panel\All Control Panel Items\Power Options. Click Change plan setting in your current power plan.
3.       Click “Change advanced power settings”, move to PCI Express-> Link State Power Management, turn off the option.

External links

Problem with compiling Boost

Warning: "using python" expects a two part (major, minor) version number; got %d.%d\nplatform=%s\nprefix=%s\nexec_prefix=%s\nexecutable=%s' % (version_info[0],version_info[1],platform,prefix,exec_prefix,executable))"  instead
Q:/ExternalLibraries/boost_trunk/tools/build/v2/build\feature.jam:276: in implied-feature from module featureerror: "version_info[1]" is not an implicit feature value
Q:/ExternalLibraries/boost_trunk/tools/build/v2/build\feature.jam:355: in expand-subfeatures-aux from module featureQ:/ExternalLibraries/boost_trunk/tools/build/v2/build\feature.jam:424: in feature.expand-subfeatures from module feature
Q:/ExternalLibraries/boost_trunk/tools/build/v2/build\property.jam:186: in property.expand-subfeatures-in-conditions from module property
Q:/ExternalLibraries/boost_trunk/tools/build/v2/build\property-set.jam:407: in property-set.create-from-user-input from module property-set
Q:/ExternalLibraries/boost_trunk/tools/build/v2/build\property-set.jam:461: in property-set.refine-from-user-input from module property-set
Q:/ExternalLibraries/boost_trunk/tools/build/v2/build\targets.jam:1580: in targets.main-target-requirements from module targets
Q:/ExternalLibraries/boost_trunk/tools/build/v2/tools\builtin.jam:532: in lib from module builtin
Q:/ExternalLibraries/boost_trunk/tools/build/v2/tools\python.jam:680: in declare-libpython-target from module python
Q:/ExternalLibraries/boost_trunk/tools/build/v2/tools\python.jam:925: in configure from module python
Q:/ExternalLibraries/boost_trunk/tools/build/v2/tools\python.jam:110: in python.init from module python
Q:/ExternalLibraries/boost_trunk/tools/build/v2/build\toolset.jam:41: in using from module toolset libs\python\build\Jamfile.v2:16: in modules.load from module Jamfile<Q:\External
Libraries\boost_trunk\libs\python\build>
Q:/ExternalLibraries/boost_trunk/tools/build/v2/build\project.jam:311: in load-jamfile from module project
Q:/ExternalLibraries/boost_trunk/tools/build/v2/build\project.jam:64: in load from module project
Q:/ExternalLibraries/boost_trunk/tools/build/v2/build\project.jam:89: in load-used-projects from module project
Q:/ExternalLibraries/boost_trunk/tools/build/v2/build\project.jam:75: in load from module project
Q:/ExternalLibraries/boost_trunk/tools/build/v2/build\project.jam:145: in project.find from module project
Q:/ExternalLibraries/boost_trunk/tools/build/v2\build-system.jam:552: in load from module build-system
Q:\ExternalLibraries\boost_trunk\tools\build\v2/kernel\modules.jam:289: in import from module modules
Q:\ExternalLibraries\boost_trunk\tools\build\v2/kernel/bootstrap.jam:139: in boost-build from module
Q:\ExternalLibraries\boost_trunk\boost-build.jam:17: in module scope from module

The problem was that boost build helper run my python.bat instead of correct python.exe from %PATH% directory.

To check which python is used enter following param:

b2 --debug-configuration:
notice: [python-cfg] Configuring python...
notice: [python-cfg] Registry indicates Python 2.7 installed at "C:\Python27\"
notice: [python-cfg] Checking interpreter command "python"...
notice: [python-cfg] running command 'python -c "from sys import *; print('version=%d.%d\nplatform=%s\nprefix=%s\nexec_prefix=%s\nexecutable=%s' % (version_info[0],version_info[1],platform,prefix,exec_prefix,executable))" 2>&1'
notice: [python-cfg] ...does not invoke a working interpreter
notice: [python-cfg] Checking interpreter command "C:\Python27\python"...

####HERE####
notice: [python-cfg] running command 'DIR /-C /A:S "C:\Python27\python.exe" 2>&1'
####HERE####

notice: [python-cfg] running command 'C:\Python27\python -c "from sys import *;print('version=%d.%d\nplatform=%s\nprefix=%s\nexec_prefix=%s\nexecutable=%s' % (version_info[0],version_info[1],platform,prefix,exec_prefix,executable))" 2>&1'
notice: [python-cfg] ...requested configuration matched!
notice: [python-cfg] Details of this Python configuration:
notice: [python-cfg]   interpreter command: "C:\Python27\python"
notice: [python-cfg]   include path: "C:\Python27\Include"
notice: [python-cfg]   library path: "C:\Python27\libs"
notice: [python-cfg]   DLL search path: "C:\Python27"

Qt and Google breakpad Windows/Linux/MacOS

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.

Using Breakpad on Linux:

Article about Linux integration.

Notes Linux

  • GCC 4.6.3
  • Ubuntu 12.04.1 32/64bit

Get and Compile Breakpad

#get breakpad latest version
svn checkout http://google-breakpad.googlecode.com/svn/trunk/ google-breakpad-read-only

#compile all breakpad tools for extracting symbol files
./configure
make
sudo make install

#when compilation is ready, you should have installed file dump_syms from original directory /src/tools/linux/dump_syms in your /usr/bin
dump_syms

Generate symbol file and test debug info

Now how to generate and use symbol file:

#generate .sym file
dump_syms ./Application > Application.sym

#store sym file in the correct location
#this step is necessary. Without that minidump_stackwalk tool doesn't work

head -n1 Application.sym
#Result: MODULE Linux x86_64 6EDC6ACDB282125843FD59DA9C81BD830 Application

mkdir -p ./symbols/Application/6EDC6ACDB282125843FD59DA9C81BD830
mv Application.sym ./symbols/Application/6EDC6ACDB282125843FD59DA9C81BD830

#show stack with using minidump_stackwalk tool
minidump_stackwalk ./crash.dmp ./symbols

Result of minidump_stackwalk tool can look like this:

Use additional tools

There is script written by Mozzila corp which simplifies extracting and storing .sym file:
http://mxr.mozilla.org/mozilla-central/source/toolkit/crashreporter/tools/symbolstore.py?raw=1

Now with this script, you can do only one step instead of all described above.

python /path/to/script/symbolstore.py /usr/local/bin/dump_syms ./symbol-storage ./Application

This command correctly creates folder Application/uuid in path symbol-storage and copy generated .sym file inside.

Using Breakpad on MacOS:

To integrate Breakpad and Qt on MacOS I used the same article as for Linux because I’m using gcc and linux-like development toolchain. For native XCode integration you have to probably use this article.

Notes MacOS

  • GCC 4.6.3
  • Qt creator toolchain
  • Mac OS 10.7.3 64bit
  • Don’t using any of XCode tool chaing

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 rest steps are same like in the Linux.

Using Breakpad on Windows

Notes Windows

Article about Windows integration.

  • Compile with Visual Studio 2010
  • Post-mortem debugging is done also via VS2010
  • Google breakpad under windows generates common .dmp files which can by simply load directly to VS

Generate symbol files and test debug info

You have to choices for Windows. First option is use standard .PDB and .DMP files mechanism in VS. Second is use the same way how you can did it for Linux and Mac.

First way: Let compiler generate .PDB file. Store this files and use them later in VS together with your crash dump.

Second way: Use dump_sys.exe. This file is located in the google breakpad directory tree: google-breakpad\src\tools\windows\binaries\dump_syms.exe .

dump_syms.exe AtomixDevelopment.exe >AtomixDevelopment.sym

And also like under Linux, you can use Python script symbolstore.py to extract symbols to correct directory:

python.exe symbolstore.py binaries\dump_syms.exe .\Symbols AtomixDevelopment.exe

Minidump stackwalk for windows:
http://code.google.com/p/pcxfirefox/source/browse/trunk/betterpgo/talos/talos/breakpad/win32/minidump_stackwalk.exe?r=19

The best thing at end

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 ;-).

# ---------- HEADER -----------------------------------------------------------
OTHERS   += $$PWD/axCrashHandler.pri
HEADERS += $$PWD/CrashHandler.h
SOURCES += $$PWD/CrashHandler.cpp

BREAKPAD_PATH=$$EXTERNAL_LIBRARIES_PATH/breakpad-qt
INCLUDEPATH += $$BREAKPAD_PATH/src

OSMAC {
  HEADERS += $$BREAKPAD_PATH/src/client/mac/handler/exception_handler.h
  HEADERS += $$BREAKPAD_PATH/src/client/mac/crash_generation/crash_generation_client.h
  HEADERS += $$BREAKPAD_PATH/src/client/mac/crash_generation/crash_generation_server.h
  HEADERS += $$BREAKPAD_PATH/src/client/mac/crash_generation/client_info.h
  HEADERS += $$BREAKPAD_PATH/src/client/mac/handler/minidump_generator.h
  HEADERS += $$BREAKPAD_PATH/src/client/mac/handler/dynamic_images.h
  HEADERS += $$BREAKPAD_PATH/src/client/mac/handler/breakpad_nlist_64.h
  HEADERS += $$BREAKPAD_PATH/src/client/mac/handler/mach_vm_compat.h
  HEADERS += $$BREAKPAD_PATH/src/client/minidump_file_writer.h
  HEADERS += $$BREAKPAD_PATH/src/client/minidump_file_writer-inl.h
  HEADERS += $$BREAKPAD_PATH/src/common/mac/macho_utilities.h
  HEADERS += $$BREAKPAD_PATH/src/common/mac/byteswap.h
  HEADERS += $$BREAKPAD_PATH/src/common/mac/MachIPC.h
  HEADERS += $$BREAKPAD_PATH/src/common/mac/scoped_task_suspend-inl.h
  HEADERS += $$BREAKPAD_PATH/src/common/mac/file_id.h
  HEADERS += $$BREAKPAD_PATH/src/common/mac/macho_id.h
  HEADERS += $$BREAKPAD_PATH/src/common/mac/macho_walker.h
  HEADERS += $$BREAKPAD_PATH/src/common/mac/macho_utilities.h
  HEADERS += $$BREAKPAD_PATH/src/common/mac/bootstrap_compat.h
  HEADERS += $$BREAKPAD_PATH/src/common/mac/string_utilities.h
  HEADERS += $$BREAKPAD_PATH/src/common/linux/linux_libc_support.h
  HEADERS += $$BREAKPAD_PATH/src/common/string_conversion.h
  HEADERS += $$BREAKPAD_PATH/src/common/md5.h
  HEADERS += $$BREAKPAD_PATH/src/common/memory.h
  HEADERS += $$BREAKPAD_PATH/src/common/using_std_string.h
  HEADERS += $$BREAKPAD_PATH/src/common/convert_UTF.h
  HEADERS += $$BREAKPAD_PATH/src/processor/scoped_ptr.h
  HEADERS += $$BREAKPAD_PATH/src/google_breakpad/common/minidump_exception_mac.h
  HEADERS += $$BREAKPAD_PATH/src/google_breakpad/common/breakpad_types.h
  HEADERS += $$BREAKPAD_PATH/src/google_breakpad/common/minidump_format.h
  HEADERS += $$BREAKPAD_PATH/src/google_breakpad/common/minidump_size.h
  HEADERS += $$BREAKPAD_PATH/src/third_party/lss/linux_syscall_support.h

  SOURCES += $$BREAKPAD_PATH/src/client/mac/handler/exception_handler.cc
  SOURCES += $$BREAKPAD_PATH/src/client/mac/crash_generation/crash_generation_client.cc
  SOURCES += $$BREAKPAD_PATH/src/client/mac/crash_generation/crash_generation_server.cc
  SOURCES += $$BREAKPAD_PATH/src/client/mac/handler/minidump_generator.cc
  SOURCES += $$BREAKPAD_PATH/src/client/mac/handler/dynamic_images.cc
  SOURCES += $$BREAKPAD_PATH/src/client/mac/handler/breakpad_nlist_64.cc
  SOURCES += $$BREAKPAD_PATH/src/client/minidump_file_writer.cc
  SOURCES += $$BREAKPAD_PATH/src/common/mac/macho_id.cc
  SOURCES += $$BREAKPAD_PATH/src/common/mac/macho_walker.cc
  SOURCES += $$BREAKPAD_PATH/src/common/mac/macho_utilities.cc
  SOURCES += $$BREAKPAD_PATH/src/common/mac/string_utilities.cc
  SOURCES += $$BREAKPAD_PATH/src/common/mac/file_id.cc
  SOURCES += $$BREAKPAD_PATH/src/common/mac/MachIPC.mm
  SOURCES += $$BREAKPAD_PATH/src/common/mac/bootstrap_compat.cc
  SOURCES += $$BREAKPAD_PATH/src/common/md5.cc
  SOURCES += $$BREAKPAD_PATH/src/common/string_conversion.cc
  SOURCES += $$BREAKPAD_PATH/src/common/linux/linux_libc_support.cc
  SOURCES += $$BREAKPAD_PATH/src/common/convert_UTF.c
  LIBS += /System/Library/Frameworks/CoreFoundation.framework/Versions/A/CoreFoundation
  LIBS += /System/Library/Frameworks/CoreServices.framework/Versions/A/CoreServices
  #breakpad app need debug info inside binaries
  QMAKE_CXXFLAGS+=-g
}

OSLIN {
  HEADERS += $$BREAKPAD_PATH/src/client/linux/handler/exception_handler.h
  HEADERS += $$BREAKPAD_PATH/src/client/linux/crash_generation/crash_generation_client.h
  HEADERS += $$BREAKPAD_PATH/src/client/linux/handler/minidump_descriptor.h
  HEADERS += $$BREAKPAD_PATH/src/client/linux/minidump_writer/minidump_writer.h
  HEADERS += $$BREAKPAD_PATH/src/client/linux/minidump_writer/line_reader.h
  HEADERS += $$BREAKPAD_PATH/src/client/linux/minidump_writer/linux_dumper.h
  HEADERS += $$BREAKPAD_PATH/src/client/linux/minidump_writer/linux_ptrace_dumper.h
  HEADERS += $$BREAKPAD_PATH/src/client/linux/minidump_writer/directory_reader.h
  HEADERS += $$BREAKPAD_PATH/src/client/linux/log/log.h
  HEADERS += $$BREAKPAD_PATH/src/client/minidump_file_writer-inl.h
  HEADERS += $$BREAKPAD_PATH/src/client/minidump_file_writer.h
  HEADERS += $$BREAKPAD_PATH/src/common/linux/linux_libc_support.h
  HEADERS += $$BREAKPAD_PATH/src/common/linux/eintr_wrapper.h
  HEADERS += $$BREAKPAD_PATH/src/common/linux/ignore_ret.h
  HEADERS += $$BREAKPAD_PATH/src/common/linux/file_id.h
  HEADERS += $$BREAKPAD_PATH/src/common/linux/memory_mapped_file.h
  HEADERS += $$BREAKPAD_PATH/src/common/linux/safe_readlink.h
  HEADERS += $$BREAKPAD_PATH/src/common/linux/guid_creator.h
  HEADERS += $$BREAKPAD_PATH/src/common/linux/elfutils.h
  HEADERS += $$BREAKPAD_PATH/src/common/linux/elfutils-inl.h
  HEADERS += $$BREAKPAD_PATH/src/common/using_std_string.h
  HEADERS += $$BREAKPAD_PATH/src/common/memory.h
  HEADERS += $$BREAKPAD_PATH/src/common/basictypes.h
  HEADERS += $$BREAKPAD_PATH/src/common/memory_range.h
  HEADERS += $$BREAKPAD_PATH/src/common/string_conversion.h
  HEADERS += $$BREAKPAD_PATH/src/common/convert_UTF.h
  HEADERS += $$BREAKPAD_PATH/src/google_breakpad/common/minidump_format.h
  HEADERS += $$BREAKPAD_PATH/src/google_breakpad/common/minidump_size.h
  HEADERS += $$BREAKPAD_PATH/src/google_breakpad/common/breakpad_types.h
  HEADERS += $$BREAKPAD_PATH/src/processor/scoped_ptr.h
  HEADERS += $$BREAKPAD_PATH/src/third_party/lss/linux_syscall_support.h
  SOURCES += $$BREAKPAD_PATH/src/client/linux/crash_generation/crash_generation_client.cc
  SOURCES += $$BREAKPAD_PATH/src/client/linux/handler/exception_handler.cc
  SOURCES += $$BREAKPAD_PATH/src/client/linux/handler/minidump_descriptor.cc
  SOURCES += $$BREAKPAD_PATH/src/client/linux/minidump_writer/minidump_writer.cc
  SOURCES += $$BREAKPAD_PATH/src/client/linux/minidump_writer/linux_dumper.cc
  SOURCES += $$BREAKPAD_PATH/src/client/linux/minidump_writer/linux_ptrace_dumper.cc
  SOURCES += $$BREAKPAD_PATH/src/client/linux/log/log.cc
  SOURCES += $$BREAKPAD_PATH/src/client/minidump_file_writer.cc
  SOURCES += $$BREAKPAD_PATH/src/common/linux/linux_libc_support.cc
  SOURCES += $$BREAKPAD_PATH/src/common/linux/file_id.cc
  SOURCES += $$BREAKPAD_PATH/src/common/linux/memory_mapped_file.cc
  SOURCES += $$BREAKPAD_PATH/src/common/linux/safe_readlink.cc
  SOURCES += $$BREAKPAD_PATH/src/common/linux/guid_creator.cc
  SOURCES += $$BREAKPAD_PATH/src/common/linux/elfutils.cc
  SOURCES += $$BREAKPAD_PATH/src/common/string_conversion.cc
  SOURCES += $$BREAKPAD_PATH/src/common/convert_UTF.c
  #breakpad app need debug info inside binaries
  QMAKE_CXXFLAGS+=-g
}

OSWIN {
  BREAKPAD_PATH=q:/Applications/breakpad-qt/third-party/latest-breakpad
  INCLUDEPATH += $$BREAKPAD_PATH/src
  HEADERS += $$BREAKPAD_PATH/src/common/windows/string_utils-inl.h
  HEADERS += $$BREAKPAD_PATH/src/common/windows/guid_string.h
  HEADERS += $$BREAKPAD_PATH/src/client/windows/handler/exception_handler.h
  HEADERS += $$BREAKPAD_PATH/src/client/windows/common/ipc_protocol.h
  HEADERS += $$BREAKPAD_PATH/src/google_breakpad/common/minidump_format.h 
  HEADERS += $$BREAKPAD_PATH/src/google_breakpad/common/breakpad_types.h 
  HEADERS += $$BREAKPAD_PATH/src/client/windows/crash_generation/crash_generation_client.h 
  HEADERS += $$BREAKPAD_PATH/src/processor/scoped_ptr.h 

  SOURCES += $$BREAKPAD_PATH/src/client/windows/handler/exception_handler.cc
  SOURCES += $$BREAKPAD_PATH/src/common/windows/string_utils.cc
  SOURCES += $$BREAKPAD_PATH/src/common/windows/guid_string.cc
  SOURCES += $$BREAKPAD_PATH/src/client/windows/crash_generation/crash_generation_client.cc 
}

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 ;-)))

CrashHandler.h

#pragma once
#include <QtCore/QString>

namespace Atomix
{
	class CrashHandlerPrivate;
	class CrashHandler
	{
	public:
		static CrashHandler* instance();
    void Init(const QString&  reportPath);

		void setReportCrashesToSystem(bool report);
		bool writeMinidump();

	private:
		CrashHandler();
		~CrashHandler();
		Q_DISABLE_COPY(CrashHandler)
		CrashHandlerPrivate* d;
	};
}

CrashHandler.cpp

#include "CrashHandler.h"
#include <QtCore/QDir>
#include <QtCore/QProcess>
#include <QtCore/QCoreApplication>
#include <QString>

#if defined(Q_OS_MAC)
#include "client/mac/handler/exception_handler.h"
#elif defined(Q_OS_LINUX)
#include "client/linux/handler/exception_handler.h"
#elif defined(Q_OS_WIN32)
#include "client/windows/handler/exception_handler.h"
#endif

namespace Atomix
{
	/************************************************************************/
	/* CrashHandlerPrivate                                                  */
	/************************************************************************/
	class CrashHandlerPrivate
	{
	public:
		CrashHandlerPrivate()
		{
			pHandler = NULL;
		}

		~CrashHandlerPrivate()
		{
			delete pHandler;
		}

		void InitCrashHandler(const QString& dumpPath);
		static google_breakpad::ExceptionHandler* pHandler;
		static bool bReportCrashesToSystem;
	};

	google_breakpad::ExceptionHandler* CrashHandlerPrivate::pHandler = NULL;
	bool CrashHandlerPrivate::bReportCrashesToSystem = false;

	/************************************************************************/
	/* DumpCallback                                                         */
	/************************************************************************/
#if defined(Q_OS_WIN32)
	bool DumpCallback(const wchar_t* _dump_dir,const wchar_t* _minidump_id,void* context,EXCEPTION_POINTERS* exinfo,MDRawAssertionInfo* assertion,bool success)
#elif defined(Q_OS_LINUX)
	bool DumpCallback(const google_breakpad::MinidumpDescriptor &md,void *context, bool success)
#elif defined(Q_OS_MAC)
	bool DumpCallback(const char* _dump_dir,const char* _minidump_id,void *context, bool success)
#endif
	{
		Q_UNUSED(context);
#if defined(Q_OS_WIN32)
		Q_UNUSED(_dump_dir);
		Q_UNUSED(_minidump_id);
		Q_UNUSED(assertion);
		Q_UNUSED(exinfo);
#endif
		qDebug("BreakpadQt crash");

		/*
		NO STACK USE, NO HEAP USE THERE !!!
		Creating QString's, using qDebug, etc. - everything is crash-unfriendly.
		*/
		return CrashHandlerPrivate::bReportCrashesToSystem ? success : true;
	}

	void CrashHandlerPrivate::InitCrashHandler(const QString& dumpPath)
	{
		if ( pHandler != NULL )
			return;

#if defined(Q_OS_WIN32)
		std::wstring pathAsStr = (const wchar_t*)dumpPath.utf16();
		pHandler = new google_breakpad::ExceptionHandler(
			pathAsStr,
			/*FilterCallback*/ 0,
			DumpCallback,
			/*context*/
			0,
			true
			);
#elif defined(Q_OS_LINUX)
		std::string pathAsStr = dumpPath.toStdString();
		google_breakpad::MinidumpDescriptor md(pathAsStr);
		pHandler = new google_breakpad::ExceptionHandler(
			md,
			/*FilterCallback*/ 0,
			DumpCallback,
			/*context*/ 0,
			true,
			-1
			);
#elif defined(Q_OS_MAC)
		std::string pathAsStr = dumpPath.toStdString();
		pHandler = new google_breakpad::ExceptionHandler(
			pathAsStr,
			/*FilterCallback*/ 0,
			DumpCallback,
			/*context*/
			0,
			true,
			NULL
			);
#endif
	}

	/************************************************************************/
	/* CrashHandler                                                         */
	/************************************************************************/
	CrashHandler* CrashHandler::instance()
	{
		static CrashHandler globalHandler;
		return &globalHandler;
	}

	CrashHandler::CrashHandler()
	{
		d = new CrashHandlerPrivate();
	}

	CrashHandler::~CrashHandler()
	{
		delete d;
	}

	void CrashHandler::setReportCrashesToSystem(bool report)
	{
		d->bReportCrashesToSystem = report;
	}

	bool CrashHandler::writeMinidump()
	{
		bool res = d->pHandler->WriteMinidump();
		if (res) {
			qDebug("BreakpadQt: writeMinidump() successed.");
		} else {
			qWarning("BreakpadQt: writeMinidump() failed.");
		}
		return res;
	}

	void CrashHandler::Init( const QString& reportPath )
	{
		d->InitCrashHandler(reportPath);
	}
}

Main.cpp

And here is how to use it:

#include "axCore/axCrashHandler/CrashHandler.h"
#include <QDebug>
#include <QCoreApplication>
#include <iostream>

int buggyFunc()
{
	delete reinterpret_cast<QString*>(0xFEE1DEAD);
	return 0;
}

int main(int argc, char * argv[])
{
	qDebug() << "App start";
	QCoreApplication app(argc, argv);

#if defined(Q_OS_WIN32)
	Atomix::CrashHandler::instance()->Init("c:\\dump");
#elif defined(Q_OS_LINUX)
	Atomix::CrashHandler::instance()->Init("/Users/dev/dump");
#elif defined(Q_OS_MAC)
	Atomix::CrashHandler::instance()->Init("/Users/User/dump");
#endif
	
	qDebug() << "CrashHandlerSet";
	buggyFunc();
	return 0;
}

Very slow svn updates from Virtual Machines (VMWare)

I have a lot of virtual machines used for my everyday development. It’s very frustrating the SVN update speed if you have several externals in your main SVN source.

Today when I wait for some compilation start searching if there is anything what could improve SVN speed. After searching a lot of articles about faster network, better server hdd,… I found article with mention how SVN client communicate with server (intensively 😉 ). But without any clue how to improve it.

So I start searching how SVN client communiacte from within VMWare machines to server. I noticed that VMWare default network settings is NAT: Used to share the host’s IP address:

So I start trying other network methods and this is the result:

When I use “Custom: Specific virtual network” and choose “VMnet0 Bridged”, my svn update is about ten times faster than on NAT settings!!. I also tried first option “Bridged:…” but this doesn’t work for me.