Developer Blog - Inventic.eu
  • Skipper - The ORM Designer
  • VsBuilds - Parallel building
  • Pulpo - Free Skipper CLI

Tag: #debug

Debugging QML application

Batches, clip, changes and overdraw

 

SET QSG_VISUALIZE=batches<br />
or<br />
SET QSG_VISUALIZE=clip<br />
or<br />
SET QSG_VISUALIZE=changes<br />
or<br />
SET QSG_VISUALIZE=overdraw</p>
<p>qmlviewer test.qml<br />

Links:

02 Jan 2016

Posted by: ludek.vodicka

Qt #Qt #debug #qml

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<br />
svn checkout http://google-breakpad.googlecode.com/svn/trunk/ google-breakpad-read-only</p>
<p>#compile all breakpad tools for extracting symbol files<br />
./configure<br />
make<br />
sudo make install</p>
<p>#when compilation is ready, you should have installed file dump_syms from original directory /src/tools/linux/dump_syms in your /usr/bin<br />
dump_syms<br />

Generate symbol file and test debug info

Now how to generate and use symbol file:

#generate .sym file<br />
dump_syms ./Application &gt; Application.sym</p>
<p>#store sym file in the correct location<br />
#this step is necessary. Without that minidump_stackwalk tool doesn't work</p>
<p>head -n1 Application.sym<br />
#Result: MODULE Linux x86_64 6EDC6ACDB282125843FD59DA9C81BD830 Application</p>
<p>mkdir -p ./symbols/Application/6EDC6ACDB282125843FD59DA9C81BD830<br />
mv Application.sym ./symbols/Application/6EDC6ACDB282125843FD59DA9C81BD830</p>
<p>#show stack with using minidump_stackwalk tool<br />
minidump_stackwalk ./crash.dmp ./symbols<br />

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<br />

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 &gt;AtomixDevelopment.sym<br />

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<br />

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 -----------------------------------------------------------<br />
OTHERS   += $$PWD/axCrashHandler.pri<br />
HEADERS += $$PWD/CrashHandler.h<br />
SOURCES += $$PWD/CrashHandler.cpp</p>
<p>BREAKPAD_PATH=$$EXTERNAL_LIBRARIES_PATH/breakpad-qt<br />
INCLUDEPATH += $$BREAKPAD_PATH/src</p>
<p>OSMAC {<br />
  HEADERS += $$BREAKPAD_PATH/src/client/mac/handler/exception_handler.h<br />
  HEADERS += $$BREAKPAD_PATH/src/client/mac/crash_generation/crash_generation_client.h<br />
  HEADERS += $$BREAKPAD_PATH/src/client/mac/crash_generation/crash_generation_server.h<br />
  HEADERS += $$BREAKPAD_PATH/src/client/mac/crash_generation/client_info.h<br />
  HEADERS += $$BREAKPAD_PATH/src/client/mac/handler/minidump_generator.h<br />
  HEADERS += $$BREAKPAD_PATH/src/client/mac/handler/dynamic_images.h<br />
  HEADERS += $$BREAKPAD_PATH/src/client/mac/handler/breakpad_nlist_64.h<br />
  HEADERS += $$BREAKPAD_PATH/src/client/mac/handler/mach_vm_compat.h<br />
  HEADERS += $$BREAKPAD_PATH/src/client/minidump_file_writer.h<br />
  HEADERS += $$BREAKPAD_PATH/src/client/minidump_file_writer-inl.h<br />
  HEADERS += $$BREAKPAD_PATH/src/common/mac/macho_utilities.h<br />
  HEADERS += $$BREAKPAD_PATH/src/common/mac/byteswap.h<br />
  HEADERS += $$BREAKPAD_PATH/src/common/mac/MachIPC.h<br />
  HEADERS += $$BREAKPAD_PATH/src/common/mac/scoped_task_suspend-inl.h<br />
  HEADERS += $$BREAKPAD_PATH/src/common/mac/file_id.h<br />
  HEADERS += $$BREAKPAD_PATH/src/common/mac/macho_id.h<br />
  HEADERS += $$BREAKPAD_PATH/src/common/mac/macho_walker.h<br />
  HEADERS += $$BREAKPAD_PATH/src/common/mac/macho_utilities.h<br />
  HEADERS += $$BREAKPAD_PATH/src/common/mac/bootstrap_compat.h<br />
  HEADERS += $$BREAKPAD_PATH/src/common/mac/string_utilities.h<br />
  HEADERS += $$BREAKPAD_PATH/src/common/linux/linux_libc_support.h<br />
  HEADERS += $$BREAKPAD_PATH/src/common/string_conversion.h<br />
  HEADERS += $$BREAKPAD_PATH/src/common/md5.h<br />
  HEADERS += $$BREAKPAD_PATH/src/common/memory.h<br />
  HEADERS += $$BREAKPAD_PATH/src/common/using_std_string.h<br />
  HEADERS += $$BREAKPAD_PATH/src/common/convert_UTF.h<br />
  HEADERS += $$BREAKPAD_PATH/src/processor/scoped_ptr.h<br />
  HEADERS += $$BREAKPAD_PATH/src/google_breakpad/common/minidump_exception_mac.h<br />
  HEADERS += $$BREAKPAD_PATH/src/google_breakpad/common/breakpad_types.h<br />
  HEADERS += $$BREAKPAD_PATH/src/google_breakpad/common/minidump_format.h<br />
  HEADERS += $$BREAKPAD_PATH/src/google_breakpad/common/minidump_size.h<br />
  HEADERS += $$BREAKPAD_PATH/src/third_party/lss/linux_syscall_support.h</p>
<p>  SOURCES += $$BREAKPAD_PATH/src/client/mac/handler/exception_handler.cc<br />
  SOURCES += $$BREAKPAD_PATH/src/client/mac/crash_generation/crash_generation_client.cc<br />
  SOURCES += $$BREAKPAD_PATH/src/client/mac/crash_generation/crash_generation_server.cc<br />
  SOURCES += $$BREAKPAD_PATH/src/client/mac/handler/minidump_generator.cc<br />
  SOURCES += $$BREAKPAD_PATH/src/client/mac/handler/dynamic_images.cc<br />
  SOURCES += $$BREAKPAD_PATH/src/client/mac/handler/breakpad_nlist_64.cc<br />
  SOURCES += $$BREAKPAD_PATH/src/client/minidump_file_writer.cc<br />
  SOURCES += $$BREAKPAD_PATH/src/common/mac/macho_id.cc<br />
  SOURCES += $$BREAKPAD_PATH/src/common/mac/macho_walker.cc<br />
  SOURCES += $$BREAKPAD_PATH/src/common/mac/macho_utilities.cc<br />
  SOURCES += $$BREAKPAD_PATH/src/common/mac/string_utilities.cc<br />
  SOURCES += $$BREAKPAD_PATH/src/common/mac/file_id.cc<br />
  SOURCES += $$BREAKPAD_PATH/src/common/mac/MachIPC.mm<br />
  SOURCES += $$BREAKPAD_PATH/src/common/mac/bootstrap_compat.cc<br />
  SOURCES += $$BREAKPAD_PATH/src/common/md5.cc<br />
  SOURCES += $$BREAKPAD_PATH/src/common/string_conversion.cc<br />
  SOURCES += $$BREAKPAD_PATH/src/common/linux/linux_libc_support.cc<br />
  SOURCES += $$BREAKPAD_PATH/src/common/convert_UTF.c<br />
  LIBS += /System/Library/Frameworks/CoreFoundation.framework/Versions/A/CoreFoundation<br />
  LIBS += /System/Library/Frameworks/CoreServices.framework/Versions/A/CoreServices<br />
  #breakpad app need debug info inside binaries<br />
  QMAKE_CXXFLAGS+=-g<br />
}</p>
<p>OSLIN {<br />
  HEADERS += $$BREAKPAD_PATH/src/client/linux/handler/exception_handler.h<br />
  HEADERS += $$BREAKPAD_PATH/src/client/linux/crash_generation/crash_generation_client.h<br />
  HEADERS += $$BREAKPAD_PATH/src/client/linux/handler/minidump_descriptor.h<br />
  HEADERS += $$BREAKPAD_PATH/src/client/linux/minidump_writer/minidump_writer.h<br />
  HEADERS += $$BREAKPAD_PATH/src/client/linux/minidump_writer/line_reader.h<br />
  HEADERS += $$BREAKPAD_PATH/src/client/linux/minidump_writer/linux_dumper.h<br />
  HEADERS += $$BREAKPAD_PATH/src/client/linux/minidump_writer/linux_ptrace_dumper.h<br />
  HEADERS += $$BREAKPAD_PATH/src/client/linux/minidump_writer/directory_reader.h<br />
  HEADERS += $$BREAKPAD_PATH/src/client/linux/log/log.h<br />
  HEADERS += $$BREAKPAD_PATH/src/client/minidump_file_writer-inl.h<br />
  HEADERS += $$BREAKPAD_PATH/src/client/minidump_file_writer.h<br />
  HEADERS += $$BREAKPAD_PATH/src/common/linux/linux_libc_support.h<br />
  HEADERS += $$BREAKPAD_PATH/src/common/linux/eintr_wrapper.h<br />
  HEADERS += $$BREAKPAD_PATH/src/common/linux/ignore_ret.h<br />
  HEADERS += $$BREAKPAD_PATH/src/common/linux/file_id.h<br />
  HEADERS += $$BREAKPAD_PATH/src/common/linux/memory_mapped_file.h<br />
  HEADERS += $$BREAKPAD_PATH/src/common/linux/safe_readlink.h<br />
  HEADERS += $$BREAKPAD_PATH/src/common/linux/guid_creator.h<br />
  HEADERS += $$BREAKPAD_PATH/src/common/linux/elfutils.h<br />
  HEADERS += $$BREAKPAD_PATH/src/common/linux/elfutils-inl.h<br />
  HEADERS += $$BREAKPAD_PATH/src/common/using_std_string.h<br />
  HEADERS += $$BREAKPAD_PATH/src/common/memory.h<br />
  HEADERS += $$BREAKPAD_PATH/src/common/basictypes.h<br />
  HEADERS += $$BREAKPAD_PATH/src/common/memory_range.h<br />
  HEADERS += $$BREAKPAD_PATH/src/common/string_conversion.h<br />
  HEADERS += $$BREAKPAD_PATH/src/common/convert_UTF.h<br />
  HEADERS += $$BREAKPAD_PATH/src/google_breakpad/common/minidump_format.h<br />
  HEADERS += $$BREAKPAD_PATH/src/google_breakpad/common/minidump_size.h<br />
  HEADERS += $$BREAKPAD_PATH/src/google_breakpad/common/breakpad_types.h<br />
  HEADERS += $$BREAKPAD_PATH/src/processor/scoped_ptr.h<br />
  HEADERS += $$BREAKPAD_PATH/src/third_party/lss/linux_syscall_support.h<br />
  SOURCES += $$BREAKPAD_PATH/src/client/linux/crash_generation/crash_generation_client.cc<br />
  SOURCES += $$BREAKPAD_PATH/src/client/linux/handler/exception_handler.cc<br />
  SOURCES += $$BREAKPAD_PATH/src/client/linux/handler/minidump_descriptor.cc<br />
  SOURCES += $$BREAKPAD_PATH/src/client/linux/minidump_writer/minidump_writer.cc<br />
  SOURCES += $$BREAKPAD_PATH/src/client/linux/minidump_writer/linux_dumper.cc<br />
  SOURCES += $$BREAKPAD_PATH/src/client/linux/minidump_writer/linux_ptrace_dumper.cc<br />
  SOURCES += $$BREAKPAD_PATH/src/client/linux/log/log.cc<br />
  SOURCES += $$BREAKPAD_PATH/src/client/minidump_file_writer.cc<br />
  SOURCES += $$BREAKPAD_PATH/src/common/linux/linux_libc_support.cc<br />
  SOURCES += $$BREAKPAD_PATH/src/common/linux/file_id.cc<br />
  SOURCES += $$BREAKPAD_PATH/src/common/linux/memory_mapped_file.cc<br />
  SOURCES += $$BREAKPAD_PATH/src/common/linux/safe_readlink.cc<br />
  SOURCES += $$BREAKPAD_PATH/src/common/linux/guid_creator.cc<br />
  SOURCES += $$BREAKPAD_PATH/src/common/linux/elfutils.cc<br />
  SOURCES += $$BREAKPAD_PATH/src/common/string_conversion.cc<br />
  SOURCES += $$BREAKPAD_PATH/src/common/convert_UTF.c<br />
  #breakpad app need debug info inside binaries<br />
  QMAKE_CXXFLAGS+=-g<br />
}</p>
<p>OSWIN {<br />
  BREAKPAD_PATH=q:/Applications/breakpad-qt/third-party/latest-breakpad<br />
  INCLUDEPATH += $$BREAKPAD_PATH/src<br />
  HEADERS += $$BREAKPAD_PATH/src/common/windows/string_utils-inl.h<br />
  HEADERS += $$BREAKPAD_PATH/src/common/windows/guid_string.h<br />
  HEADERS += $$BREAKPAD_PATH/src/client/windows/handler/exception_handler.h<br />
  HEADERS += $$BREAKPAD_PATH/src/client/windows/common/ipc_protocol.h<br />
  HEADERS += $$BREAKPAD_PATH/src/google_breakpad/common/minidump_format.h<br />
  HEADERS += $$BREAKPAD_PATH/src/google_breakpad/common/breakpad_types.h<br />
  HEADERS += $$BREAKPAD_PATH/src/client/windows/crash_generation/crash_generation_client.h<br />
  HEADERS += $$BREAKPAD_PATH/src/processor/scoped_ptr.h </p>
<p>  SOURCES += $$BREAKPAD_PATH/src/client/windows/handler/exception_handler.cc<br />
  SOURCES += $$BREAKPAD_PATH/src/common/windows/string_utils.cc<br />
  SOURCES += $$BREAKPAD_PATH/src/common/windows/guid_string.cc<br />
  SOURCES += $$BREAKPAD_PATH/src/client/windows/crash_generation/crash_generation_client.cc<br />
}<br />

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<br />
#include &lt;QtCore/QString&gt;</p>
<p>namespace Atomix<br />
{<br />
	class CrashHandlerPrivate;<br />
	class CrashHandler<br />
	{<br />
	public:<br />
		static CrashHandler* instance();<br />
    void Init(const QString&amp;  reportPath);</p>
<p>		void setReportCrashesToSystem(bool report);<br />
		bool writeMinidump();</p>
<p>	private:<br />
		CrashHandler();<br />
		~CrashHandler();<br />
		Q_DISABLE_COPY(CrashHandler)<br />
		CrashHandlerPrivate* d;<br />
	};<br />
}<br />

CrashHandler.cpp

#include &quot;CrashHandler.h&quot;<br />
#include &lt;QtCore/QDir&gt;<br />
#include &lt;QtCore/QProcess&gt;<br />
#include &lt;QtCore/QCoreApplication&gt;<br />
#include &lt;QString&gt;</p>
<p>#if defined(Q_OS_MAC)<br />
#include &quot;client/mac/handler/exception_handler.h&quot;<br />
#elif defined(Q_OS_LINUX)<br />
#include &quot;client/linux/handler/exception_handler.h&quot;<br />
#elif defined(Q_OS_WIN32)<br />
#include &quot;client/windows/handler/exception_handler.h&quot;<br />
#endif</p>
<p>namespace Atomix<br />
{<br />
	/************************************************************************/<br />
	/* CrashHandlerPrivate                                                  */<br />
	/************************************************************************/<br />
	class CrashHandlerPrivate<br />
	{<br />
	public:<br />
		CrashHandlerPrivate()<br />
		{<br />
			pHandler = NULL;<br />
		}</p>
<p>		~CrashHandlerPrivate()<br />
		{<br />
			delete pHandler;<br />
		}</p>
<p>		void InitCrashHandler(const QString&amp; dumpPath);<br />
		static google_breakpad::ExceptionHandler* pHandler;<br />
		static bool bReportCrashesToSystem;<br />
	};</p>
<p>	google_breakpad::ExceptionHandler* CrashHandlerPrivate::pHandler = NULL;<br />
	bool CrashHandlerPrivate::bReportCrashesToSystem = false;</p>
<p>	/************************************************************************/<br />
	/* DumpCallback                                                         */<br />
	/************************************************************************/<br />
#if defined(Q_OS_WIN32)<br />
	bool DumpCallback(const wchar_t* _dump_dir,const wchar_t* _minidump_id,void* context,EXCEPTION_POINTERS* exinfo,MDRawAssertionInfo* assertion,bool success)<br />
#elif defined(Q_OS_LINUX)<br />
	bool DumpCallback(const google_breakpad::MinidumpDescriptor &amp;md,void *context, bool success)<br />
#elif defined(Q_OS_MAC)<br />
	bool DumpCallback(const char* _dump_dir,const char* _minidump_id,void *context, bool success)<br />
#endif<br />
	{<br />
		Q_UNUSED(context);<br />
#if defined(Q_OS_WIN32)<br />
		Q_UNUSED(_dump_dir);<br />
		Q_UNUSED(_minidump_id);<br />
		Q_UNUSED(assertion);<br />
		Q_UNUSED(exinfo);<br />
#endif<br />
		qDebug(&quot;BreakpadQt crash&quot;);</p>
<p>		/*<br />
		NO STACK USE, NO HEAP USE THERE !!!<br />
		Creating QString's, using qDebug, etc. - everything is crash-unfriendly.<br />
		*/<br />
		return CrashHandlerPrivate::bReportCrashesToSystem ? success : true;<br />
	}</p>
<p>	void CrashHandlerPrivate::InitCrashHandler(const QString&amp; dumpPath)<br />
	{<br />
		if ( pHandler != NULL )<br />
			return;</p>
<p>#if defined(Q_OS_WIN32)<br />
		std::wstring pathAsStr = (const wchar_t*)dumpPath.utf16();<br />
		pHandler = new google_breakpad::ExceptionHandler(<br />
			pathAsStr,<br />
			/*FilterCallback*/ 0,<br />
			DumpCallback,<br />
			/*context*/<br />
			0,<br />
			true<br />
			);<br />
#elif defined(Q_OS_LINUX)<br />
		std::string pathAsStr = dumpPath.toStdString();<br />
		google_breakpad::MinidumpDescriptor md(pathAsStr);<br />
		pHandler = new google_breakpad::ExceptionHandler(<br />
			md,<br />
			/*FilterCallback*/ 0,<br />
			DumpCallback,<br />
			/*context*/ 0,<br />
			true,<br />
			-1<br />
			);<br />
#elif defined(Q_OS_MAC)<br />
		std::string pathAsStr = dumpPath.toStdString();<br />
		pHandler = new google_breakpad::ExceptionHandler(<br />
			pathAsStr,<br />
			/*FilterCallback*/ 0,<br />
			DumpCallback,<br />
			/*context*/<br />
			0,<br />
			true,<br />
			NULL<br />
			);<br />
#endif<br />
	}</p>
<p>	/************************************************************************/<br />
	/* CrashHandler                                                         */<br />
	/************************************************************************/<br />
	CrashHandler* CrashHandler::instance()<br />
	{<br />
		static CrashHandler globalHandler;<br />
		return &amp;globalHandler;<br />
	}</p>
<p>	CrashHandler::CrashHandler()<br />
	{<br />
		d = new CrashHandlerPrivate();<br />
	}</p>
<p>	CrashHandler::~CrashHandler()<br />
	{<br />
		delete d;<br />
	}</p>
<p>	void CrashHandler::setReportCrashesToSystem(bool report)<br />
	{<br />
		d-&gt;bReportCrashesToSystem = report;<br />
	}</p>
<p>	bool CrashHandler::writeMinidump()<br />
	{<br />
		bool res = d-&gt;pHandler-&gt;WriteMinidump();<br />
		if (res) {<br />
			qDebug(&quot;BreakpadQt: writeMinidump() successed.&quot;);<br />
		} else {<br />
			qWarning(&quot;BreakpadQt: writeMinidump() failed.&quot;);<br />
		}<br />
		return res;<br />
	}</p>
<p>	void CrashHandler::Init( const QString&amp; reportPath )<br />
	{<br />
		d-&gt;InitCrashHandler(reportPath);<br />
	}<br />
}<br />

Main.cpp

And here is how to use it:

#include &quot;axCore/axCrashHandler/CrashHandler.h&quot;<br />
#include &lt;QDebug&gt;<br />
#include &lt;QCoreApplication&gt;<br />
#include &lt;iostream&gt;</p>
<p>int buggyFunc()<br />
{<br />
	delete reinterpret_cast&lt;QString*&gt;(0xFEE1DEAD);<br />
	return 0;<br />
}</p>
<p>int main(int argc, char * argv[])<br />
{<br />
	qDebug() &lt;&lt; &quot;App start&quot;;<br />
	QCoreApplication app(argc, argv);</p>
<p>#if defined(Q_OS_WIN32)<br />
	Atomix::CrashHandler::instance()-&gt;Init(&quot;c:\\dump&quot;);<br />
#elif defined(Q_OS_LINUX)<br />
	Atomix::CrashHandler::instance()-&gt;Init(&quot;/Users/dev/dump&quot;);<br />
#elif defined(Q_OS_MAC)<br />
	Atomix::CrashHandler::instance()-&gt;Init(&quot;/Users/User/dump&quot;);<br />
#endif</p>
<p>	qDebug() &lt;&lt; &quot;CrashHandlerSet&quot;;<br />
	buggyFunc();<br />
	return 0;<br />
}<br />