Crashpad and Visual Studio

Crashpad is an open-source library initially developed by Google as a successor to the Google Breakpad library.

Obtain Crashpad

You can build Crashpad from source or download Backtrace-provided versions of the library.

Build from source

It is always possible to build Crashpad from source. In order to do this, please see the build guide on the Crashpad website.

Download built libraries

Backtrace provides updated builds of Crashpad. It is recommended to use the latest version to take advantage of the latest improvements in Crashpad. These archives contain the complete source archive of the snapshot to make it easier to manage in-place updates.

See below for all releases and SHA256 checksums. These are built for the latest version of Windows 10. All releases are builds from Crashpad master. Click on the .zip file to download Crashpad.

Date File SHA256
06/23/17 crashpad_062317.zip 0a7e4ac0c26fc204d31ac9eba8a6957a9bde8cd8369e0c2b2349d4c998044742
04/28/17 crashpad_042817.zip 945f3e6146d18682b17097ad51385f16eb239b3569c371e13587fff6bdad7895

Integrate Crashpad

Once you have built Crashpad or download the pre-built libraries, you will now need to integrate the library into your application. The library is statically linked into your project, so you will not need to distribute any additional projects.

There are two versions of Crashpad provided in the Backtrace archive.

Build Description Path
Release Release mode 32-bit build. out\Release
Release_x64 Release mode 64-bit build. out\Release_x64
Debug Debug mode 32-bit build. out\Debug
Debug_x64 Debug mode 64-bit build. out\Debug_x64

If in release build, for 32-bit applications, use Release. If in release build, for 64-bit applications, use Release_x64. If in debug build, for 32-bit applications, use Debug. If in debug build, for 64-bit applications, use Debug_x64.

Integrate into your build process

This section outlines how to import the Crashpad library into your Visual Studio project.

Add the header files

First, you'll need to add the Crashpad directory in the include path for your application. The header files for Crashpad in the provided .zip file are in the include directory.

Go to the project configuration menu (Project > Properties > VC++ Directories) and set Include Directories to point to the include folder of the extracted archive.

Add the libraries

Static Linking

Now, you'll need to add the relevant release path (see the table above) to your Library Directories (Project > Properties > VC++ Directories). For example, if I am deploying a 32-bit Windows application, then the Release\lib sub-directory is added to Library Directories.

Once that is done, you'll need to add the actual set of static libraries for Crashpad. Navigate to your linker input settings (Project > Properties > Linker > Input), and add crashpad_util.lib;base.lib;crashpad_client.lib as an additional dependency. See the screenshot below for an example.

Remember to use the build of the Crashpad library that corresponds with your build configuration. For example, if you are building a 32-bit Debug build, then ensure that you are referencing the .lib files from out\Debug. If you encounter errors involving ITERATOR_DEBUG_LEVEL, then there is likely a mismatch between your build configuration and the build of Crashpad. In order to change the build settings, go to Build > Configuration Manager then change your Active solution configuration.

Dynamic Linking

If you are using dynamic linking (the \MD flag), then make sure to use the lib_MD sub-directory rather than lib. For example, out\Release_x64\lib_MD rather than out\Release\lib.

Verify Linker Settings

Static Linking

Last but not least, ensure that you have code generation runtime settings set to a mode compatible with static libraries, such as Multi-threaded (/MT). Go to Project > Properties > C/C++ > Code Generation and update the the Runtime Library setting.

Dynamic Linking

If you are using dynamic linking, then ensure that you use the /MD option instead of /MT.

Ensure symbol generation

It is required to upload symbols into Backtrace for intelligent deduplication and classification. This section explains how to enable debug symbols for your application.

Go to Project > Properties > Linker and update the the Generate Debug Info setting. You'll want to set it to either Generate Debug Information (/DEBUG) or Generate Debug Information optimized for sharing and publishing (/DEBUG:FULL). The /DEBUG option is recommended if you would like to avoid the possibility of a performance impact.

With this setting, a .pdb file will be generated for your application in the build output directory. You are able to upload .sym, .pdb and archive files containing .pdb or .sym files into Backtrace manually or through the command line. It is also possible to hook up Visual Studio to automatically upload symbols as they are generated. You should be good to send crash reports at this point. Simply ensure that you've uploaded your symbols (click on Symbols tab under the Project Configuration page).

For more details, please refer to the symbolification guide.

Send crash reports

Congratulations, now you're ready to integrate Crashpad into your application. In order to do this, you'll need to add the following to your source-code.

#include "client/crashpad_client.h"

using namespace crashpad;

Once that's done, it's time to initialize the Crashpad library. For this, you will use the crashpad::CrashpadClient::StartHandler function as defined below.

bool crashpad::CrashpadClient::StartHandler(const base::FilePath &handler,
    const base::FilePath &database,
    const base::FilePath &metrics_dir,
    const std::string &url,
    const std::map<std::string, std::string> &annotations,
    const std::vector<std::string> &arguments,
    bool restartable,
    bool asynchronous_start 
)

If handler is specified, it is a path to an external program responsible for generating and uploading dumps. This is the recommended for uploading crashes as it's reliable. Look for bin/crashpad_handler.exe, which is suitable as a default crash handler. See below for a complete example.

[...]

#include "client/crashpad_client.h"
#include "client/crash_report_database.h"
#include "client/settings.h"

using namespace crashpad;

[...]

static bool
startCrashHandler()
{
    CrashpadClient client;
    bool rc;

    std::map<std::string, std::string> annotations;
    std::vector<std::string> arguments;

    /*
     * ENSURE THIS VALUE IS CORRECT.
     *
     * This is the directory you will use to store and queue crash data.
     */
    std::wstring db_path(L"my_app_dir\\Crashpad\\db");

    /*
     * ENSURE THIS VALUE IS CORRECT.
     *
     * Crashpad has the ability to support crashes both in-process and out-of-process.
     * The out-of-process handler is significantly more robust than traditional in-process
     * crash handlers. This path may be relative.
     */
    std::wstring handler_path(L"C:\crashpad_042817\\out\\Release\\bin\\crashpad_handler.exe");

    /*
     * YOU MUST CHANGE THIS VALUE.
     *
     * This should point to your server dump submission port (labeled as "http/writer"
     * in the listener configuration pane. Preferrably, the SSL enabled port should
     * be used. If Backtrace is hosting your instance, the default port is 6098.
     */
    std::string url("https://yourteam.sp.backtrace.io:6098");

    /*
     * YOU MUST CHANGE THIS VALUE.
     *
     * Set this to the submission token under the project page.
     * Learn more at https://documentation.backtrace.io/coronerd_setup/#tokens
     */
    annotations["token"] = "b6dd361e5800babc23beb88c5797147c1a06dbe11bf096ed935b59ac42766ec3";

    /*
     * THE FOLLOWING ANNOTATIONS MUST BE SET.
     *
     * Backtrace supports many file formats. Set format to minidump so it knows
     * how to process the incoming dump.
     */
    annotations["format"] = "minidump";

    /*
     * REMOVE THIS FOR ACTUAL BUILD.
     *
     * We disable crashpad rate limiting for this example.
     */
    arguments.push_back("--no-rate-limit");

    base::FilePath db(db_path);
    base::FilePath handler(handler_path);

    std::unique_ptr<CrashReportDatabase> database =
        crashpad::CrashReportDatabase::Initialize(db);
    if (database == nullptr || database->GetSettings() == NULL)
        return false;

    /* Enable automated uploads. */
    database->GetSettings()->SetUploadsEnabled(true);

    rc = client.StartHandler(handler,
        db,
        db,
        url,
        annotations,
        arguments,
        true,
        true);
    if (rc == false)
        return false;

    /* Optional, wait for Crashpad to initialize. */
    rc = client.WaitForHandlerStart(INFINITE);
    if (rc == false)
        return false;

    return true;
}

Enable automated crash upload

If you haven't done so with the Crashpad API, enable automated upload of crashes with crashpad_database_util. On Windows, for example:

C:\Project>crashpad_database_util.exe -d C:\my_crash_repo --set-uploads-enabled=TRUE

Finish

At this point, crashes should be automatically submitted into Backtrace. As crashes generate, refresh the Project page of the associated project to see faults in real-time.

Additional Documentation

Additional documentation is available at the Crashpad Website. For more information on the crashpad_handler, please see crashpad_handler.md.

If you're still encountering issues, contact us at support@backtrace.io.