5
5
6
6
#include < algorithm>
7
7
#include < cstdint>
8
- #include < vector>
9
8
#include < dirent.h>
10
- #include < string>
11
9
#include < memory>
10
+ #include < string>
11
+ #include < vector>
12
12
13
- #include < libunwind.h>
14
- #include < libunwind-ptrace.h>
15
- #include < sys/ptrace.h>
16
- #include < sys/wait.h>
13
+ #include " FfiHelper.h"
17
14
#include < fstream>
18
- #include < sstream>
15
+ #include < libunwind-ptrace.h>
16
+ #include < libunwind.h>
19
17
#include < map>
18
+ #include < sstream>
20
19
#include < string.h>
21
- #include " FfiHelper.h"
20
+ #include < sys/ptrace.h>
21
+ #include < sys/wait.h>
22
22
23
23
extern " C"
24
24
{
25
25
#include " datadog/common.h"
26
- #include " datadog/profiling.h"
27
26
#include " datadog/crashtracker.h"
27
+ #include " datadog/profiling.h"
28
28
}
29
29
30
30
#include < shared/src/native-src/dd_filesystem.hpp>
@@ -35,8 +35,8 @@ CrashReporting* CrashReporting::Create(int32_t pid)
35
35
return (CrashReporting*)crashReporting;
36
36
}
37
37
38
- CrashReportingLinux::CrashReportingLinux (int32_t pid)
39
- : CrashReporting(pid)
38
+ CrashReportingLinux::CrashReportingLinux (int32_t pid) :
39
+ CrashReporting(pid)
40
40
{
41
41
}
42
42
@@ -67,17 +67,17 @@ int32_t CrashReportingLinux::Initialize()
67
67
return result;
68
68
}
69
69
70
- std::pair<std::string_view, uintptr_t > CrashReportingLinux::FindModule (uintptr_t ip)
70
+ const ModuleInfo* CrashReportingLinux::FindModule (uintptr_t ip)
71
71
{
72
72
for (auto const & module : _modules)
73
73
{
74
74
if (ip >= module.startAddress && ip < module.endAddress )
75
75
{
76
- return std::make_pair ( module. path , module. baseAddress ) ;
76
+ return & module;
77
77
}
78
78
}
79
79
80
- return std::make_pair ( " " , 0 ) ;
80
+ return nullptr ;
81
81
}
82
82
83
83
std::vector<ModuleInfo> CrashReportingLinux::GetModules ()
@@ -97,10 +97,9 @@ std::vector<ModuleInfo> CrashReportingLinux::GetModules()
97
97
std::getline (iss, path); // Skip whitespace at the start
98
98
99
99
// Trim path
100
- path.erase (path.begin (), std::find_if (path.begin (), path.end (), [](int ch)
101
- {
102
- return !std::isspace (ch);
103
- }));
100
+ path.erase (path.begin (), std::find_if (path.begin (), path.end (), [](int ch) {
101
+ return !std::isspace (ch);
102
+ }));
104
103
105
104
if (path.empty ())
106
105
{
@@ -133,7 +132,8 @@ std::vector<ModuleInfo> CrashReportingLinux::GetModules()
133
132
moduleBaseAddresses[path] = baseAddress;
134
133
}
135
134
136
- modules.push_back (ModuleInfo{ start, end, baseAddress, std::move (path) });
135
+ auto buildId = ElfBuildId (path.data ());
136
+ modules.push_back (ModuleInfo{ start, end, baseAddress, std::move (path), std::move (buildId) });
137
137
}
138
138
139
139
return modules;
@@ -196,67 +196,76 @@ std::vector<StackFrame> CrashReportingLinux::GetThreadFrames(int32_t tid, Resolv
196
196
stackFrame.sp = sp;
197
197
stackFrame.isSuspicious = false ;
198
198
199
- ResolveMethodData methodData;
200
199
201
- auto [moduleName, moduleAddress] = FindModule (ip);
202
- stackFrame.moduleAddress = moduleAddress;
203
-
204
- bool hasName = false ;
205
-
206
- unw_proc_info_t procInfo;
207
- result = unw_get_proc_info (&cursor, &procInfo);
208
-
209
- if (result == 0 )
200
+ auto * module = FindModule (ip);
201
+ if (module != nullptr )
210
202
{
211
- stackFrame.symbolAddress = procInfo. start_ip ;
203
+ stackFrame.moduleAddress = module-> baseAddress ;
212
204
213
- unw_word_t offset;
214
- result = unw_get_proc_name (&cursor, methodData.symbolName , sizeof (methodData.symbolName ), &offset);
205
+ bool hasName = false ;
206
+
207
+ unw_proc_info_t procInfo;
208
+ result = unw_get_proc_info (&cursor, &procInfo);
215
209
216
210
if (result == 0 )
217
211
{
218
- stackFrame.method = std::string (methodData.symbolName );
219
- hasName = true ;
212
+ stackFrame.symbolAddress = procInfo.start_ip ;
220
213
221
- auto demangleResult = ddog_crasht_demangle (libdatadog::to_char_slice (stackFrame.method ), DDOG_CRASHT_DEMANGLE_OPTIONS_COMPLETE);
214
+ ResolveMethodData methodData;
215
+ unw_word_t offset;
216
+ result = unw_get_proc_name (&cursor, methodData.symbolName , sizeof (methodData.symbolName ), &offset);
222
217
223
- if (demangleResult. tag == DDOG_CRASHT_STRING_WRAPPER_RESULT_OK )
218
+ if (result == 0 )
224
219
{
225
- // TODO: There is currently no safe way to free the StringWrapper
226
- auto stringWrapper = demangleResult.ok ;
220
+ stackFrame.method = std::string (methodData.symbolName );
221
+ hasName = true ;
222
+
223
+ auto demangleResult = ddog_crasht_demangle (libdatadog::to_char_slice (stackFrame.method ), DDOG_CRASHT_DEMANGLE_OPTIONS_COMPLETE);
227
224
228
- if (stringWrapper. message . len > 0 )
225
+ if (demangleResult. tag == DDOG_CRASHT_STRING_WRAPPER_RESULT_OK )
229
226
{
230
- stackFrame.method = std::string ((char *)stringWrapper.message .ptr , stringWrapper.message .len );
227
+ // TODO: There is currently no safe way to free the StringWrapper
228
+ auto stringWrapper = demangleResult.ok ;
229
+
230
+ if (stringWrapper.message .len > 0 )
231
+ {
232
+ stackFrame.method = std::string ((char *)stringWrapper.message .ptr , stringWrapper.message .len );
233
+ }
231
234
}
232
235
}
233
236
}
234
- }
235
237
236
- if (!hasName)
237
- {
238
- std::ostringstream unknownModule;
239
- unknownModule << moduleName << " !<unknown>+" << std::hex << (ip - moduleAddress );
240
- stackFrame.method = unknownModule.str ();
241
- }
238
+ if (!hasName)
239
+ {
240
+ std::ostringstream unknownModule;
241
+ unknownModule << module-> path << " !<unknown>+" << std::hex << (ip - module-> baseAddress );
242
+ stackFrame.method = unknownModule.str ();
243
+ }
242
244
243
- stackFrame.isSuspicious = false ;
245
+ stackFrame.isSuspicious = false ;
244
246
245
- fs::path modulePath (moduleName) ;
247
+ stackFrame. buildId = module-> build_id ;
246
248
247
- if (modulePath.has_filename ())
248
- {
249
- const auto moduleFilename = modulePath.stem ().string ();
249
+ fs::path modulePath (module->path );
250
250
251
- if ((moduleFilename.rfind (" Datadog" , 0 ) == 0 && stackFrame.method != " dd_pthread_entry" )
252
- || moduleFilename == " libdatadog"
253
- || moduleFilename == " datadog"
254
- || moduleFilename == " libddwaf"
255
- || moduleFilename == " ddwaf" )
251
+ if (modulePath.has_filename ())
256
252
{
257
- stackFrame.isSuspicious = true ;
253
+ const auto moduleFilename = modulePath.stem ().string ();
254
+
255
+ if ((moduleFilename.rfind (" Datadog" , 0 ) == 0 && stackFrame.method != " dd_pthread_entry" )
256
+ || moduleFilename == " libdatadog"
257
+ || moduleFilename == " datadog"
258
+ || moduleFilename == " libddwaf"
259
+ || moduleFilename == " ddwaf" )
260
+ {
261
+ stackFrame.isSuspicious = true ;
262
+ }
258
263
}
259
264
}
265
+ else
266
+ {
267
+ stackFrame.method = " <unknown>" ;
268
+ }
260
269
261
270
frames.push_back (std::move (stackFrame));
262
271
@@ -325,5 +334,5 @@ std::string CrashReportingLinux::GetThreadName(int32_t tid)
325
334
std::string threadName;
326
335
std::getline (commFile, threadName);
327
336
commFile.close ();
328
- return threadName;
337
+ return threadName;
329
338
}
0 commit comments