Repo-Init
 
Loading...
Searching...
No Matches
Tracer Class Reference

#include <Tracer.hpp>

Public Member Functions

 Tracer (std::shared_ptr< std::atomic_flag > checkFlag, std::string serverPath="", std::string serverProxy="", const std::string &crashpadHandlerPath="", const std::string &reportPath="", std::vector< base::FilePath > attachments={})
 
 Tracer (const Tracer &)=delete
 Copy constructor.
 
 Tracer (Tracer &&)=delete
 Move constructor.
 
Traceroperator= (Tracer)=delete
 Copy assignment operator.
 
Traceroperator= (Tracer &&)=delete
 Move assignment operator.
 
 ~Tracer ()
 
void restart ()
 

Static Public Member Functions

static bool isRunning ()
 

Private Member Functions

void startHandler ()
 
void threadFunc () noexcept
 

Static Private Member Functions

static bool checkPidIsRunning (pid_t processId)
 
static bool checkSocketIsRunning (int sockId)
 
static std::string getSelfExecutableDir ()
 
static void dumpSharedLibraryInfo (const std::string &filePath)
 

Private Attributes

std::unique_ptr< std::thread > _thread
 
std::atomic_flag _shouldStop {false}
 
std::shared_ptr< std::atomic_flag > _checkFlag
 
std::string _serverPath
 
std::string _serverProxy
 
std::string _handlerPath
 
std::map< std::string, std::string > _annotations
 
std::vector< base::FilePath > _attachments
 
std::string _reportPath
 
std::unique_ptr< crashpad::CrashpadClient > _clientHandler
 

Detailed Description

Tracer class to handle operations of Crashpad

Definition at line 10 of file Tracer.hpp.

Constructor & Destructor Documentation

◆ Tracer() [1/3]

Tracer::Tracer ( std::shared_ptr< std::atomic_flag > checkFlag,
std::string serverPath = "",
std::string serverProxy = "",
const std::string & crashpadHandlerPath = "",
const std::string & reportPath = "",
std::vector< base::FilePath > attachments = {} )
explicit

Construct a new Tracer object

Parameters
[in]checkFlagFlag to check if the process is running
[in]serverPathRemote server address
[in]serverProxyRemote server proxy
[in]reportPathPath to where dump minidump files
[in]crashpadHandlerPathPath to crashpad_handler executable
[in]attachmentsAttachments to add to the minidump

Definition at line 173 of file Tracer.cpp.

176 : _checkFlag(std::move(checkFlag)), _serverPath(std::move(serverPath)), _serverProxy(std::move(serverProxy)),
177 _attachments(std::move(attachments))
178{
179 auto selfDir = getSelfExecutableDir();
180
181 _handlerPath = crashpadHandlerPath.empty() ? selfDir + "/crashpad_handler" : crashpadHandlerPath;
182 _reportPath = reportPath.empty() ? selfDir : reportPath;
183 _clientHandler = std::make_unique<crashpad::CrashpadClient>();
184
185 _annotations = std::map<std::string, std::string>(
186 {{"name", PROJECT_NAME},
187 {"version", PROJECT_FULL_REVISION},
188 {"build_info", PROJECT_BUILD_DATE + std::string(" ") + PROJECT_BUILD_TIME + std::string(" ") + BUILD_TYPE},
189 {"compiler_info", COMPILER_NAME + std::string(" ") + COMPILER_VERSION}});
190
191 // Dump shared library information and add as attachment
192 dumpSharedLibraryInfo(_reportPath + "/shared_libs.txt");
193 _attachments.emplace_back(_reportPath + "/shared_libs.txt");
194
195 startHandler();
196}
std::string _reportPath
Definition Tracer.hpp:21
static void dumpSharedLibraryInfo(const std::string &filePath)
Definition Tracer.cpp:133
void startHandler()
Definition Tracer.cpp:22
std::unique_ptr< crashpad::CrashpadClient > _clientHandler
Definition Tracer.hpp:22
std::string _serverPath
Definition Tracer.hpp:16
std::string _serverProxy
Definition Tracer.hpp:17
std::vector< base::FilePath > _attachments
Definition Tracer.hpp:20
std::shared_ptr< std::atomic_flag > _checkFlag
Definition Tracer.hpp:14
static std::string getSelfExecutableDir()
Definition Tracer.cpp:94
std::map< std::string, std::string > _annotations
Definition Tracer.hpp:19
std::string _handlerPath
Definition Tracer.hpp:18
Here is the call graph for this function:

◆ Tracer() [2/3]

Tracer::Tracer ( const Tracer & )
delete

Copy constructor.

◆ Tracer() [3/3]

Tracer::Tracer ( Tracer && )
delete

Move constructor.

◆ ~Tracer()

Tracer::~Tracer ( )

Destroy the Tracer object

Definition at line 198 of file Tracer.cpp.

199{
200 _shouldStop._M_i = true;
201 if (_thread && _thread->joinable())
202 {
203 _thread->join();
204 }
205}
std::atomic_flag _shouldStop
Definition Tracer.hpp:13
std::unique_ptr< std::thread > _thread
Definition Tracer.hpp:12

Member Function Documentation

◆ checkPidIsRunning()

bool Tracer::checkPidIsRunning ( pid_t processId)
staticprivate

Check if the given process ID is running

Parameters
[in]processIdThe process ID to check
Returns
true if the process is running, false otherwise

Definition at line 82 of file Tracer.cpp.

82{ return kill(processId, 0) == 0; }
Here is the caller graph for this function:

◆ checkSocketIsRunning()

bool Tracer::checkSocketIsRunning ( int sockId)
staticprivate

Check if the given socket ID is running

Parameters
[in]sockIdThe socket ID to check
Returns
true if the socket is running, false otherwise

Definition at line 84 of file Tracer.cpp.

85{
86 int error = 0;
87 socklen_t len = sizeof(error);
88
89 char buff = 0;
90 const int result = getsockopt(sockId, SOL_SOCKET, SO_ERROR, &error, &len);
91 return result == 0 && error == 0 && recv(sockId, &buff, 1, MSG_PEEK | MSG_DONTWAIT) != 0;
92}
Here is the caller graph for this function:

◆ dumpSharedLibraryInfo()

void Tracer::dumpSharedLibraryInfo ( const std::string & filePath)
staticprivate

Dump shared library information to a file

Parameters
[in]filePathFile path to dump the information

Definition at line 133 of file Tracer.cpp.

134{
135 // Open the output file
136 std::ofstream ofile(filePath);
137 if (!ofile.is_open())
138 {
139 throw std::invalid_argument("Can't open file: " + filePath);
140 }
141
142 // Get the shared library information
143 std::ifstream maps("/proc/self/maps");
144
145 std::string line;
146 while (std::getline(maps, line))
147 {
148 // The format of each line is: address perms offset dev inode pathname
149 // We only care about the address and the pathname, which are the first and last fields
150 std::istringstream iss(line);
151 std::string address;
152 std::string perms;
153 std::string offset;
154 std::string dev;
155 std::string inode;
156 std::string pathname;
157 iss >> address >> perms >> offset >> dev >> inode >> pathname;
158
159 // We only want the shared libraries, which have the .so extension and the read and execute permissions
160 if (pathname.find(".so") != std::string::npos && perms.find("r-x") != std::string::npos)
161 {
162 // The address field is in the form of start-end, we only need the start address
163 const std::string start = address.substr(0, address.find('-'));
164
165 // Convert the start address from hexadecimal string to unsigned long
166 const unsigned long addr = std::stoul(start, nullptr, 16);
167
168 ofile << pathname << " " << addr << '\n';
169 }
170 }
171}
Here is the caller graph for this function:

◆ getSelfExecutableDir()

std::string Tracer::getSelfExecutableDir ( )
inlinestaticprivate

Get the executable directory of the current application

Returns
The executable directory path

Definition at line 94 of file Tracer.cpp.

95{
96 std::array<char, FILENAME_MAX> pathBuffer{'\0'};
97 auto bytes = readlink("/proc/self/exe", pathBuffer.data(), sizeof(pathBuffer));
98
99 auto path = std::string(pathBuffer.data(), bytes == -1 ? 0 : static_cast<size_t>(bytes));
100 auto lastDelimPos = path.find_last_of('/');
101 return (lastDelimPos == std::string::npos) ? "" : path.substr(0, lastDelimPos);
102}
Here is the caller graph for this function:

◆ isRunning()

bool Tracer::isRunning ( )
staticnodiscard

Check if the crashpad_handler process is running

Returns
true if the crashpad_handler is running, false otherwise

Definition at line 104 of file Tracer.cpp.

105{
106 int sockId{-1};
107 pid_t processId{-1};
108
109 if (!crashpad::CrashpadClient::GetHandlerSocket(&sockId, &processId))
110 {
111 return false;
112 }
113
114 if (sockId >= 0 && !checkSocketIsRunning(sockId))
115 {
116 return false;
117 }
118 if (processId > 0 && !checkPidIsRunning(processId))
119 {
120 return false;
121 }
122 return true;
123}
static bool checkSocketIsRunning(int sockId)
Definition Tracer.cpp:84
static bool checkPidIsRunning(pid_t processId)
Definition Tracer.cpp:82
Here is the call graph for this function:
Here is the caller graph for this function:

◆ operator=() [1/2]

Tracer & Tracer::operator= ( Tracer && )
delete

Move assignment operator.

◆ operator=() [2/2]

Tracer & Tracer::operator= ( Tracer )
delete

Copy assignment operator.

◆ restart()

void Tracer::restart ( )

Check and restart the crashpad_handler process if it is not running

Definition at line 125 of file Tracer.cpp.

126{
127 if (!isRunning())
128 {
129 startHandler();
130 }
131}
static bool isRunning()
Definition Tracer.cpp:104
Here is the call graph for this function:
Here is the caller graph for this function:

◆ startHandler()

void Tracer::startHandler ( )
private

Start the crashpad handler process

Definition at line 22 of file Tracer.cpp.

23{
24 // Path to crashpad executable
25 const base::FilePath handler(_handlerPath);
26
27 // Must be writable or crashpad_handler will crash
28 const base::FilePath reportsDir(_reportPath);
29 const base::FilePath metricsDir(_reportPath);
30
31 // Initialize Crashpad database
32 auto database = crashpad::CrashReportDatabase::Initialize(reportsDir);
33 if (database == nullptr)
34 {
35 throw std::ios_base::failure("Can't initialize crash report database");
36 }
37
38 // Enable automated crash uploads
39 auto *settings = database->GetSettings();
40 if (settings == nullptr)
41 {
42 throw std::ios_base::failure("Can't get crash report database settings");
43 }
44 settings->SetUploadsEnabled(true);
45
46 // Start crash handler
47 if (!_clientHandler->StartHandler(handler, reportsDir, metricsDir, _serverPath, _serverProxy, _annotations,
48 {"--no-rate-limit"}, true, false, _attachments))
49 {
50 throw std::ios_base::failure("Can't start crash handler");
51 }
52
53 _thread = std::make_unique<std::thread>(&Tracer::threadFunc, this);
54}
void threadFunc() noexcept
Definition Tracer.cpp:56
Here is the call graph for this function:
Here is the caller graph for this function:

◆ threadFunc()

void Tracer::threadFunc ( )
privatenoexcept

Thread function to check and restart the crashpad handler process

Definition at line 56 of file Tracer.cpp.

57{
58 while (!_shouldStop._M_i)
59 {
60 try
61 {
62 if (!isRunning())
63 {
64 // NOTICE: Worked before but currently restarting the handler raises an error
65 // due to changes in the crashpad library
66 restart();
67 spdlog::warn("Crashpad handler restarted");
68 }
69 if (_checkFlag)
70 {
71 _checkFlag->test_and_set();
72 }
73 }
74 catch (const std::exception &e)
75 {
76 spdlog::error("Crashpad failed: {}", e.what());
77 }
78 std::this_thread::sleep_for(std::chrono::milliseconds(SLEEP_INTERVAL_MS));
79 }
80}
constexpr int SLEEP_INTERVAL_MS
void restart()
Definition Tracer.cpp:125
Here is the call graph for this function:
Here is the caller graph for this function:

Member Data Documentation

◆ _annotations

std::map<std::string, std::string> Tracer::_annotations
private

Definition at line 19 of file Tracer.hpp.

◆ _attachments

std::vector<base::FilePath> Tracer::_attachments
private

Definition at line 20 of file Tracer.hpp.

◆ _checkFlag

std::shared_ptr<std::atomic_flag> Tracer::_checkFlag
private

Definition at line 14 of file Tracer.hpp.

◆ _clientHandler

std::unique_ptr<crashpad::CrashpadClient> Tracer::_clientHandler
private

Definition at line 22 of file Tracer.hpp.

◆ _handlerPath

std::string Tracer::_handlerPath
private

Definition at line 18 of file Tracer.hpp.

◆ _reportPath

std::string Tracer::_reportPath
private

Definition at line 21 of file Tracer.hpp.

◆ _serverPath

std::string Tracer::_serverPath
private

Definition at line 16 of file Tracer.hpp.

◆ _serverProxy

std::string Tracer::_serverProxy
private

Definition at line 17 of file Tracer.hpp.

◆ _shouldStop

std::atomic_flag Tracer::_shouldStop {false}
private

Definition at line 13 of file Tracer.hpp.

13{false};

◆ _thread

std::unique_ptr<std::thread> Tracer::_thread
private

Definition at line 12 of file Tracer.hpp.


The documentation for this class was generated from the following files: