2323#include " NativeThreadLinux.h"
2424#include " Plugins/Process/POSIX/ProcessPOSIXLog.h"
2525#include " Plugins/Process/Utility/LinuxProcMaps.h"
26+ #include " Plugins/Process/Utility/LinuxProcStatus.h"
2627#include " Procfs.h"
2728#include " lldb/Core/ModuleSpec.h"
2829#include " lldb/Host/Host.h"
@@ -443,10 +444,29 @@ NativeProcessLinux::NativeProcessLinux(::pid_t pid, int terminal_fd,
443444 SetCurrentThreadID (tids[0 ]);
444445 SetState (StateType::eStateStopped, false );
445446}
447+ static bool IsCoredumping (lldb::pid_t pid) {
448+ auto BufferOrError = getProcFile (pid, " status" );
449+ if (!BufferOrError)
450+ return false ;
451+
452+ lldb_private::StructuredData::Dictionary proc_status =
453+ ParseProcStatus (BufferOrError.get ()->getBuffer ());
454+
455+ if (!proc_status.HasKey (" CoreDumping" ))
456+ return false ;
457+
458+ llvm::StringRef result;
459+ if (!proc_status.GetValueForKeyAsString (" CoreDumping" , result))
460+ return false ;
461+
462+ return result == " 1" ;
463+ }
446464
447465llvm::Expected<std::vector<::pid_t >> NativeProcessLinux::Attach (::pid_t pid) {
448466 Log *log = GetLog (POSIXLog::Process);
449467
468+ bool coreDumping = IsCoredumping (pid);
469+ LLDB_LOG (log, " {0} coredumping: {1}" , pid, coreDumping);
450470 Status status;
451471 // Use a map to keep track of the threads which we have attached/need to
452472 // attach.
@@ -457,21 +477,55 @@ llvm::Expected<std::vector<::pid_t>> NativeProcessLinux::Attach(::pid_t pid) {
457477 if (it->second == false ) {
458478 lldb::tid_t tid = it->first ;
459479
460- // Attach to the requested process.
461- // An attach will cause the thread to stop with a SIGSTOP.
462- if ((status = PtraceWrapper (PTRACE_ATTACH, tid)).Fail ()) {
463- // No such thread. The thread may have exited. More error handling
464- // may be needed.
465- if (status.GetError () == ESRCH) {
466- it = tids_to_attach.erase (it);
467- continue ;
480+ if (!coreDumping) {
481+ // Attach to the requested process.
482+ // An attach will cause the thread to stop with a SIGSTOP.
483+ if ((status = PtraceWrapper (PTRACE_ATTACH, tid)).Fail ()) {
484+ // No such thread. The thread may have exited. More error handling
485+ // may be needed.
486+ if (status.GetError () == ESRCH) {
487+ it = tids_to_attach.erase (it);
488+ continue ;
489+ }
490+ if (status.GetError () == EPERM) {
491+ // Depending on the value of ptrace_scope, we can return a
492+ // different error that suggests how to fix it.
493+ return AddPtraceScopeNote (status.ToError ());
494+ }
495+ return status.ToError ();
468496 }
469- if (status.GetError () == EPERM) {
470- // Depending on the value of ptrace_scope, we can return a different
471- // error that suggests how to fix it.
472- return AddPtraceScopeNote (status.ToError ());
497+ } else {
498+ long options = PTRACE_O_TRACEEXIT | PTRACE_O_TRACESYSGOOD;
499+ if ((status =
500+ PtraceWrapper (PTRACE_SEIZE, tid, nullptr , (void *)options))
501+ .Fail ()) {
502+ // No such thread. The thread may have exited. More error handling
503+ // may be needed.
504+ if (status.GetError () == ESRCH) {
505+ it = tids_to_attach.erase (it);
506+ continue ;
507+ }
508+ if (status.GetError () == EPERM) {
509+ // Depending on the value of ptrace_scope, we can return a
510+ // different error that suggests how to fix it.
511+ return AddPtraceScopeNote (status.ToError ());
512+ }
513+ return status.ToError ();
514+ }
515+ if ((status = PtraceWrapper (PTRACE_INTERRUPT, tid)).Fail ()) {
516+ // No such thread. The thread may have exited. More error handling
517+ // may be needed.
518+ if (status.GetError () == ESRCH) {
519+ it = tids_to_attach.erase (it);
520+ continue ;
521+ }
522+ if (status.GetError () == EPERM) {
523+ // Depending on the value of ptrace_scope, we can return a
524+ // different error that suggests how to fix it.
525+ return AddPtraceScopeNote (status.ToError ());
526+ }
527+ return status.ToError ();
473528 }
474- return status.ToError ();
475529 }
476530
477531 int wpid =
0 commit comments