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 () const 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 163 of file Tracer.cpp.

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

189{
190 _shouldStop._M_i = true;
191 if (_thread && _thread->joinable())
192 {
193 _thread->join();
194 }
195}
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 123 of file Tracer.cpp.

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

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 (!crashpad::CrashpadClient::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

◆ 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() const 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 ( ) const
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 spdlog::info("Crashpad handler closed");
65 return;
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
static bool isRunning()
Definition Tracer.cpp:102
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: