-
-
Notifications
You must be signed in to change notification settings - Fork 17
Crashpad
Installing depot_tools (ref)
MacOS
git clone https://chromium.googlesource.com/chromium/tools/depot_tools.git
sudo echo "export PATH=/path/to/depot_tools:$PATH" >> ~/.zshrc
Getting the Crashpad source (ref)
mkdir ~/crashpad
cd ~/crashpad
fetch crashpad
cd ~/crashpad/crashpad
git pull -r
gclient sync
cd ~/crashpad/crashpad
gn gen out/Default
ninja -C out/Default
Building Shared Libraries (ref)
Windows
After running gn gen out\Default
, you can edit the out\Default\toolchain.ninja
file to add extra compiler flags to the command for the cc and cxx rules.
rule cc
command = ninja -t msvc -e environment.amd64 -- cl.exe ... ${cflags} ${cflags_c} /c ...
add the /MD compiler flag after the others, here ^
Linking (ref)
MacOS
Building Crashpad outputs several .a files which need to be added to your project along with the corresponding include directories. In addition to the .a files Crashpad generates a collection of .o files that need to be included. You will also need to link with libbsm
, Security.Framework
and AppKit.Framework
. Finally, you'll need to add config parameters force_debug_info
and separate_debug_info
. The following is a snippet from the myQtCrasher.pro file:
# Create a dSYM file for dump_syms
CONFIG += force_debug_info
CONFIG += separate_debug_info
# Include directories for Crashpad libraries
INCLUDEPATH += $$PWD/Crashpad/Include/crashpad
INCLUDEPATH += $$PWD/Crashpad/Include/crashpad/third_party/mini_chromium/mini_chromium
# Crashpad rules for MacOS
macx {
# Crashpad libraries
LIBS += -L$$PWD/Crashpad/Libraries/MacOS/ -lbase
LIBS += -L$$PWD/Crashpad/Libraries/MacOS/ -lutil
LIBS += -L$$PWD/Crashpad/Libraries/MacOS/ -lclient
LIBS += "$$PWD/Crashpad/Libraries/MacOS/util/mach/*.o"
# System libraries
LIBS += -L/usr/lib/ -lbsm
LIBS += -framework AppKit
LIBS += -framework Security
# Copy crashpad_handler to build directory
crashpad.commands = mkdir -p $$OUT_PWD/crashpad && cp $$PWD/Crashpad/Bin/MacOS/crashpad_handler $$OUT_PWD/crashpad
first.depends = $(first) crashpad
export(first.depends)
export(copydata.commands)
QMAKE_EXTRA_TARGETS += first crashpad
}
Configuring Crashpad (ref)
Building Crashpad outputs the crashpad_handler executable. Copy this file into your project and note its path. Ensure that this file is distributed with your application.
Add the following snippet to the entry point of your application:
bool initializeCrashpad(char *dbName, char *appName, char *appVersion )
{
// Ensure that handler is shipped with your application
base::FilePath handler("../../../crashpad/crashpad_handler");
// Directory where reports will be saved. Important! Must be writable or crashpad_handler will crash.
base::FilePath reportsDir("../../../crashpad");
// Directory where metrics will be saved. Important! Must be writable or crashpad_handler will crash.
base::FilePath metricsDir("../../../crashpad");
// Configure url with your BugSplat database
std::string url;
url = "https://";
url += dbName;
url += ".bugsplat.com/post/bp/crash/crashpad.php";
// Metadata that will be posted to BugSplat
std::map<std::string, std::string> annotations;
annotations["format"] = "minidump"; // Required: Crashpad setting to save crash as a minidump
annotations["product"].assign(appName); // Required: BugSplat appName
annotations["version"].assign(appVersion); // Required: BugSplat appVersion
annotations["key"] = "Sample key"; // Optional: BugSplat key field
annotations["user"] = "[email protected]"; // Optional: BugSplat user email
annotations["list_annotations"] = "Sample comment"; // Optional: BugSplat crash description
// Disable crashpad rate limiting so that all crashes have dmp files
std::vector<std::string> arguments;
arguments.push_back("--no-rate-limit");
// Initialize crashpad database
std::unique_ptr<CrashReportDatabase> database = crashpad::CrashReportDatabase::Initialize(reportsDir);
if (database == NULL) return false;
// Enable automated crash uploads
Settings *settings = database->GetSettings();
if (settings == NULL) return false;
settings->SetUploadsEnabled(true);
// Start crash handler
CrashpadClient *client = new CrashpadClient();
bool status = client->StartHandler(handler, reportsDir, metricsDir, url, annotations, arguments, true, true);
return status;
}
Call initializeCrashpad at the entry point of your application passing it the name of your BugSplat database, the name of your application and the current version.
char *dbName = (char *)"Fred";
char *appName = (char *)"myQtCrasher";
char *appVersion = (char *)"1.0";
initializeCrashpad(dbName, appName, appVersion);
Add code that will crash your application and ensure it will run after Crashpad has been initialized.
void crash() {
*(volatile int *)0 = 0;
}
Ensure your project builds before moving on to the next step.
The Crashpad repository is missing a few tools that are available in the Breakpad repository. In order to generate sym files from your compiled executable you'll need to clone the Breakpad repository and build the dump_syms utility.
Getting the Breakpad source (ref)
mkdir ~/breakpad
cd ~/breakpad
fetch breakpad
MacOS
Open breakpad/src/src/tools/mac/dump_syms/dump_syms.xcodeproj
. Switch the configuration to dump_syms and build the project. The report navigator tab (icon looks like a chat bubble in Xcode 11) will show you the file system location with the compiled executable. Copy the dump_syms executable into your project.
Running dump_syms (ref)
./dump_syms -g path/to/myApp.dSYM path/to/myApp > myApp.sym
MacOS
Open breakpad/src/src/tools/mac/sym_upload/symupload.xcodeproj
and build the project. The report navigator tab (icon looks like a chat bubble in Xcode 11) will show you the file system location with the compiled executable. Copy the sym_upload executable into your project.
If your application generates large sym file sizes, or your network bandwidth is limited you may run into upload timeouts. If this happens, increase the value of
timeoutInterval
inbreakpad/src/src/common/mac/HTTPMultipartUpload.m
and rebuild the symupload project.
Running symupload (ref)
./symupload "path/to/myApp.sym" "https://{database}.bugsplat.com/post/bp/symbol/breakpadsymbols.php?appName={appName}&appVer={appVersion}"
- Be sure to replace {database} with your BugSplat database
- Be sure that {appName} and {appVersion} are the same values used to initialize the Crashpad handler
Run your application to generate a crash report. The crash report should show up on BugSplat's Crashes page. Click the number in the ID column to see more information about the crash report. If everything is set up correctly you should see something like this:
The Debugger Output tab on the Crash page will show you the output from minidump_stackwalk. If file names and line numbers are not being displayed in the stack trace, the most common cause is mismatched sym files. Look for the following line in the Debugger Output tab to determine the identifier of the module that was loaded at crash time.
2020-04-23 09:42:03: simple_symbol_supplier.cc:196: INFO: No symbol file at /www/src/RemoteStackAnalyzer/build/symbols/breakpad/Fred/myQtCrasher-1.0/myQtCrasher/63DE7DDC72203043B92951A0582ADE1B0/myQtCrasher.sym
Verify that the correct sym file has been uploaded to BugSplat on the Symbols page. The application name and version of the symbol store must match the application name and version configured in initializeCrashpad.
Click symbol store link to be taken to the Symbol Details page. Click the link in the download column and open the sym file in a text editor. If the identifier at top of the sym file does not match the identifier from the Debugger Output it is not the correct sym file.
MODULE mac x86_64 63DE7DDC72203043B92951A0582ADE1B0 myQtCrasher
Finally, if you are using copy protection or anti-cheat software, ensure that dump_syms has been run after your executable has been modified by your copy protection or anti-cheat solution.