blob: 70584d015ed756fdaa3d52777c41a565df4d651a [file] [log] [blame]
// Copyright 2015 The Android Open Source Project
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#pragma once
#include "android/base/StringView.h"
#include "google_breakpad/processor/process_state.h"
#include "google_breakpad/processor/basic_source_line_resolver.h"
#include <memory>
#include <set>
#include <string>
namespace android {
namespace crashreport {
// The Suggestion type represents possible suggestions
// presented to the user upon
// analyzing a crash report.
enum class Suggestion {
// TODO: Add more suggestion types
// (Update OS, Get more RAM, etc)
// as we find them
UpdateGfxDrivers
};
// Class UserSuggestions parses and generates user suggestions.
class UserSuggestions {
public:
std::set<Suggestion> suggestions;
UserSuggestions(google_breakpad::ProcessState* process_state);
};
// Class CrashService wraps Breakpad platform specific crash generation server
//
// Usage:
// Instantiate with a version and build number to be used as default report
// version
//
// For manual processing:
// setDumpFile
// Otherwise:
// startCrashServer
// waitForDumpFile
// stopCrashServer
//
// Process the crash for details:
// processCrash
//
// Finally, to upload the crash:
// uploadCrash
//
// After uploading, the report id is populated:
// getReportId
//
class CrashService {
public:
// Context state used by breakpad crash server dump request callbacks
struct DumpRequestContext {
std::string file_path;
};
// Server state used by breakpad crash server connect / exit callbacks
struct ServerState {
bool waiting;
int connected;
};
// version and build args will be used to construct breakpad version
// identifier
CrashService(const std::string& version,
const std::string& build,
const char* dataDir);
virtual ~CrashService();
// Save a dumpfile path
void setDumpFile(const std::string& dumpfile);
// Get saved dumpfile path
std::string getDumpFile() const;
// Check if saved dumpfile path is valid
bool validDumpFile() const;
// Wait for client to crashdump or exit or timeout in ms. |timeout| of -1
// for no timeout.
// Returns -1 if parent dies unexpectedly or timeout
// Return ms time taken to receive crashdump otherwise
int64_t waitForDumpFile(int clientpid, int timeout_ms = -1);
// Platform specific start of the crash server
// Returns false if already started or not successful
virtual bool startCrashServer(const std::string& pipe) = 0;
// Platform specific stop of the crash server
// Returns false if not started
virtual bool stopCrashServer() = 0;
UserSuggestions getSuggestions();
// Processes the saved dumpfile with breakpad processor libraries
// Contains stack trace and loaded modules.
// Is parsed for suggestions on debugging
// (driver update etc)
// Return true on success
bool processCrash();
// Collects system info, resulting in the "full" dump file.
bool collectSysInfo();
// Utility function for reading a txt file into string
static std::string readFile(android::base::StringView path);
// Return string containing collectSysInfo result
std::string getSysInfo();
// Uploads the saved dumpfile to server defined by CrashSystem
bool uploadCrash();
// Get the processed crash report
std::string getReport();
// Get the crash report ID returned by the crash servers
std::string getReportId() const;
// Returns the dump message passed by the emulator (or empty string if
// there's none)
const std::string& getDumpMessage() const;
const std::string& getCrashOnExitMessage() const;
// Tells us whether or not this crash was an exit crash.
bool didCrashOnExit() const;
// Factory method
static std::unique_ptr<CrashService> makeCrashService(
const std::string& version,
const std::string& build,
const char* dataDir);
// Key value pair to be added to crash report
void addReportValue(const std::string& key, const std::string& value);
// Key filepath pair to be added to crash report
void addReportFile(const std::string& key, const std::string& path);
// User comments to be added to crash report
void addUserComments(const std::string& comments);
// Read the dump message passed by the watched/dumped application
void retrieveDumpMessage();
// Collects the process list, default implementation runs the POSIX ps
// command
virtual void collectProcessList();
protected:
// Initialize serverstate
void initCrashServer();
const std::string& getDataDirectory() const;
// Platform specific set instance client
// Returns false if invalid pid
virtual bool setClient(int clientpid);
// Platform specific check if instance client is still running
// Returns false if client not set or not running
virtual bool isClientAlive() = 0;
// Uploads system-specific hardware information.
virtual bool getHWInfo() = 0;
// Uploads system-specific memory information.
virtual bool getMemInfo() = 0;
DumpRequestContext mDumpRequestContext;
ServerState mServerState;
int mClientPID = 0;
std::string mDataDirectory;
static const char* const kHwInfoName;
static const char* const kMemInfoName;
private:
CrashService();
// Read the data files passed by the watched/dumped application
void collectDataFiles();
std::string mVersion;
std::string mBuild;
std::string mVersionId;
std::string mDumpFile;
std::string mReportId;
std::string mComments;
std::string mDumpMessage;
std::string mCrashOnExitMessage;
std::map<std::string, std::string> mReportValues;
std::map<std::string, std::string> mReportFiles;
google_breakpad::ProcessState mProcessState;
google_breakpad::BasicSourceLineResolver mLineResolver;
std::unique_ptr<google_breakpad::Minidump> mMinidump;
bool mDidCrashOnExit;
};
} // namespace crashreport
} // namespace android