@@ -157,8 +157,7 @@ ProcessMinidump::ProcessMinidump(lldb::TargetSP target_sp,
157
157
const FileSpec &core_file,
158
158
DataBufferSP core_data)
159
159
: PostMortemProcess(target_sp, listener_sp, core_file),
160
- m_core_data(std::move(core_data)), m_active_exception(nullptr ),
161
- m_is_wow64(false ) {}
160
+ m_core_data(std::move(core_data)), m_is_wow64(false ) {}
162
161
163
162
ProcessMinidump::~ProcessMinidump () {
164
163
Clear ();
@@ -209,7 +208,20 @@ Status ProcessMinidump::DoLoadCore() {
209
208
GetTarget ().SetArchitecture (arch, true /* set_platform*/ );
210
209
211
210
m_thread_list = m_minidump_parser->GetThreads ();
212
- m_active_exception = m_minidump_parser->GetExceptionStream ();
211
+ auto exception_stream_it = m_minidump_parser->GetExceptionStreams ();
212
+ for (auto exception_stream : exception_stream_it) {
213
+ // If we can't read an exception stream skip it
214
+ // We should probably serve a warning
215
+ if (!exception_stream)
216
+ continue ;
217
+
218
+ if (!m_exceptions_by_tid
219
+ .try_emplace (exception_stream->ThreadId , exception_stream.get ())
220
+ .second ) {
221
+ return Status::FromErrorStringWithFormatv (
222
+ " Duplicate exception stream for tid {0}" , exception_stream->ThreadId );
223
+ }
224
+ }
213
225
214
226
SetUnixSignals (UnixSignals::Create (GetArchitecture ()));
215
227
@@ -232,60 +244,57 @@ Status ProcessMinidump::DoDestroy() { return Status(); }
232
244
233
245
void ProcessMinidump::RefreshStateAfterStop () {
234
246
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
- }
247
+ for (const auto &[_, exception_stream] : m_exceptions_by_tid) {
248
+ constexpr uint32_t BreakpadDumpRequested = 0xFFFFFFFF ;
249
+ if (exception_stream.ExceptionRecord .ExceptionCode ==
250
+ BreakpadDumpRequested) {
251
+ // This "ExceptionCode" value is a sentinel that is sometimes used
252
+ // when generating a dump for a process that hasn't crashed.
253
+
254
+ // TODO: The definition and use of this "dump requested" constant
255
+ // in Breakpad are actually Linux-specific, and for similar use
256
+ // cases on Mac/Windows it defines different constants, referring
257
+ // to them as "simulated" exceptions; consider moving this check
258
+ // down to the OS-specific paths and checking each OS for its own
259
+ // constant.
260
+ return ;
261
+ }
252
262
253
- lldb::StopInfoSP stop_info;
254
- lldb::ThreadSP stop_thread;
263
+ lldb::StopInfoSP stop_info;
264
+ lldb::ThreadSP stop_thread;
255
265
256
- Process::m_thread_list.SetSelectedThreadByID (m_active_exception-> ThreadId );
257
- stop_thread = Process::m_thread_list.GetSelectedThread ();
258
- ArchSpec arch = GetArchitecture ();
266
+ Process::m_thread_list.SetSelectedThreadByID (exception_stream. ThreadId );
267
+ stop_thread = Process::m_thread_list.GetSelectedThread ();
268
+ ArchSpec arch = GetArchitecture ();
259
269
260
- if (arch.GetTriple ().getOS () == llvm::Triple::Linux) {
261
- uint32_t signo = m_active_exception->ExceptionRecord .ExceptionCode ;
270
+ if (arch.GetTriple ().getOS () == llvm::Triple::Linux) {
271
+ uint32_t signo = exception_stream.ExceptionRecord .ExceptionCode ;
272
+ if (signo == 0 ) {
273
+ // No stop.
274
+ return ;
275
+ }
262
276
263
- if (signo == 0 ) {
264
- // No stop.
265
- return ;
277
+ stop_info = StopInfo::CreateStopReasonWithSignal (*stop_thread, signo);
278
+ } else if (arch.GetTriple ().getVendor () == llvm::Triple::Apple) {
279
+ stop_info = StopInfoMachException::CreateStopReasonWithMachException (
280
+ *stop_thread, exception_stream.ExceptionRecord .ExceptionCode , 2 ,
281
+ exception_stream.ExceptionRecord .ExceptionFlags ,
282
+ exception_stream.ExceptionRecord .ExceptionAddress , 0 );
283
+ } else {
284
+ std::string desc;
285
+ llvm::raw_string_ostream desc_stream (desc);
286
+ desc_stream << " Exception "
287
+ << llvm::format_hex (
288
+ exception_stream.ExceptionRecord .ExceptionCode , 8 )
289
+ << " encountered at address "
290
+ << llvm::format_hex (
291
+ exception_stream.ExceptionRecord .ExceptionAddress , 8 );
292
+ stop_info = StopInfo::CreateStopReasonWithException (
293
+ *stop_thread, desc_stream.str ().c_str ());
266
294
}
267
295
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);
296
+ stop_thread->SetStopInfo (stop_info);
297
+ }
289
298
}
290
299
291
300
bool ProcessMinidump::IsAlive () { return true ; }
@@ -387,10 +396,9 @@ bool ProcessMinidump::DoUpdateThreadList(ThreadList &old_thread_list,
387
396
LocationDescriptor context_location = thread.Context ;
388
397
389
398
// 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 ;
393
- }
399
+ if (auto it = m_exceptions_by_tid.find (thread.ThreadId );
400
+ it != m_exceptions_by_tid.end ())
401
+ context_location = it->second .ThreadContext ;
394
402
395
403
llvm::ArrayRef<uint8_t > context;
396
404
if (!m_is_wow64)
0 commit comments