39
39
40
40
#include < memory>
41
41
#include < optional>
42
+ #include < iostream>
42
43
43
44
using namespace lldb ;
44
45
using namespace lldb_private ;
@@ -157,7 +158,7 @@ ProcessMinidump::ProcessMinidump(lldb::TargetSP target_sp,
157
158
const FileSpec &core_file,
158
159
DataBufferSP core_data)
159
160
: PostMortemProcess(target_sp, listener_sp, core_file),
160
- m_core_data(std::move(core_data)), m_active_exception( nullptr ),
161
+ m_core_data(std::move(core_data)),
161
162
m_is_wow64(false ) {}
162
163
163
164
ProcessMinidump::~ProcessMinidump () {
@@ -209,7 +210,19 @@ Status ProcessMinidump::DoLoadCore() {
209
210
GetTarget ().SetArchitecture (arch, true /* set_platform*/ );
210
211
211
212
m_thread_list = m_minidump_parser->GetThreads ();
212
- m_active_exception = m_minidump_parser->GetExceptionStream ();
213
+ std::vector<minidump::ExceptionStream> exception_streams = m_minidump_parser->GetExceptionStreams ();
214
+ for (const auto &exception_stream : exception_streams) {
215
+ if (m_exceptions_by_tid.count (exception_stream.ThreadId ) > 0 ) {
216
+ // We only cast to avoid the warning around converting little endian in printf.
217
+ error.SetErrorStringWithFormat (" duplicate exception stream for tid %" PRIu32, (uint32_t )exception_stream.ThreadId );
218
+ return error;
219
+ } else
220
+ m_exceptions_by_tid[exception_stream.ThreadId ] = exception_stream;
221
+
222
+
223
+ std::cout << " Adding Exception Stream # " << (uint32_t )exception_stream.ThreadId << std::endl;
224
+ std::cout << " Added index " << (uint32_t )m_exceptions_by_tid[exception_stream.ThreadId ].ExceptionRecord .ExceptionCode << std::endl;
225
+ }
213
226
214
227
SetUnixSignals (UnixSignals::Create (GetArchitecture ()));
215
228
@@ -232,60 +245,59 @@ Status ProcessMinidump::DoDestroy() { return Status(); }
232
245
233
246
void ProcessMinidump::RefreshStateAfterStop () {
234
247
235
- if (!m_active_exception)
236
- return ;
237
-
238
- constexpr uint32_t BreakpadDumpRequested = 0xFFFFFFFF ;
239
- if (m_active_exception->ExceptionRecord .ExceptionCode ==
240
- BreakpadDumpRequested) {
241
- // This "ExceptionCode" value is a sentinel that is sometimes used
242
- // when generating a dump for a process that hasn't crashed.
243
-
244
- // TODO: The definition and use of this "dump requested" constant
245
- // in Breakpad are actually Linux-specific, and for similar use
246
- // cases on Mac/Windows it defines different constants, referring
247
- // to them as "simulated" exceptions; consider moving this check
248
- // down to the OS-specific paths and checking each OS for its own
249
- // constant.
250
- return ;
251
- }
248
+ for (auto &[_, exception_stream] : m_exceptions_by_tid) {
249
+ constexpr uint32_t BreakpadDumpRequested = 0xFFFFFFFF ;
250
+ if (exception_stream.ExceptionRecord .ExceptionCode ==
251
+ BreakpadDumpRequested) {
252
+ // This "ExceptionCode" value is a sentinel that is sometimes used
253
+ // when generating a dump for a process that hasn't crashed.
254
+
255
+ // TODO: The definition and use of this "dump requested" constant
256
+ // in Breakpad are actually Linux-specific, and for similar use
257
+ // cases on Mac/Windows it defines different constants, referring
258
+ // to them as "simulated" exceptions; consider moving this check
259
+ // down to the OS-specific paths and checking each OS for its own
260
+ // constant.
261
+ return ;
262
+ }
252
263
253
- lldb::StopInfoSP stop_info;
254
- lldb::ThreadSP stop_thread;
264
+ lldb::StopInfoSP stop_info;
265
+ lldb::ThreadSP stop_thread;
255
266
256
- Process::m_thread_list.SetSelectedThreadByID (m_active_exception-> ThreadId );
257
- stop_thread = Process::m_thread_list.GetSelectedThread ();
258
- ArchSpec arch = GetArchitecture ();
267
+ Process::m_thread_list.SetSelectedThreadByID (exception_stream. ThreadId );
268
+ stop_thread = Process::m_thread_list.GetSelectedThread ();
269
+ ArchSpec arch = GetArchitecture ();
259
270
260
- if (arch.GetTriple ().getOS () == llvm::Triple::Linux) {
261
- uint32_t signo = m_active_exception->ExceptionRecord .ExceptionCode ;
271
+ if (arch.GetTriple ().getOS () == llvm::Triple::Linux) {
272
+ uint32_t signo = exception_stream.ExceptionRecord .ExceptionCode ;
273
+ std::cout << " Thread Id : " << exception_stream.ThreadId << " has signal " << signo << std::endl;
274
+ if (signo == 0 ) {
275
+ // No stop.
276
+ return ;
277
+ }
262
278
263
- if (signo == 0 ) {
264
- // No stop.
265
- return ;
279
+ stop_info = StopInfo::CreateStopReasonWithSignal (
280
+ *stop_thread, signo);
281
+ } else if (arch.GetTriple ().getVendor () == llvm::Triple::Apple) {
282
+ stop_info = StopInfoMachException::CreateStopReasonWithMachException (
283
+ *stop_thread, exception_stream.ExceptionRecord .ExceptionCode , 2 ,
284
+ exception_stream.ExceptionRecord .ExceptionFlags ,
285
+ exception_stream.ExceptionRecord .ExceptionAddress , 0 );
286
+ } else {
287
+ std::string desc;
288
+ llvm::raw_string_ostream desc_stream (desc);
289
+ desc_stream << " Exception "
290
+ << llvm::format_hex (
291
+ exception_stream.ExceptionRecord .ExceptionCode , 8 )
292
+ << " encountered at address "
293
+ << llvm::format_hex (
294
+ exception_stream.ExceptionRecord .ExceptionAddress , 8 );
295
+ stop_info = StopInfo::CreateStopReasonWithException (
296
+ *stop_thread, desc_stream.str ().c_str ());
266
297
}
267
298
268
- stop_info = StopInfo::CreateStopReasonWithSignal (
269
- *stop_thread, signo);
270
- } else if (arch.GetTriple ().getVendor () == llvm::Triple::Apple) {
271
- stop_info = StopInfoMachException::CreateStopReasonWithMachException (
272
- *stop_thread, m_active_exception->ExceptionRecord .ExceptionCode , 2 ,
273
- m_active_exception->ExceptionRecord .ExceptionFlags ,
274
- m_active_exception->ExceptionRecord .ExceptionAddress , 0 );
275
- } else {
276
- std::string desc;
277
- llvm::raw_string_ostream desc_stream (desc);
278
- desc_stream << " Exception "
279
- << llvm::format_hex (
280
- m_active_exception->ExceptionRecord .ExceptionCode , 8 )
281
- << " encountered at address "
282
- << llvm::format_hex (
283
- m_active_exception->ExceptionRecord .ExceptionAddress , 8 );
284
- stop_info = StopInfo::CreateStopReasonWithException (
285
- *stop_thread, desc_stream.str ().c_str ());
286
- }
287
-
288
- stop_thread->SetStopInfo (stop_info);
299
+ stop_thread->SetStopInfo (stop_info);
300
+ }
289
301
}
290
302
291
303
bool ProcessMinidump::IsAlive () { return true ; }
@@ -386,19 +398,21 @@ bool ProcessMinidump::DoUpdateThreadList(ThreadList &old_thread_list,
386
398
for (const minidump::Thread &thread : m_thread_list) {
387
399
LocationDescriptor context_location = thread.Context ;
388
400
401
+ std::optional<minidump::Exception> exception;
389
402
// If the minidump contains an exception context, use it
390
- if (m_active_exception != nullptr &&
391
- m_active_exception-> ThreadId == thread.ThreadId ) {
392
- context_location = m_active_exception-> ThreadContext ;
403
+ if (m_exceptions_by_tid. count (thread. ThreadId ) > 0 ) {
404
+ context_location = m_exceptions_by_tid[ thread.ThreadId ]. ThreadContext ;
405
+ exception = m_exceptions_by_tid[thread. ThreadId ]. ExceptionRecord ;
393
406
}
394
407
408
+
395
409
llvm::ArrayRef<uint8_t > context;
396
410
if (!m_is_wow64)
397
411
context = m_minidump_parser->GetThreadContext (context_location);
398
412
else
399
413
context = m_minidump_parser->GetThreadContextWow64 (thread);
400
414
401
- lldb::ThreadSP thread_sp (new ThreadMinidump (*this , thread, context));
415
+ lldb::ThreadSP thread_sp (new ThreadMinidump (*this , thread, context, exception ));
402
416
new_thread_list.AddThread (thread_sp);
403
417
}
404
418
return new_thread_list.GetSize (false ) > 0 ;
0 commit comments