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 ()
 
bool isRunning () const
 
void restart ()
 

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 171 of file Tracer.cpp.

174 : _checkFlag(std::move(checkFlag)), _serverPath(std::move(serverPath)), _serverProxy(std::move(serverProxy)),
175 _attachments(std::move(attachments))
176{
177 auto selfDir = getSelfExecutableDir();
178
179 _handlerPath = crashpadHandlerPath.empty() ? selfDir + "/crashpad_handler" : crashpadHandlerPath;
180 _reportPath = reportPath.empty() ? selfDir : reportPath;
181 _clientHandler = std::make_unique<crashpad::CrashpadClient>();
182
183 _annotations = std::map<std::string, std::string>(
184 {{"name", PROJECT_NAME},
185 {"version", PROJECT_FULL_REVISION},
186 {"build_info", PROJECT_BUILD_DATE + std::string(" ") + PROJECT_BUILD_TIME + std::string(" ") + BUILD_TYPE},
187 {"compiler_info", COMPILER_NAME + std::string(" ") + COMPILER_VERSION}});
188
189 // Dump shared library information and add as attachment
190 dumpSharedLibraryInfo(_reportPath + "/shared_libs.txt");
191 _attachments.emplace_back(_reportPath + "/shared_libs.txt");
192
193 startHandler();
194}
std::string _reportPath
Definition Tracer.hpp:21
static void dumpSharedLibraryInfo(const std::string &filePath)
Definition Tracer.cpp:131
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:92
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 196 of file Tracer.cpp.

197{
198 _shouldStop._M_i = true;
199 if (_thread && _thread->joinable())
200 {
201 _thread->join();
202 }
203}
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 80 of file Tracer.cpp.

80{ 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 82 of file Tracer.cpp.

83{
84 int error = 0;
85 socklen_t len = sizeof(error);
86
87 char buff = 0;
88 const int result = getsockopt(sockId, SOL_SOCKET, SO_ERROR, &error, &len);
89 return result == 0 && error == 0 && recv(sockId, &buff, 1, MSG_PEEK | MSG_DONTWAIT) != 0;
90}
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 131 of file Tracer.cpp.

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

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

◆ isRunning()

bool Tracer::isRunning ( ) const
nodiscard

Check if the crashpad_handler process is running

Returns
true if the crashpad_handler is running, false otherwise

Definition at line 102 of file Tracer.cpp.

103{
104 int sockId{-1};
105 pid_t processId{-1};
106
107 if (!_clientHandler->GetHandlerSocket(&sockId, &processId))
108 {
109 return false;
110 }
111
112 if (sockId >= 0 && !checkSocketIsRunning(sockId))
113 {
114 return false;
115 }
116 if (processId > 0 && !checkPidIsRunning(processId))
117 {
118 return false;
119 }
120 return true;
121}
static bool checkSocketIsRunning(int sockId)
Definition Tracer.cpp:82
static bool checkPidIsRunning(pid_t processId)
Definition Tracer.cpp:80
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 123 of file Tracer.cpp.

124{
125 if (!isRunning())
126 {
127 startHandler();
128 }
129}
bool isRunning() const
Definition Tracer.cpp:102
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 restart();
65 spdlog::warn("Crashpad handler restarted");
66 }
67 if (_checkFlag)
68 {
69 _checkFlag->test_and_set();
70 }
71 }
72 catch (const std::exception &e)
73 {
74 spdlog::error("Crashpad failed: {}", e.what());
75 }
76 std::this_thread::sleep_for(std::chrono::milliseconds(SLEEP_INTERVAL_MS));
77 }
78}
constexpr int SLEEP_INTERVAL_MS
void restart()
Definition Tracer.cpp:123
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: