@@ -312,26 +312,10 @@ NativeProcessLinux::Manager::Attach(
312312 Log *log = GetLog (POSIXLog::Process);
313313 LLDB_LOG (log, " pid = {0:x}" , pid);
314314
315- // This safety check lets us decide if we should
316- // seize or attach.
317- ProcessInstanceInfo process_info;
318- if (!Host::GetProcessInfo (pid, process_info))
319- return llvm::make_error<StringError>(" Unable to read process info" ,
320- llvm::inconvertibleErrorCode ());
321-
322- std::vector<::pid_t > tids;
323- // IsCoreDumping is an optional, so check for value then true/false.
324- if (process_info.IsCoreDumping () && *process_info.IsCoreDumping ()) {
325- auto attached_or = NativeProcessLinux::Seize (pid);
326- if (!attached_or)
327- return attached_or.takeError ();
328- tids = std::move (*attached_or);
329- } else {
330- auto attached_or = NativeProcessLinux::Attach (pid);
331- if (!attached_or)
332- return attached_or.takeError ();
333- tids = std::move (*attached_or);
334- }
315+ auto tids_or = NativeProcessLinux::Attach (pid);
316+ if (!tids_or)
317+ return tids_or.takeError ();
318+ ArrayRef<::pid_t > tids = *tids_or;
335319
336320 llvm::Expected<ArchSpec> arch_or =
337321 NativeRegisterContextLinux::DetermineArchitecture (tids[0 ]);
@@ -461,91 +445,10 @@ NativeProcessLinux::NativeProcessLinux(::pid_t pid, int terminal_fd,
461445 SetState (StateType::eStateStopped, false );
462446}
463447
464- llvm::Expected<std::vector<::pid_t >> NativeProcessLinux::Seize (::pid_t pid) {
465- Log *log = GetLog (POSIXLog::Process);
466-
467- uint64_t options = GetDefaultPtraceOpts ();
468- Status status;
469- // Use a map to keep track of the threads which we have attached/need to
470- // attach.
471- Host::TidMap tids_to_attach;
472- while (Host::FindProcessThreads (pid, tids_to_attach)) {
473- for (Host::TidMap::iterator it = tids_to_attach.begin ();
474- it != tids_to_attach.end ();) {
475- if (it->second == true ) {
476- continue ;
477- }
478- lldb::tid_t tid = it->first ;
479- if ((status = PtraceWrapper (PTRACE_SEIZE, tid, nullptr , (void *)options))
480- .Fail ()) {
481- // No such thread. The thread may have exited. More error handling
482- // may be needed.
483- if (status.GetError () == ESRCH) {
484- it = tids_to_attach.erase (it);
485- continue ;
486- }
487- if (status.GetError () == EPERM) {
488- // Depending on the value of ptrace_scope, we can return a
489- // different error that suggests how to fix it.
490- return AddPtraceScopeNote (status.ToError ());
491- }
492- return status.ToError ();
493- }
494-
495- if ((status = PtraceWrapper (PTRACE_INTERRUPT, tid)).Fail ()) {
496- // No such thread. The thread may have exited. More error handling
497- // may be needed.
498- if (status.GetError () == ESRCH) {
499- it = tids_to_attach.erase (it);
500- continue ;
501- }
502- if (status.GetError () == EPERM) {
503- // Depending on the value of ptrace_scope, we can return a
504- // different error that suggests how to fix it.
505- return AddPtraceScopeNote (status.ToError ());
506- }
507- return status.ToError ();
508- }
509-
510- int wpid =
511- llvm::sys::RetryAfterSignal (-1 , ::waitpid, tid, nullptr , __WALL);
512- // Need to use __WALL otherwise we receive an error with errno=ECHLD At
513- // this point we should have a thread stopped if waitpid succeeds.
514- if (wpid < 0 ) {
515- // No such thread. The thread may have exited. More error handling
516- // may be needed.
517- if (errno == ESRCH) {
518- it = tids_to_attach.erase (it);
519- continue ;
520- }
521- return llvm::errorCodeToError (
522- std::error_code (errno, std::generic_category ()));
523- }
524-
525- LLDB_LOG (log, " adding tid = {0}" , tid);
526- it->second = true ;
527-
528- // move the loop forward
529- ++it;
530- }
531- }
532-
533- size_t tid_count = tids_to_attach.size ();
534- if (tid_count == 0 )
535- return llvm::make_error<StringError>(" No such process" ,
536- llvm::inconvertibleErrorCode ());
537-
538- std::vector<::pid_t > tids;
539- tids.reserve (tid_count);
540- for (const auto &p : tids_to_attach)
541- tids.push_back (p.first );
542-
543- return std::move (tids);
544- }
545-
546448llvm::Expected<std::vector<::pid_t >> NativeProcessLinux::Attach (::pid_t pid) {
547449 Log *log = GetLog (POSIXLog::Process);
548450
451+ uint64_t options = GetDefaultPtraceOpts ();
549452 Status status;
550453 // Use a map to keep track of the threads which we have attached/need to
551454 // attach.
@@ -556,9 +459,12 @@ llvm::Expected<std::vector<::pid_t>> NativeProcessLinux::Attach(::pid_t pid) {
556459 if (it->second == false ) {
557460 lldb::tid_t tid = it->first ;
558461
559- // Attach to the requested process.
560- // An attach will cause the thread to stop with a SIGSTOP.
561- if ((status = PtraceWrapper (PTRACE_ATTACH, tid)).Fail ()) {
462+ // Seize and interrupt the requested process.
463+ // This will cause the thread to stop in a TRACE_STOP state.
464+ // Akin to a sigstop but without sending the signal.
465+ if ((status =
466+ PtraceWrapper (PTRACE_SEIZE, tid, nullptr , (void *)options))
467+ .Fail ()) {
562468 // No such thread. The thread may have exited. More error handling
563469 // may be needed.
564470 if (status.GetError () == ESRCH) {
@@ -573,6 +479,24 @@ llvm::Expected<std::vector<::pid_t>> NativeProcessLinux::Attach(::pid_t pid) {
573479 return status.ToError ();
574480 }
575481
482+ // Send a sigstop, this makes it so our seize->interrupt is signal wise
483+ // the same as ptrace_attach. We do this so any program/workflow
484+ // depending on the sending of a sigstop will still receive a sigstop.
485+ tgkill (tid, tid, SIGSTOP);
486+
487+ if ((status = PtraceWrapper (PTRACE_INTERRUPT, tid)).Fail ()) {
488+ // No such thread, the thread may have exited, this shouldn't
489+ // happen at this stage, but we check regardless
490+ if (status.GetError () == ESRCH) {
491+ it = tids_to_attach.erase (it);
492+ continue ;
493+ }
494+
495+ // No check for EPERM because we already checked for it above
496+ // when we seized
497+ return status.ToError ();
498+ }
499+
576500 int wpid =
577501 llvm::sys::RetryAfterSignal (-1 , ::waitpid, tid, nullptr , __WALL);
578502 // Need to use __WALL otherwise we receive an error with errno=ECHLD At
@@ -588,9 +512,6 @@ llvm::Expected<std::vector<::pid_t>> NativeProcessLinux::Attach(::pid_t pid) {
588512 std::error_code (errno, std::generic_category ()));
589513 }
590514
591- if ((status = SetDefaultPtraceOpts (tid)).Fail ())
592- return status.ToError ();
593-
594515 LLDB_LOG (log, " adding tid = {0}" , tid);
595516 it->second = true ;
596517 }
0 commit comments