1af245d11STodd Fiala //===-- NativeProcessLinux.cpp -------------------------------- -*- C++ -*-===// 2af245d11STodd Fiala // 3af245d11STodd Fiala // The LLVM Compiler Infrastructure 4af245d11STodd Fiala // 5af245d11STodd Fiala // This file is distributed under the University of Illinois Open Source 6af245d11STodd Fiala // License. See LICENSE.TXT for details. 7af245d11STodd Fiala // 8af245d11STodd Fiala //===----------------------------------------------------------------------===// 9af245d11STodd Fiala 10af245d11STodd Fiala #include "NativeProcessLinux.h" 11af245d11STodd Fiala 12af245d11STodd Fiala // C Includes 13af245d11STodd Fiala #include <errno.h> 14af245d11STodd Fiala #include <string.h> 15af245d11STodd Fiala #include <stdint.h> 16af245d11STodd Fiala #include <unistd.h> 17af245d11STodd Fiala 18af245d11STodd Fiala // C++ Includes 19af245d11STodd Fiala #include <fstream> 20df7c6995SPavel Labath #include <mutex> 21c076559aSPavel Labath #include <sstream> 22af245d11STodd Fiala #include <string> 235b981ab9SPavel Labath #include <unordered_map> 24af245d11STodd Fiala 25af245d11STodd Fiala // Other libraries and framework includes 26d8c338d4STamas Berghammer #include "lldb/Core/EmulateInstruction.h" 27af245d11STodd Fiala #include "lldb/Core/Error.h" 28af245d11STodd Fiala #include "lldb/Core/Module.h" 296edef204SOleksiy Vyalov #include "lldb/Core/ModuleSpec.h" 30af245d11STodd Fiala #include "lldb/Core/RegisterValue.h" 31af245d11STodd Fiala #include "lldb/Core/State.h" 321e209fccSTamas Berghammer #include "lldb/Host/common/NativeBreakpoint.h" 330cbf0b13STamas Berghammer #include "lldb/Host/common/NativeRegisterContext.h" 34af245d11STodd Fiala #include "lldb/Host/Host.h" 3539de3110SZachary Turner #include "lldb/Host/ThreadLauncher.h" 365b981ab9SPavel Labath #include "lldb/Target/Platform.h" 3790aff47cSZachary Turner #include "lldb/Target/Process.h" 38af245d11STodd Fiala #include "lldb/Target/ProcessLaunchInfo.h" 395b981ab9SPavel Labath #include "lldb/Target/Target.h" 40c16f5dcaSChaoren Lin #include "lldb/Utility/LLDBAssert.h" 41af245d11STodd Fiala #include "lldb/Utility/PseudoTerminal.h" 42f805e190SPavel Labath #include "lldb/Utility/StringExtractor.h" 43af245d11STodd Fiala 441e209fccSTamas Berghammer #include "Plugins/Process/POSIX/ProcessPOSIXLog.h" 45af245d11STodd Fiala #include "NativeThreadLinux.h" 46af245d11STodd Fiala #include "ProcFileReader.h" 471e209fccSTamas Berghammer #include "Procfs.h" 48cacde7dfSTodd Fiala 49d858487eSTamas Berghammer // System includes - They have to be included after framework includes because they define some 50d858487eSTamas Berghammer // macros which collide with variable names in other modules 51d858487eSTamas Berghammer #include <linux/unistd.h> 52d858487eSTamas Berghammer #include <sys/socket.h> 538b335671SVince Harron 54df7c6995SPavel Labath #include <sys/syscall.h> 55d858487eSTamas Berghammer #include <sys/types.h> 56d858487eSTamas Berghammer #include <sys/user.h> 57d858487eSTamas Berghammer #include <sys/wait.h> 58d858487eSTamas Berghammer 598b335671SVince Harron #include "lldb/Host/linux/Personality.h" 608b335671SVince Harron #include "lldb/Host/linux/Ptrace.h" 618b335671SVince Harron #include "lldb/Host/linux/Signalfd.h" 62df7c6995SPavel Labath #include "lldb/Host/linux/Uio.h" 638b335671SVince Harron #include "lldb/Host/android/Android.h" 64af245d11STodd Fiala 650bce1b67STodd Fiala #define LLDB_PERSONALITY_GET_CURRENT_SETTINGS 0xffffffff 66af245d11STodd Fiala 67af245d11STodd Fiala // Support hardware breakpoints in case it has not been defined 68af245d11STodd Fiala #ifndef TRAP_HWBKPT 69af245d11STodd Fiala #define TRAP_HWBKPT 4 70af245d11STodd Fiala #endif 71af245d11STodd Fiala 727cb18bf5STamas Berghammer using namespace lldb; 737cb18bf5STamas Berghammer using namespace lldb_private; 74db264a6dSTamas Berghammer using namespace lldb_private::process_linux; 757cb18bf5STamas Berghammer using namespace llvm; 767cb18bf5STamas Berghammer 77af245d11STodd Fiala // Private bits we only need internally. 78df7c6995SPavel Labath 79df7c6995SPavel Labath static bool ProcessVmReadvSupported() 80df7c6995SPavel Labath { 81df7c6995SPavel Labath static bool is_supported; 82df7c6995SPavel Labath static std::once_flag flag; 83df7c6995SPavel Labath 84df7c6995SPavel Labath std::call_once(flag, [] { 85df7c6995SPavel Labath Log *log(GetLogIfAllCategoriesSet (LIBLLDB_LOG_PROCESS)); 86df7c6995SPavel Labath 87df7c6995SPavel Labath uint32_t source = 0x47424742; 88df7c6995SPavel Labath uint32_t dest = 0; 89df7c6995SPavel Labath 90df7c6995SPavel Labath struct iovec local, remote; 91df7c6995SPavel Labath remote.iov_base = &source; 92df7c6995SPavel Labath local.iov_base = &dest; 93df7c6995SPavel Labath remote.iov_len = local.iov_len = sizeof source; 94df7c6995SPavel Labath 95df7c6995SPavel Labath // We shall try if cross-process-memory reads work by attempting to read a value from our own process. 96df7c6995SPavel Labath ssize_t res = process_vm_readv(getpid(), &local, 1, &remote, 1, 0); 97df7c6995SPavel Labath is_supported = (res == sizeof(source) && source == dest); 98df7c6995SPavel Labath if (log) 99df7c6995SPavel Labath { 100df7c6995SPavel Labath if (is_supported) 101df7c6995SPavel Labath log->Printf("%s: Detected kernel support for process_vm_readv syscall. Fast memory reads enabled.", 102df7c6995SPavel Labath __FUNCTION__); 103df7c6995SPavel Labath else 104df7c6995SPavel Labath log->Printf("%s: syscall process_vm_readv failed (error: %s). Fast memory reads disabled.", 105df7c6995SPavel Labath __FUNCTION__, strerror(errno)); 106df7c6995SPavel Labath } 107df7c6995SPavel Labath }); 108df7c6995SPavel Labath 109df7c6995SPavel Labath return is_supported; 110df7c6995SPavel Labath } 111df7c6995SPavel Labath 112af245d11STodd Fiala namespace 113af245d11STodd Fiala { 114af245d11STodd Fiala Error 115af245d11STodd Fiala ResolveProcessArchitecture (lldb::pid_t pid, Platform &platform, ArchSpec &arch) 116af245d11STodd Fiala { 117af245d11STodd Fiala // Grab process info for the running process. 118af245d11STodd Fiala ProcessInstanceInfo process_info; 119af245d11STodd Fiala if (!platform.GetProcessInfo (pid, process_info)) 120db264a6dSTamas Berghammer return Error("failed to get process info"); 121af245d11STodd Fiala 122af245d11STodd Fiala // Resolve the executable module. 123af245d11STodd Fiala ModuleSP exe_module_sp; 124e56f6dceSChaoren Lin ModuleSpec exe_module_spec(process_info.GetExecutableFile(), process_info.GetArchitecture()); 125af245d11STodd Fiala FileSpecList executable_search_paths (Target::GetDefaultExecutableSearchPaths ()); 126af245d11STodd Fiala Error error = platform.ResolveExecutable( 12754539338SOleksiy Vyalov exe_module_spec, 128af245d11STodd Fiala exe_module_sp, 129af245d11STodd Fiala executable_search_paths.GetSize () ? &executable_search_paths : NULL); 130af245d11STodd Fiala 131af245d11STodd Fiala if (!error.Success ()) 132af245d11STodd Fiala return error; 133af245d11STodd Fiala 134af245d11STodd Fiala // Check if we've got our architecture from the exe_module. 135af245d11STodd Fiala arch = exe_module_sp->GetArchitecture (); 136af245d11STodd Fiala if (arch.IsValid ()) 137af245d11STodd Fiala return Error(); 138af245d11STodd Fiala else 139af245d11STodd Fiala return Error("failed to retrieve a valid architecture from the exe module"); 140af245d11STodd Fiala } 141af245d11STodd Fiala 142af245d11STodd Fiala void 143db264a6dSTamas Berghammer DisplayBytes (StreamString &s, void *bytes, uint32_t count) 144af245d11STodd Fiala { 145af245d11STodd Fiala uint8_t *ptr = (uint8_t *)bytes; 146af245d11STodd Fiala const uint32_t loop_count = std::min<uint32_t>(DEBUG_PTRACE_MAXBYTES, count); 147af245d11STodd Fiala for(uint32_t i=0; i<loop_count; i++) 148af245d11STodd Fiala { 149af245d11STodd Fiala s.Printf ("[%x]", *ptr); 150af245d11STodd Fiala ptr++; 151af245d11STodd Fiala } 152af245d11STodd Fiala } 153af245d11STodd Fiala 154af245d11STodd Fiala void 155af245d11STodd Fiala PtraceDisplayBytes(int &req, void *data, size_t data_size) 156af245d11STodd Fiala { 157af245d11STodd Fiala StreamString buf; 158af245d11STodd Fiala Log *verbose_log (ProcessPOSIXLog::GetLogIfAllCategoriesSet ( 159af245d11STodd Fiala POSIX_LOG_PTRACE | POSIX_LOG_VERBOSE)); 160af245d11STodd Fiala 161af245d11STodd Fiala if (verbose_log) 162af245d11STodd Fiala { 163af245d11STodd Fiala switch(req) 164af245d11STodd Fiala { 165af245d11STodd Fiala case PTRACE_POKETEXT: 166af245d11STodd Fiala { 167af245d11STodd Fiala DisplayBytes(buf, &data, 8); 168af245d11STodd Fiala verbose_log->Printf("PTRACE_POKETEXT %s", buf.GetData()); 169af245d11STodd Fiala break; 170af245d11STodd Fiala } 171af245d11STodd Fiala case PTRACE_POKEDATA: 172af245d11STodd Fiala { 173af245d11STodd Fiala DisplayBytes(buf, &data, 8); 174af245d11STodd Fiala verbose_log->Printf("PTRACE_POKEDATA %s", buf.GetData()); 175af245d11STodd Fiala break; 176af245d11STodd Fiala } 177af245d11STodd Fiala case PTRACE_POKEUSER: 178af245d11STodd Fiala { 179af245d11STodd Fiala DisplayBytes(buf, &data, 8); 180af245d11STodd Fiala verbose_log->Printf("PTRACE_POKEUSER %s", buf.GetData()); 181af245d11STodd Fiala break; 182af245d11STodd Fiala } 183af245d11STodd Fiala case PTRACE_SETREGS: 184af245d11STodd Fiala { 185af245d11STodd Fiala DisplayBytes(buf, data, data_size); 186af245d11STodd Fiala verbose_log->Printf("PTRACE_SETREGS %s", buf.GetData()); 187af245d11STodd Fiala break; 188af245d11STodd Fiala } 189af245d11STodd Fiala case PTRACE_SETFPREGS: 190af245d11STodd Fiala { 191af245d11STodd Fiala DisplayBytes(buf, data, data_size); 192af245d11STodd Fiala verbose_log->Printf("PTRACE_SETFPREGS %s", buf.GetData()); 193af245d11STodd Fiala break; 194af245d11STodd Fiala } 195af245d11STodd Fiala case PTRACE_SETSIGINFO: 196af245d11STodd Fiala { 197af245d11STodd Fiala DisplayBytes(buf, data, sizeof(siginfo_t)); 198af245d11STodd Fiala verbose_log->Printf("PTRACE_SETSIGINFO %s", buf.GetData()); 199af245d11STodd Fiala break; 200af245d11STodd Fiala } 201af245d11STodd Fiala case PTRACE_SETREGSET: 202af245d11STodd Fiala { 203af245d11STodd Fiala // Extract iov_base from data, which is a pointer to the struct IOVEC 204af245d11STodd Fiala DisplayBytes(buf, *(void **)data, data_size); 205af245d11STodd Fiala verbose_log->Printf("PTRACE_SETREGSET %s", buf.GetData()); 206af245d11STodd Fiala break; 207af245d11STodd Fiala } 208af245d11STodd Fiala default: 209af245d11STodd Fiala { 210af245d11STodd Fiala } 211af245d11STodd Fiala } 212af245d11STodd Fiala } 213af245d11STodd Fiala } 214af245d11STodd Fiala 21519cbe96aSPavel Labath static constexpr unsigned k_ptrace_word_size = sizeof(void*); 21619cbe96aSPavel Labath static_assert(sizeof(long) >= k_ptrace_word_size, "Size of long must be larger than ptrace word size"); 2171107b5a5SPavel Labath } // end of anonymous namespace 2181107b5a5SPavel Labath 219bd7cbc5aSPavel Labath // Simple helper function to ensure flags are enabled on the given file 220bd7cbc5aSPavel Labath // descriptor. 221bd7cbc5aSPavel Labath static Error 222bd7cbc5aSPavel Labath EnsureFDFlags(int fd, int flags) 223bd7cbc5aSPavel Labath { 224bd7cbc5aSPavel Labath Error error; 225bd7cbc5aSPavel Labath 226bd7cbc5aSPavel Labath int status = fcntl(fd, F_GETFL); 227bd7cbc5aSPavel Labath if (status == -1) 228bd7cbc5aSPavel Labath { 229bd7cbc5aSPavel Labath error.SetErrorToErrno(); 230bd7cbc5aSPavel Labath return error; 231bd7cbc5aSPavel Labath } 232bd7cbc5aSPavel Labath 233bd7cbc5aSPavel Labath if (fcntl(fd, F_SETFL, status | flags) == -1) 234bd7cbc5aSPavel Labath { 235bd7cbc5aSPavel Labath error.SetErrorToErrno(); 236bd7cbc5aSPavel Labath return error; 237bd7cbc5aSPavel Labath } 238bd7cbc5aSPavel Labath 239bd7cbc5aSPavel Labath return error; 240bd7cbc5aSPavel Labath } 241bd7cbc5aSPavel Labath 242bd7cbc5aSPavel Labath NativeProcessLinux::LaunchArgs::LaunchArgs(Module *module, 243af245d11STodd Fiala char const **argv, 244af245d11STodd Fiala char const **envp, 245d3173f34SChaoren Lin const FileSpec &stdin_file_spec, 246d3173f34SChaoren Lin const FileSpec &stdout_file_spec, 247d3173f34SChaoren Lin const FileSpec &stderr_file_spec, 248d3173f34SChaoren Lin const FileSpec &working_dir, 249db264a6dSTamas Berghammer const ProcessLaunchInfo &launch_info) 250bd7cbc5aSPavel Labath : m_module(module), 251af245d11STodd Fiala m_argv(argv), 252af245d11STodd Fiala m_envp(envp), 253d3173f34SChaoren Lin m_stdin_file_spec(stdin_file_spec), 254d3173f34SChaoren Lin m_stdout_file_spec(stdout_file_spec), 255d3173f34SChaoren Lin m_stderr_file_spec(stderr_file_spec), 2560bce1b67STodd Fiala m_working_dir(working_dir), 2570bce1b67STodd Fiala m_launch_info(launch_info) 2580bce1b67STodd Fiala { 2590bce1b67STodd Fiala } 260af245d11STodd Fiala 261af245d11STodd Fiala NativeProcessLinux::LaunchArgs::~LaunchArgs() 262af245d11STodd Fiala { } 263af245d11STodd Fiala 264af245d11STodd Fiala // ----------------------------------------------------------------------------- 265af245d11STodd Fiala // Public Static Methods 266af245d11STodd Fiala // ----------------------------------------------------------------------------- 267af245d11STodd Fiala 268db264a6dSTamas Berghammer Error 269d5b310f2SPavel Labath NativeProcessProtocol::Launch ( 270db264a6dSTamas Berghammer ProcessLaunchInfo &launch_info, 271db264a6dSTamas Berghammer NativeProcessProtocol::NativeDelegate &native_delegate, 27219cbe96aSPavel Labath MainLoop &mainloop, 273af245d11STodd Fiala NativeProcessProtocolSP &native_process_sp) 274af245d11STodd Fiala { 275af245d11STodd Fiala Log *log (GetLogIfAllCategoriesSet (LIBLLDB_LOG_PROCESS)); 276af245d11STodd Fiala 277d5b310f2SPavel Labath lldb::ModuleSP exe_module_sp; 278d5b310f2SPavel Labath PlatformSP platform_sp (Platform::GetHostPlatform ()); 279d5b310f2SPavel Labath Error error = platform_sp->ResolveExecutable( 280d5b310f2SPavel Labath ModuleSpec(launch_info.GetExecutableFile(), launch_info.GetArchitecture()), 281d5b310f2SPavel Labath exe_module_sp, 282d5b310f2SPavel Labath nullptr); 283d5b310f2SPavel Labath 284d5b310f2SPavel Labath if (! error.Success()) 285d5b310f2SPavel Labath return error; 286af245d11STodd Fiala 287af245d11STodd Fiala // Verify the working directory is valid if one was specified. 288d3173f34SChaoren Lin FileSpec working_dir{launch_info.GetWorkingDirectory()}; 289d3173f34SChaoren Lin if (working_dir && 290d3173f34SChaoren Lin (!working_dir.ResolvePath() || 291d3173f34SChaoren Lin working_dir.GetFileType() != FileSpec::eFileTypeDirectory)) 292af245d11STodd Fiala { 293d3173f34SChaoren Lin error.SetErrorStringWithFormat ("No such file or directory: %s", 294d3173f34SChaoren Lin working_dir.GetCString()); 295af245d11STodd Fiala return error; 296af245d11STodd Fiala } 297af245d11STodd Fiala 298db264a6dSTamas Berghammer const FileAction *file_action; 299af245d11STodd Fiala 300d3173f34SChaoren Lin // Default of empty will mean to use existing open file descriptors. 301d3173f34SChaoren Lin FileSpec stdin_file_spec{}; 302d3173f34SChaoren Lin FileSpec stdout_file_spec{}; 303d3173f34SChaoren Lin FileSpec stderr_file_spec{}; 304af245d11STodd Fiala 305af245d11STodd Fiala file_action = launch_info.GetFileActionForFD (STDIN_FILENO); 30675f47c3aSTodd Fiala if (file_action) 307d3173f34SChaoren Lin stdin_file_spec = file_action->GetFileSpec(); 308af245d11STodd Fiala 309af245d11STodd Fiala file_action = launch_info.GetFileActionForFD (STDOUT_FILENO); 31075f47c3aSTodd Fiala if (file_action) 311d3173f34SChaoren Lin stdout_file_spec = file_action->GetFileSpec(); 312af245d11STodd Fiala 313af245d11STodd Fiala file_action = launch_info.GetFileActionForFD (STDERR_FILENO); 31475f47c3aSTodd Fiala if (file_action) 315d3173f34SChaoren Lin stderr_file_spec = file_action->GetFileSpec(); 31675f47c3aSTodd Fiala 31775f47c3aSTodd Fiala if (log) 31875f47c3aSTodd Fiala { 319d3173f34SChaoren Lin if (stdin_file_spec) 320d3173f34SChaoren Lin log->Printf ("NativeProcessLinux::%s setting STDIN to '%s'", 321d3173f34SChaoren Lin __FUNCTION__, stdin_file_spec.GetCString()); 32275f47c3aSTodd Fiala else 32375f47c3aSTodd Fiala log->Printf ("NativeProcessLinux::%s leaving STDIN as is", __FUNCTION__); 32475f47c3aSTodd Fiala 325d3173f34SChaoren Lin if (stdout_file_spec) 326d3173f34SChaoren Lin log->Printf ("NativeProcessLinux::%s setting STDOUT to '%s'", 327d3173f34SChaoren Lin __FUNCTION__, stdout_file_spec.GetCString()); 32875f47c3aSTodd Fiala else 32975f47c3aSTodd Fiala log->Printf ("NativeProcessLinux::%s leaving STDOUT as is", __FUNCTION__); 33075f47c3aSTodd Fiala 331d3173f34SChaoren Lin if (stderr_file_spec) 332d3173f34SChaoren Lin log->Printf ("NativeProcessLinux::%s setting STDERR to '%s'", 333d3173f34SChaoren Lin __FUNCTION__, stderr_file_spec.GetCString()); 33475f47c3aSTodd Fiala else 33575f47c3aSTodd Fiala log->Printf ("NativeProcessLinux::%s leaving STDERR as is", __FUNCTION__); 33675f47c3aSTodd Fiala } 337af245d11STodd Fiala 338af245d11STodd Fiala // Create the NativeProcessLinux in launch mode. 339af245d11STodd Fiala native_process_sp.reset (new NativeProcessLinux ()); 340af245d11STodd Fiala 341af245d11STodd Fiala if (log) 342af245d11STodd Fiala { 343af245d11STodd Fiala int i = 0; 344af245d11STodd Fiala for (const char **args = launch_info.GetArguments ().GetConstArgumentVector (); *args; ++args, ++i) 345af245d11STodd Fiala { 346af245d11STodd Fiala log->Printf ("NativeProcessLinux::%s arg %d: \"%s\"", __FUNCTION__, i, *args ? *args : "nullptr"); 347af245d11STodd Fiala ++i; 348af245d11STodd Fiala } 349af245d11STodd Fiala } 350af245d11STodd Fiala 351af245d11STodd Fiala if (!native_process_sp->RegisterNativeDelegate (native_delegate)) 352af245d11STodd Fiala { 353af245d11STodd Fiala native_process_sp.reset (); 354af245d11STodd Fiala error.SetErrorStringWithFormat ("failed to register the native delegate"); 355af245d11STodd Fiala return error; 356af245d11STodd Fiala } 357af245d11STodd Fiala 358cb84eebbSTamas Berghammer std::static_pointer_cast<NativeProcessLinux> (native_process_sp)->LaunchInferior ( 35919cbe96aSPavel Labath mainloop, 360d5b310f2SPavel Labath exe_module_sp.get(), 361af245d11STodd Fiala launch_info.GetArguments ().GetConstArgumentVector (), 362af245d11STodd Fiala launch_info.GetEnvironmentEntries ().GetConstArgumentVector (), 363d3173f34SChaoren Lin stdin_file_spec, 364d3173f34SChaoren Lin stdout_file_spec, 365d3173f34SChaoren Lin stderr_file_spec, 366af245d11STodd Fiala working_dir, 3670bce1b67STodd Fiala launch_info, 368af245d11STodd Fiala error); 369af245d11STodd Fiala 370af245d11STodd Fiala if (error.Fail ()) 371af245d11STodd Fiala { 372af245d11STodd Fiala native_process_sp.reset (); 373af245d11STodd Fiala if (log) 374af245d11STodd Fiala log->Printf ("NativeProcessLinux::%s failed to launch process: %s", __FUNCTION__, error.AsCString ()); 375af245d11STodd Fiala return error; 376af245d11STodd Fiala } 377af245d11STodd Fiala 378af245d11STodd Fiala launch_info.SetProcessID (native_process_sp->GetID ()); 379af245d11STodd Fiala 380af245d11STodd Fiala return error; 381af245d11STodd Fiala } 382af245d11STodd Fiala 383db264a6dSTamas Berghammer Error 384d5b310f2SPavel Labath NativeProcessProtocol::Attach ( 385af245d11STodd Fiala lldb::pid_t pid, 386db264a6dSTamas Berghammer NativeProcessProtocol::NativeDelegate &native_delegate, 38719cbe96aSPavel Labath MainLoop &mainloop, 388af245d11STodd Fiala NativeProcessProtocolSP &native_process_sp) 389af245d11STodd Fiala { 390af245d11STodd Fiala Log *log (GetLogIfAllCategoriesSet (LIBLLDB_LOG_PROCESS)); 391af245d11STodd Fiala if (log && log->GetMask ().Test (POSIX_LOG_VERBOSE)) 392af245d11STodd Fiala log->Printf ("NativeProcessLinux::%s(pid = %" PRIi64 ")", __FUNCTION__, pid); 393af245d11STodd Fiala 394af245d11STodd Fiala // Grab the current platform architecture. This should be Linux, 395af245d11STodd Fiala // since this code is only intended to run on a Linux host. 396615eb7e6SGreg Clayton PlatformSP platform_sp (Platform::GetHostPlatform ()); 397af245d11STodd Fiala if (!platform_sp) 398af245d11STodd Fiala return Error("failed to get a valid default platform"); 399af245d11STodd Fiala 400af245d11STodd Fiala // Retrieve the architecture for the running process. 401af245d11STodd Fiala ArchSpec process_arch; 402af245d11STodd Fiala Error error = ResolveProcessArchitecture (pid, *platform_sp.get (), process_arch); 403af245d11STodd Fiala if (!error.Success ()) 404af245d11STodd Fiala return error; 405af245d11STodd Fiala 4061339b5e8SOleksiy Vyalov std::shared_ptr<NativeProcessLinux> native_process_linux_sp (new NativeProcessLinux ()); 407af245d11STodd Fiala 4081339b5e8SOleksiy Vyalov if (!native_process_linux_sp->RegisterNativeDelegate (native_delegate)) 409af245d11STodd Fiala { 410af245d11STodd Fiala error.SetErrorStringWithFormat ("failed to register the native delegate"); 411af245d11STodd Fiala return error; 412af245d11STodd Fiala } 413af245d11STodd Fiala 41419cbe96aSPavel Labath native_process_linux_sp->AttachToInferior (mainloop, pid, error); 415af245d11STodd Fiala if (!error.Success ()) 416af245d11STodd Fiala return error; 417af245d11STodd Fiala 4181339b5e8SOleksiy Vyalov native_process_sp = native_process_linux_sp; 419af245d11STodd Fiala return error; 420af245d11STodd Fiala } 421af245d11STodd Fiala 422af245d11STodd Fiala // ----------------------------------------------------------------------------- 423af245d11STodd Fiala // Public Instance Methods 424af245d11STodd Fiala // ----------------------------------------------------------------------------- 425af245d11STodd Fiala 426af245d11STodd Fiala NativeProcessLinux::NativeProcessLinux () : 427af245d11STodd Fiala NativeProcessProtocol (LLDB_INVALID_PROCESS_ID), 428af245d11STodd Fiala m_arch (), 429af245d11STodd Fiala m_supports_mem_region (eLazyBoolCalculate), 430af245d11STodd Fiala m_mem_region_cache (), 431*0e1d729bSPavel Labath m_mem_region_cache_mutex(), 432*0e1d729bSPavel Labath m_pending_notification_tid(LLDB_INVALID_THREAD_ID) 433af245d11STodd Fiala { 434af245d11STodd Fiala } 435af245d11STodd Fiala 436af245d11STodd Fiala void 437af245d11STodd Fiala NativeProcessLinux::LaunchInferior ( 43819cbe96aSPavel Labath MainLoop &mainloop, 439af245d11STodd Fiala Module *module, 440af245d11STodd Fiala const char *argv[], 441af245d11STodd Fiala const char *envp[], 442d3173f34SChaoren Lin const FileSpec &stdin_file_spec, 443d3173f34SChaoren Lin const FileSpec &stdout_file_spec, 444d3173f34SChaoren Lin const FileSpec &stderr_file_spec, 445d3173f34SChaoren Lin const FileSpec &working_dir, 446db264a6dSTamas Berghammer const ProcessLaunchInfo &launch_info, 447db264a6dSTamas Berghammer Error &error) 448af245d11STodd Fiala { 44919cbe96aSPavel Labath m_sigchld_handle = mainloop.RegisterSignal(SIGCHLD, 45019cbe96aSPavel Labath [this] (MainLoopBase &) { SigchldHandler(); }, error); 45119cbe96aSPavel Labath if (! m_sigchld_handle) 45219cbe96aSPavel Labath return; 45319cbe96aSPavel Labath 454af245d11STodd Fiala if (module) 455af245d11STodd Fiala m_arch = module->GetArchitecture (); 456af245d11STodd Fiala 457af245d11STodd Fiala SetState (eStateLaunching); 458af245d11STodd Fiala 459af245d11STodd Fiala std::unique_ptr<LaunchArgs> args( 460d3173f34SChaoren Lin new LaunchArgs(module, argv, envp, 461d3173f34SChaoren Lin stdin_file_spec, 462d3173f34SChaoren Lin stdout_file_spec, 463d3173f34SChaoren Lin stderr_file_spec, 464d3173f34SChaoren Lin working_dir, 465d3173f34SChaoren Lin launch_info)); 466af245d11STodd Fiala 46719cbe96aSPavel Labath Launch(args.get(), error); 468af245d11STodd Fiala } 469af245d11STodd Fiala 470af245d11STodd Fiala void 47119cbe96aSPavel Labath NativeProcessLinux::AttachToInferior (MainLoop &mainloop, lldb::pid_t pid, Error &error) 472af245d11STodd Fiala { 473af245d11STodd Fiala Log *log (GetLogIfAllCategoriesSet (LIBLLDB_LOG_PROCESS)); 474af245d11STodd Fiala if (log) 475af245d11STodd Fiala log->Printf ("NativeProcessLinux::%s (pid = %" PRIi64 ")", __FUNCTION__, pid); 476af245d11STodd Fiala 47719cbe96aSPavel Labath m_sigchld_handle = mainloop.RegisterSignal(SIGCHLD, 47819cbe96aSPavel Labath [this] (MainLoopBase &) { SigchldHandler(); }, error); 47919cbe96aSPavel Labath if (! m_sigchld_handle) 48019cbe96aSPavel Labath return; 48119cbe96aSPavel Labath 482af245d11STodd Fiala // We can use the Host for everything except the ResolveExecutable portion. 483615eb7e6SGreg Clayton PlatformSP platform_sp = Platform::GetHostPlatform (); 484af245d11STodd Fiala if (!platform_sp) 485af245d11STodd Fiala { 486af245d11STodd Fiala if (log) 487af245d11STodd Fiala log->Printf ("NativeProcessLinux::%s (pid = %" PRIi64 "): no default platform set", __FUNCTION__, pid); 488af245d11STodd Fiala error.SetErrorString ("no default platform available"); 48950d60be3SShawn Best return; 490af245d11STodd Fiala } 491af245d11STodd Fiala 492af245d11STodd Fiala // Gather info about the process. 493af245d11STodd Fiala ProcessInstanceInfo process_info; 49450d60be3SShawn Best if (!platform_sp->GetProcessInfo (pid, process_info)) 49550d60be3SShawn Best { 49650d60be3SShawn Best if (log) 49750d60be3SShawn Best log->Printf ("NativeProcessLinux::%s (pid = %" PRIi64 "): failed to get process info", __FUNCTION__, pid); 49850d60be3SShawn Best error.SetErrorString ("failed to get process info"); 49950d60be3SShawn Best return; 50050d60be3SShawn Best } 501af245d11STodd Fiala 502af245d11STodd Fiala // Resolve the executable module 503af245d11STodd Fiala ModuleSP exe_module_sp; 504af245d11STodd Fiala FileSpecList executable_search_paths (Target::GetDefaultExecutableSearchPaths()); 505e56f6dceSChaoren Lin ModuleSpec exe_module_spec(process_info.GetExecutableFile(), process_info.GetArchitecture()); 5066edef204SOleksiy Vyalov error = platform_sp->ResolveExecutable(exe_module_spec, exe_module_sp, 507af245d11STodd Fiala executable_search_paths.GetSize() ? &executable_search_paths : NULL); 508af245d11STodd Fiala if (!error.Success()) 509af245d11STodd Fiala return; 510af245d11STodd Fiala 511af245d11STodd Fiala // Set the architecture to the exe architecture. 512af245d11STodd Fiala m_arch = exe_module_sp->GetArchitecture(); 513af245d11STodd Fiala if (log) 514af245d11STodd Fiala log->Printf ("NativeProcessLinux::%s (pid = %" PRIi64 ") detected architecture %s", __FUNCTION__, pid, m_arch.GetArchitectureName ()); 515af245d11STodd Fiala 516af245d11STodd Fiala m_pid = pid; 517af245d11STodd Fiala SetState(eStateAttaching); 518af245d11STodd Fiala 51919cbe96aSPavel Labath Attach(pid, error); 520af245d11STodd Fiala } 521af245d11STodd Fiala 522bd7cbc5aSPavel Labath ::pid_t 523bd7cbc5aSPavel Labath NativeProcessLinux::Launch(LaunchArgs *args, Error &error) 524af245d11STodd Fiala { 5250bce1b67STodd Fiala assert (args && "null args"); 526af245d11STodd Fiala 527af245d11STodd Fiala const char **argv = args->m_argv; 528af245d11STodd Fiala const char **envp = args->m_envp; 529d3173f34SChaoren Lin const FileSpec working_dir = args->m_working_dir; 530af245d11STodd Fiala 531af245d11STodd Fiala lldb_utility::PseudoTerminal terminal; 532af245d11STodd Fiala const size_t err_len = 1024; 533af245d11STodd Fiala char err_str[err_len]; 534af245d11STodd Fiala lldb::pid_t pid; 535af245d11STodd Fiala NativeThreadProtocolSP thread_sp; 536af245d11STodd Fiala 537af245d11STodd Fiala lldb::ThreadSP inferior; 538af245d11STodd Fiala 539af245d11STodd Fiala // Propagate the environment if one is not supplied. 540af245d11STodd Fiala if (envp == NULL || envp[0] == NULL) 541af245d11STodd Fiala envp = const_cast<const char **>(environ); 542af245d11STodd Fiala 543af245d11STodd Fiala if ((pid = terminal.Fork(err_str, err_len)) == static_cast<lldb::pid_t> (-1)) 544af245d11STodd Fiala { 545bd7cbc5aSPavel Labath error.SetErrorToGenericError(); 546bd7cbc5aSPavel Labath error.SetErrorStringWithFormat("Process fork failed: %s", err_str); 547bd7cbc5aSPavel Labath return -1; 548af245d11STodd Fiala } 549af245d11STodd Fiala 550af245d11STodd Fiala // Recognized child exit status codes. 551af245d11STodd Fiala enum { 552af245d11STodd Fiala ePtraceFailed = 1, 553af245d11STodd Fiala eDupStdinFailed, 554af245d11STodd Fiala eDupStdoutFailed, 555af245d11STodd Fiala eDupStderrFailed, 556af245d11STodd Fiala eChdirFailed, 557af245d11STodd Fiala eExecFailed, 55878856474SPavel Labath eSetGidFailed, 55978856474SPavel Labath eSetSigMaskFailed 560af245d11STodd Fiala }; 561af245d11STodd Fiala 562af245d11STodd Fiala // Child process. 563af245d11STodd Fiala if (pid == 0) 564af245d11STodd Fiala { 565d2c4c9b1SPavel Labath // First, make sure we disable all logging. If we are logging to stdout, our logs can be 566d2c4c9b1SPavel Labath // mistaken for inferior output. 567d2c4c9b1SPavel Labath Log::DisableAllLogChannels(nullptr); 56875f47c3aSTodd Fiala // FIXME consider opening a pipe between parent/child and have this forked child 569d2c4c9b1SPavel Labath // send log info to parent re: launch status. 570af245d11STodd Fiala 57175f47c3aSTodd Fiala // Start tracing this child that is about to exec. 5724a9babb2SPavel Labath error = PtraceWrapper(PTRACE_TRACEME, 0); 573bd7cbc5aSPavel Labath if (error.Fail()) 574af245d11STodd Fiala exit(ePtraceFailed); 575af245d11STodd Fiala 576493c3a12SPavel Labath // terminal has already dupped the tty descriptors to stdin/out/err. 577493c3a12SPavel Labath // This closes original fd from which they were copied (and avoids 578493c3a12SPavel Labath // leaking descriptors to the debugged process. 579493c3a12SPavel Labath terminal.CloseSlaveFileDescriptor(); 580493c3a12SPavel Labath 581af245d11STodd Fiala // Do not inherit setgid powers. 582af245d11STodd Fiala if (setgid(getgid()) != 0) 583af245d11STodd Fiala exit(eSetGidFailed); 584af245d11STodd Fiala 585af245d11STodd Fiala // Attempt to have our own process group. 586af245d11STodd Fiala if (setpgid(0, 0) != 0) 587af245d11STodd Fiala { 58875f47c3aSTodd Fiala // FIXME log that this failed. This is common. 589af245d11STodd Fiala // Don't allow this to prevent an inferior exec. 590af245d11STodd Fiala } 591af245d11STodd Fiala 592af245d11STodd Fiala // Dup file descriptors if needed. 593d3173f34SChaoren Lin if (args->m_stdin_file_spec) 594d3173f34SChaoren Lin if (!DupDescriptor(args->m_stdin_file_spec, STDIN_FILENO, O_RDONLY)) 595af245d11STodd Fiala exit(eDupStdinFailed); 596af245d11STodd Fiala 597d3173f34SChaoren Lin if (args->m_stdout_file_spec) 598d3173f34SChaoren Lin if (!DupDescriptor(args->m_stdout_file_spec, STDOUT_FILENO, O_WRONLY | O_CREAT | O_TRUNC)) 599af245d11STodd Fiala exit(eDupStdoutFailed); 600af245d11STodd Fiala 601d3173f34SChaoren Lin if (args->m_stderr_file_spec) 602d3173f34SChaoren Lin if (!DupDescriptor(args->m_stderr_file_spec, STDERR_FILENO, O_WRONLY | O_CREAT | O_TRUNC)) 603af245d11STodd Fiala exit(eDupStderrFailed); 604af245d11STodd Fiala 6059cf4f2c2SChaoren Lin // Close everything besides stdin, stdout, and stderr that has no file 6069cf4f2c2SChaoren Lin // action to avoid leaking 6079cf4f2c2SChaoren Lin for (int fd = 3; fd < sysconf(_SC_OPEN_MAX); ++fd) 6089cf4f2c2SChaoren Lin if (!args->m_launch_info.GetFileActionForFD(fd)) 6099cf4f2c2SChaoren Lin close(fd); 6109cf4f2c2SChaoren Lin 611af245d11STodd Fiala // Change working directory 612d3173f34SChaoren Lin if (working_dir && 0 != ::chdir(working_dir.GetCString())) 613af245d11STodd Fiala exit(eChdirFailed); 614af245d11STodd Fiala 6150bce1b67STodd Fiala // Disable ASLR if requested. 6160bce1b67STodd Fiala if (args->m_launch_info.GetFlags ().Test (lldb::eLaunchFlagDisableASLR)) 6170bce1b67STodd Fiala { 6180bce1b67STodd Fiala const int old_personality = personality (LLDB_PERSONALITY_GET_CURRENT_SETTINGS); 6190bce1b67STodd Fiala if (old_personality == -1) 6200bce1b67STodd Fiala { 62175f47c3aSTodd Fiala // Can't retrieve Linux personality. Cannot disable ASLR. 6220bce1b67STodd Fiala } 6230bce1b67STodd Fiala else 6240bce1b67STodd Fiala { 6250bce1b67STodd Fiala const int new_personality = personality (ADDR_NO_RANDOMIZE | old_personality); 6260bce1b67STodd Fiala if (new_personality == -1) 6270bce1b67STodd Fiala { 62875f47c3aSTodd Fiala // Disabling ASLR failed. 6290bce1b67STodd Fiala } 6300bce1b67STodd Fiala else 6310bce1b67STodd Fiala { 63275f47c3aSTodd Fiala // Disabling ASLR succeeded. 6330bce1b67STodd Fiala } 6340bce1b67STodd Fiala } 6350bce1b67STodd Fiala } 6360bce1b67STodd Fiala 63778856474SPavel Labath // Clear the signal mask to prevent the child from being affected by 63878856474SPavel Labath // any masking done by the parent. 63978856474SPavel Labath sigset_t set; 64078856474SPavel Labath if (sigemptyset(&set) != 0 || pthread_sigmask(SIG_SETMASK, &set, nullptr) != 0) 64178856474SPavel Labath exit(eSetSigMaskFailed); 64278856474SPavel Labath 64375f47c3aSTodd Fiala // Execute. We should never return... 644af245d11STodd Fiala execve(argv[0], 645af245d11STodd Fiala const_cast<char *const *>(argv), 646af245d11STodd Fiala const_cast<char *const *>(envp)); 64775f47c3aSTodd Fiala 64875f47c3aSTodd Fiala // ...unless exec fails. In which case we definitely need to end the child here. 649af245d11STodd Fiala exit(eExecFailed); 650af245d11STodd Fiala } 651af245d11STodd Fiala 65275f47c3aSTodd Fiala // 65375f47c3aSTodd Fiala // This is the parent code here. 65475f47c3aSTodd Fiala // 65575f47c3aSTodd Fiala Log *log (GetLogIfAllCategoriesSet (LIBLLDB_LOG_PROCESS)); 65675f47c3aSTodd Fiala 657af245d11STodd Fiala // Wait for the child process to trap on its call to execve. 658af245d11STodd Fiala ::pid_t wpid; 659af245d11STodd Fiala int status; 660af245d11STodd Fiala if ((wpid = waitpid(pid, &status, 0)) < 0) 661af245d11STodd Fiala { 662bd7cbc5aSPavel Labath error.SetErrorToErrno(); 663af245d11STodd Fiala if (log) 664bd7cbc5aSPavel Labath log->Printf ("NativeProcessLinux::%s waitpid for inferior failed with %s", 665bd7cbc5aSPavel Labath __FUNCTION__, error.AsCString ()); 666af245d11STodd Fiala 667af245d11STodd Fiala // Mark the inferior as invalid. 668af245d11STodd Fiala // FIXME this could really use a new state - eStateLaunchFailure. For now, using eStateInvalid. 669bd7cbc5aSPavel Labath SetState (StateType::eStateInvalid); 670af245d11STodd Fiala 671bd7cbc5aSPavel Labath return -1; 672af245d11STodd Fiala } 673af245d11STodd Fiala else if (WIFEXITED(status)) 674af245d11STodd Fiala { 675af245d11STodd Fiala // open, dup or execve likely failed for some reason. 676bd7cbc5aSPavel Labath error.SetErrorToGenericError(); 677af245d11STodd Fiala switch (WEXITSTATUS(status)) 678af245d11STodd Fiala { 679af245d11STodd Fiala case ePtraceFailed: 680bd7cbc5aSPavel Labath error.SetErrorString("Child ptrace failed."); 681af245d11STodd Fiala break; 682af245d11STodd Fiala case eDupStdinFailed: 683bd7cbc5aSPavel Labath error.SetErrorString("Child open stdin failed."); 684af245d11STodd Fiala break; 685af245d11STodd Fiala case eDupStdoutFailed: 686bd7cbc5aSPavel Labath error.SetErrorString("Child open stdout failed."); 687af245d11STodd Fiala break; 688af245d11STodd Fiala case eDupStderrFailed: 689bd7cbc5aSPavel Labath error.SetErrorString("Child open stderr failed."); 690af245d11STodd Fiala break; 691af245d11STodd Fiala case eChdirFailed: 692bd7cbc5aSPavel Labath error.SetErrorString("Child failed to set working directory."); 693af245d11STodd Fiala break; 694af245d11STodd Fiala case eExecFailed: 695bd7cbc5aSPavel Labath error.SetErrorString("Child exec failed."); 696af245d11STodd Fiala break; 697af245d11STodd Fiala case eSetGidFailed: 698bd7cbc5aSPavel Labath error.SetErrorString("Child setgid failed."); 699af245d11STodd Fiala break; 70078856474SPavel Labath case eSetSigMaskFailed: 70178856474SPavel Labath error.SetErrorString("Child failed to set signal mask."); 70278856474SPavel Labath break; 703af245d11STodd Fiala default: 704bd7cbc5aSPavel Labath error.SetErrorString("Child returned unknown exit status."); 705af245d11STodd Fiala break; 706af245d11STodd Fiala } 707af245d11STodd Fiala 708af245d11STodd Fiala if (log) 709af245d11STodd Fiala { 710af245d11STodd Fiala log->Printf ("NativeProcessLinux::%s inferior exited with status %d before issuing a STOP", 711af245d11STodd Fiala __FUNCTION__, 712af245d11STodd Fiala WEXITSTATUS(status)); 713af245d11STodd Fiala } 714af245d11STodd Fiala 715af245d11STodd Fiala // Mark the inferior as invalid. 716af245d11STodd Fiala // FIXME this could really use a new state - eStateLaunchFailure. For now, using eStateInvalid. 717bd7cbc5aSPavel Labath SetState (StateType::eStateInvalid); 718af245d11STodd Fiala 719bd7cbc5aSPavel Labath return -1; 720af245d11STodd Fiala } 721af245d11STodd Fiala assert(WIFSTOPPED(status) && (wpid == static_cast< ::pid_t> (pid)) && 722af245d11STodd Fiala "Could not sync with inferior process."); 723af245d11STodd Fiala 724af245d11STodd Fiala if (log) 725af245d11STodd Fiala log->Printf ("NativeProcessLinux::%s inferior started, now in stopped state", __FUNCTION__); 726af245d11STodd Fiala 727bd7cbc5aSPavel Labath error = SetDefaultPtraceOpts(pid); 728bd7cbc5aSPavel Labath if (error.Fail()) 729af245d11STodd Fiala { 730af245d11STodd Fiala if (log) 731af245d11STodd Fiala log->Printf ("NativeProcessLinux::%s inferior failed to set default ptrace options: %s", 732bd7cbc5aSPavel Labath __FUNCTION__, error.AsCString ()); 733af245d11STodd Fiala 734af245d11STodd Fiala // Mark the inferior as invalid. 735af245d11STodd Fiala // FIXME this could really use a new state - eStateLaunchFailure. For now, using eStateInvalid. 736bd7cbc5aSPavel Labath SetState (StateType::eStateInvalid); 737af245d11STodd Fiala 738bd7cbc5aSPavel Labath return -1; 739af245d11STodd Fiala } 740af245d11STodd Fiala 741af245d11STodd Fiala // Release the master terminal descriptor and pass it off to the 742af245d11STodd Fiala // NativeProcessLinux instance. Similarly stash the inferior pid. 743bd7cbc5aSPavel Labath m_terminal_fd = terminal.ReleaseMasterFileDescriptor(); 744bd7cbc5aSPavel Labath m_pid = pid; 745af245d11STodd Fiala 746af245d11STodd Fiala // Set the terminal fd to be in non blocking mode (it simplifies the 747af245d11STodd Fiala // implementation of ProcessLinux::GetSTDOUT to have a non-blocking 748af245d11STodd Fiala // descriptor to read from). 749bd7cbc5aSPavel Labath error = EnsureFDFlags(m_terminal_fd, O_NONBLOCK); 750bd7cbc5aSPavel Labath if (error.Fail()) 751af245d11STodd Fiala { 752af245d11STodd Fiala if (log) 753af245d11STodd Fiala log->Printf ("NativeProcessLinux::%s inferior EnsureFDFlags failed for ensuring terminal O_NONBLOCK setting: %s", 754bd7cbc5aSPavel Labath __FUNCTION__, error.AsCString ()); 755af245d11STodd Fiala 756af245d11STodd Fiala // Mark the inferior as invalid. 757af245d11STodd Fiala // FIXME this could really use a new state - eStateLaunchFailure. For now, using eStateInvalid. 758bd7cbc5aSPavel Labath SetState (StateType::eStateInvalid); 759af245d11STodd Fiala 760bd7cbc5aSPavel Labath return -1; 761af245d11STodd Fiala } 762af245d11STodd Fiala 763af245d11STodd Fiala if (log) 764af245d11STodd Fiala log->Printf ("NativeProcessLinux::%s() adding pid = %" PRIu64, __FUNCTION__, pid); 765af245d11STodd Fiala 766bd7cbc5aSPavel Labath thread_sp = AddThread (pid); 767af245d11STodd Fiala assert (thread_sp && "AddThread() returned a nullptr thread"); 768cb84eebbSTamas Berghammer std::static_pointer_cast<NativeThreadLinux> (thread_sp)->SetStoppedBySignal (SIGSTOP); 7691dbc6c9cSPavel Labath ThreadWasCreated(pid); 770af245d11STodd Fiala 771af245d11STodd Fiala // Let our process instance know the thread has stopped. 772bd7cbc5aSPavel Labath SetCurrentThreadID (thread_sp->GetID ()); 773bd7cbc5aSPavel Labath SetState (StateType::eStateStopped); 774af245d11STodd Fiala 775af245d11STodd Fiala if (log) 776af245d11STodd Fiala { 777bd7cbc5aSPavel Labath if (error.Success ()) 778af245d11STodd Fiala { 779af245d11STodd Fiala log->Printf ("NativeProcessLinux::%s inferior launching succeeded", __FUNCTION__); 780af245d11STodd Fiala } 781af245d11STodd Fiala else 782af245d11STodd Fiala { 783af245d11STodd Fiala log->Printf ("NativeProcessLinux::%s inferior launching failed: %s", 784bd7cbc5aSPavel Labath __FUNCTION__, error.AsCString ()); 785bd7cbc5aSPavel Labath return -1; 786af245d11STodd Fiala } 787af245d11STodd Fiala } 788bd7cbc5aSPavel Labath return pid; 789af245d11STodd Fiala } 790af245d11STodd Fiala 791bd7cbc5aSPavel Labath ::pid_t 792bd7cbc5aSPavel Labath NativeProcessLinux::Attach(lldb::pid_t pid, Error &error) 793af245d11STodd Fiala { 794af245d11STodd Fiala lldb::ThreadSP inferior; 795af245d11STodd Fiala Log *log (GetLogIfAllCategoriesSet (LIBLLDB_LOG_PROCESS)); 796af245d11STodd Fiala 797af245d11STodd Fiala // Use a map to keep track of the threads which we have attached/need to attach. 798af245d11STodd Fiala Host::TidMap tids_to_attach; 799af245d11STodd Fiala if (pid <= 1) 800af245d11STodd Fiala { 801bd7cbc5aSPavel Labath error.SetErrorToGenericError(); 802bd7cbc5aSPavel Labath error.SetErrorString("Attaching to process 1 is not allowed."); 803bd7cbc5aSPavel Labath return -1; 804af245d11STodd Fiala } 805af245d11STodd Fiala 806af245d11STodd Fiala while (Host::FindProcessThreads(pid, tids_to_attach)) 807af245d11STodd Fiala { 808af245d11STodd Fiala for (Host::TidMap::iterator it = tids_to_attach.begin(); 809af245d11STodd Fiala it != tids_to_attach.end();) 810af245d11STodd Fiala { 811af245d11STodd Fiala if (it->second == false) 812af245d11STodd Fiala { 813af245d11STodd Fiala lldb::tid_t tid = it->first; 814af245d11STodd Fiala 815af245d11STodd Fiala // Attach to the requested process. 816af245d11STodd Fiala // An attach will cause the thread to stop with a SIGSTOP. 8174a9babb2SPavel Labath error = PtraceWrapper(PTRACE_ATTACH, tid); 818bd7cbc5aSPavel Labath if (error.Fail()) 819af245d11STodd Fiala { 820af245d11STodd Fiala // No such thread. The thread may have exited. 821af245d11STodd Fiala // More error handling may be needed. 822bd7cbc5aSPavel Labath if (error.GetError() == ESRCH) 823af245d11STodd Fiala { 824af245d11STodd Fiala it = tids_to_attach.erase(it); 825af245d11STodd Fiala continue; 826af245d11STodd Fiala } 827af245d11STodd Fiala else 828bd7cbc5aSPavel Labath return -1; 829af245d11STodd Fiala } 830af245d11STodd Fiala 831af245d11STodd Fiala int status; 832af245d11STodd Fiala // Need to use __WALL otherwise we receive an error with errno=ECHLD 833af245d11STodd Fiala // At this point we should have a thread stopped if waitpid succeeds. 834af245d11STodd Fiala if ((status = waitpid(tid, NULL, __WALL)) < 0) 835af245d11STodd Fiala { 836af245d11STodd Fiala // No such thread. The thread may have exited. 837af245d11STodd Fiala // More error handling may be needed. 838af245d11STodd Fiala if (errno == ESRCH) 839af245d11STodd Fiala { 840af245d11STodd Fiala it = tids_to_attach.erase(it); 841af245d11STodd Fiala continue; 842af245d11STodd Fiala } 843af245d11STodd Fiala else 844af245d11STodd Fiala { 845bd7cbc5aSPavel Labath error.SetErrorToErrno(); 846bd7cbc5aSPavel Labath return -1; 847af245d11STodd Fiala } 848af245d11STodd Fiala } 849af245d11STodd Fiala 850bd7cbc5aSPavel Labath error = SetDefaultPtraceOpts(tid); 851bd7cbc5aSPavel Labath if (error.Fail()) 852bd7cbc5aSPavel Labath return -1; 853af245d11STodd Fiala 854af245d11STodd Fiala if (log) 855af245d11STodd Fiala log->Printf ("NativeProcessLinux::%s() adding tid = %" PRIu64, __FUNCTION__, tid); 856af245d11STodd Fiala 857af245d11STodd Fiala it->second = true; 858af245d11STodd Fiala 859af245d11STodd Fiala // Create the thread, mark it as stopped. 860bd7cbc5aSPavel Labath NativeThreadProtocolSP thread_sp (AddThread (static_cast<lldb::tid_t> (tid))); 861af245d11STodd Fiala assert (thread_sp && "AddThread() returned a nullptr"); 862fa03ad2eSChaoren Lin 863fa03ad2eSChaoren Lin // This will notify this is a new thread and tell the system it is stopped. 864cb84eebbSTamas Berghammer std::static_pointer_cast<NativeThreadLinux> (thread_sp)->SetStoppedBySignal (SIGSTOP); 8651dbc6c9cSPavel Labath ThreadWasCreated(tid); 866bd7cbc5aSPavel Labath SetCurrentThreadID (thread_sp->GetID ()); 867af245d11STodd Fiala } 868af245d11STodd Fiala 869af245d11STodd Fiala // move the loop forward 870af245d11STodd Fiala ++it; 871af245d11STodd Fiala } 872af245d11STodd Fiala } 873af245d11STodd Fiala 874af245d11STodd Fiala if (tids_to_attach.size() > 0) 875af245d11STodd Fiala { 876bd7cbc5aSPavel Labath m_pid = pid; 877af245d11STodd Fiala // Let our process instance know the thread has stopped. 878bd7cbc5aSPavel Labath SetState (StateType::eStateStopped); 879af245d11STodd Fiala } 880af245d11STodd Fiala else 881af245d11STodd Fiala { 882bd7cbc5aSPavel Labath error.SetErrorToGenericError(); 883bd7cbc5aSPavel Labath error.SetErrorString("No such process."); 884bd7cbc5aSPavel Labath return -1; 885af245d11STodd Fiala } 886af245d11STodd Fiala 887bd7cbc5aSPavel Labath return pid; 888af245d11STodd Fiala } 889af245d11STodd Fiala 89097ccc294SChaoren Lin Error 891af245d11STodd Fiala NativeProcessLinux::SetDefaultPtraceOpts(lldb::pid_t pid) 892af245d11STodd Fiala { 893af245d11STodd Fiala long ptrace_opts = 0; 894af245d11STodd Fiala 895af245d11STodd Fiala // Have the child raise an event on exit. This is used to keep the child in 896af245d11STodd Fiala // limbo until it is destroyed. 897af245d11STodd Fiala ptrace_opts |= PTRACE_O_TRACEEXIT; 898af245d11STodd Fiala 899af245d11STodd Fiala // Have the tracer trace threads which spawn in the inferior process. 900af245d11STodd Fiala // TODO: if we want to support tracing the inferiors' child, add the 901af245d11STodd Fiala // appropriate ptrace flags here (PTRACE_O_TRACEFORK, PTRACE_O_TRACEVFORK) 902af245d11STodd Fiala ptrace_opts |= PTRACE_O_TRACECLONE; 903af245d11STodd Fiala 904af245d11STodd Fiala // Have the tracer notify us before execve returns 905af245d11STodd Fiala // (needed to disable legacy SIGTRAP generation) 906af245d11STodd Fiala ptrace_opts |= PTRACE_O_TRACEEXEC; 907af245d11STodd Fiala 9084a9babb2SPavel Labath return PtraceWrapper(PTRACE_SETOPTIONS, pid, nullptr, (void*)ptrace_opts); 909af245d11STodd Fiala } 910af245d11STodd Fiala 911af245d11STodd Fiala static ExitType convert_pid_status_to_exit_type (int status) 912af245d11STodd Fiala { 913af245d11STodd Fiala if (WIFEXITED (status)) 914af245d11STodd Fiala return ExitType::eExitTypeExit; 915af245d11STodd Fiala else if (WIFSIGNALED (status)) 916af245d11STodd Fiala return ExitType::eExitTypeSignal; 917af245d11STodd Fiala else if (WIFSTOPPED (status)) 918af245d11STodd Fiala return ExitType::eExitTypeStop; 919af245d11STodd Fiala else 920af245d11STodd Fiala { 921af245d11STodd Fiala // We don't know what this is. 922af245d11STodd Fiala return ExitType::eExitTypeInvalid; 923af245d11STodd Fiala } 924af245d11STodd Fiala } 925af245d11STodd Fiala 926af245d11STodd Fiala static int convert_pid_status_to_return_code (int status) 927af245d11STodd Fiala { 928af245d11STodd Fiala if (WIFEXITED (status)) 929af245d11STodd Fiala return WEXITSTATUS (status); 930af245d11STodd Fiala else if (WIFSIGNALED (status)) 931af245d11STodd Fiala return WTERMSIG (status); 932af245d11STodd Fiala else if (WIFSTOPPED (status)) 933af245d11STodd Fiala return WSTOPSIG (status); 934af245d11STodd Fiala else 935af245d11STodd Fiala { 936af245d11STodd Fiala // We don't know what this is. 937af245d11STodd Fiala return ExitType::eExitTypeInvalid; 938af245d11STodd Fiala } 939af245d11STodd Fiala } 940af245d11STodd Fiala 9411107b5a5SPavel Labath // Handles all waitpid events from the inferior process. 9421107b5a5SPavel Labath void 9431107b5a5SPavel Labath NativeProcessLinux::MonitorCallback(lldb::pid_t pid, 944af245d11STodd Fiala bool exited, 945af245d11STodd Fiala int signal, 946af245d11STodd Fiala int status) 947af245d11STodd Fiala { 948af245d11STodd Fiala Log *log (GetLogIfAnyCategoriesSet (LIBLLDB_LOG_PROCESS)); 949af245d11STodd Fiala 950af245d11STodd Fiala // Certain activities differ based on whether the pid is the tid of the main thread. 9511107b5a5SPavel Labath const bool is_main_thread = (pid == GetID ()); 952af245d11STodd Fiala 953af245d11STodd Fiala // Handle when the thread exits. 954af245d11STodd Fiala if (exited) 955af245d11STodd Fiala { 956af245d11STodd Fiala if (log) 95786fd8e45SChaoren Lin log->Printf ("NativeProcessLinux::%s() got exit signal(%d) , tid = %" PRIu64 " (%s main thread)", __FUNCTION__, signal, pid, is_main_thread ? "is" : "is not"); 958af245d11STodd Fiala 959af245d11STodd Fiala // This is a thread that exited. Ensure we're not tracking it anymore. 9601107b5a5SPavel Labath const bool thread_found = StopTrackingThread (pid); 961af245d11STodd Fiala 962af245d11STodd Fiala if (is_main_thread) 963af245d11STodd Fiala { 964af245d11STodd Fiala // We only set the exit status and notify the delegate if we haven't already set the process 965af245d11STodd Fiala // state to an exited state. We normally should have received a SIGTRAP | (PTRACE_EVENT_EXIT << 8) 966af245d11STodd Fiala // for the main thread. 9671107b5a5SPavel Labath const bool already_notified = (GetState() == StateType::eStateExited) || (GetState () == StateType::eStateCrashed); 968af245d11STodd Fiala if (!already_notified) 969af245d11STodd Fiala { 970af245d11STodd Fiala if (log) 9711107b5a5SPavel Labath log->Printf ("NativeProcessLinux::%s() tid = %" PRIu64 " handling main thread exit (%s), expected exit state already set but state was %s instead, setting exit state now", __FUNCTION__, pid, thread_found ? "stopped tracking thread metadata" : "thread metadata not found", StateAsCString (GetState ())); 972af245d11STodd Fiala // The main thread exited. We're done monitoring. Report to delegate. 9731107b5a5SPavel Labath SetExitStatus (convert_pid_status_to_exit_type (status), convert_pid_status_to_return_code (status), nullptr, true); 974af245d11STodd Fiala 975af245d11STodd Fiala // Notify delegate that our process has exited. 9761107b5a5SPavel Labath SetState (StateType::eStateExited, true); 977af245d11STodd Fiala } 978af245d11STodd Fiala else 979af245d11STodd Fiala { 980af245d11STodd Fiala if (log) 981af245d11STodd Fiala log->Printf ("NativeProcessLinux::%s() tid = %" PRIu64 " main thread now exited (%s)", __FUNCTION__, pid, thread_found ? "stopped tracking thread metadata" : "thread metadata not found"); 982af245d11STodd Fiala } 983af245d11STodd Fiala } 984af245d11STodd Fiala else 985af245d11STodd Fiala { 986af245d11STodd Fiala // Do we want to report to the delegate in this case? I think not. If this was an orderly 987af245d11STodd Fiala // thread exit, we would already have received the SIGTRAP | (PTRACE_EVENT_EXIT << 8) signal, 988af245d11STodd Fiala // and we would have done an all-stop then. 989af245d11STodd Fiala if (log) 990af245d11STodd Fiala log->Printf ("NativeProcessLinux::%s() tid = %" PRIu64 " handling non-main thread exit (%s)", __FUNCTION__, pid, thread_found ? "stopped tracking thread metadata" : "thread metadata not found"); 991af245d11STodd Fiala } 9921107b5a5SPavel Labath return; 993af245d11STodd Fiala } 994af245d11STodd Fiala 995af245d11STodd Fiala // Get details on the signal raised. 996af245d11STodd Fiala siginfo_t info; 9971107b5a5SPavel Labath const auto err = GetSignalInfo(pid, &info); 99897ccc294SChaoren Lin if (err.Success()) 999fa03ad2eSChaoren Lin { 1000fa03ad2eSChaoren Lin // We have retrieved the signal info. Dispatch appropriately. 1001fa03ad2eSChaoren Lin if (info.si_signo == SIGTRAP) 10021107b5a5SPavel Labath MonitorSIGTRAP(&info, pid); 1003fa03ad2eSChaoren Lin else 10041107b5a5SPavel Labath MonitorSignal(&info, pid, exited); 1005fa03ad2eSChaoren Lin } 1006fa03ad2eSChaoren Lin else 1007af245d11STodd Fiala { 100897ccc294SChaoren Lin if (err.GetError() == EINVAL) 1009af245d11STodd Fiala { 1010fa03ad2eSChaoren Lin // This is a group stop reception for this tid. 101139036ac3SPavel Labath // We can reach here if we reinject SIGSTOP, SIGSTP, SIGTTIN or SIGTTOU into the 101239036ac3SPavel Labath // tracee, triggering the group-stop mechanism. Normally receiving these would stop 101339036ac3SPavel Labath // the process, pending a SIGCONT. Simulating this state in a debugger is hard and is 101439036ac3SPavel Labath // generally not needed (one use case is debugging background task being managed by a 101539036ac3SPavel Labath // shell). For general use, it is sufficient to stop the process in a signal-delivery 101639036ac3SPavel Labath // stop which happens before the group stop. This done by MonitorSignal and works 101739036ac3SPavel Labath // correctly for all signals. 1018fa03ad2eSChaoren Lin if (log) 101939036ac3SPavel Labath log->Printf("NativeProcessLinux::%s received a group stop for pid %" PRIu64 " tid %" PRIu64 ". Transparent handling of group stops not supported, resuming the thread.", __FUNCTION__, GetID (), pid); 102039036ac3SPavel Labath Resume(pid, signal); 1021a9882ceeSTodd Fiala } 1022a9882ceeSTodd Fiala else 1023a9882ceeSTodd Fiala { 1024af245d11STodd Fiala // ptrace(GETSIGINFO) failed (but not due to group-stop). 1025af245d11STodd Fiala 1026af245d11STodd Fiala // A return value of ESRCH means the thread/process is no longer on the system, 1027af245d11STodd Fiala // so it was killed somehow outside of our control. Either way, we can't do anything 1028af245d11STodd Fiala // with it anymore. 1029af245d11STodd Fiala 1030af245d11STodd Fiala // Stop tracking the metadata for the thread since it's entirely off the system now. 10311107b5a5SPavel Labath const bool thread_found = StopTrackingThread (pid); 1032af245d11STodd Fiala 1033af245d11STodd Fiala if (log) 1034af245d11STodd Fiala log->Printf ("NativeProcessLinux::%s GetSignalInfo failed: %s, tid = %" PRIu64 ", signal = %d, status = %d (%s, %s, %s)", 103597ccc294SChaoren Lin __FUNCTION__, err.AsCString(), pid, signal, status, err.GetError() == ESRCH ? "thread/process killed" : "unknown reason", is_main_thread ? "is main thread" : "is not main thread", thread_found ? "thread metadata removed" : "thread metadata not found"); 1036af245d11STodd Fiala 1037af245d11STodd Fiala if (is_main_thread) 1038af245d11STodd Fiala { 1039af245d11STodd Fiala // Notify the delegate - our process is not available but appears to have been killed outside 1040af245d11STodd Fiala // our control. Is eStateExited the right exit state in this case? 10411107b5a5SPavel Labath SetExitStatus (convert_pid_status_to_exit_type (status), convert_pid_status_to_return_code (status), nullptr, true); 10421107b5a5SPavel Labath SetState (StateType::eStateExited, true); 1043af245d11STodd Fiala } 1044af245d11STodd Fiala else 1045af245d11STodd Fiala { 1046af245d11STodd Fiala // This thread was pulled out from underneath us. Anything to do here? Do we want to do an all stop? 1047af245d11STodd Fiala if (log) 10481107b5a5SPavel Labath log->Printf ("NativeProcessLinux::%s pid %" PRIu64 " tid %" PRIu64 " non-main thread exit occurred, didn't tell delegate anything since thread disappeared out from underneath us", __FUNCTION__, GetID (), pid); 1049af245d11STodd Fiala } 1050af245d11STodd Fiala } 1051af245d11STodd Fiala } 1052af245d11STodd Fiala } 1053af245d11STodd Fiala 1054af245d11STodd Fiala void 1055426bdf88SPavel Labath NativeProcessLinux::WaitForNewThread(::pid_t tid) 1056426bdf88SPavel Labath { 1057426bdf88SPavel Labath Log *log (GetLogIfAllCategoriesSet (LIBLLDB_LOG_PROCESS)); 1058426bdf88SPavel Labath 1059*0e1d729bSPavel Labath NativeThreadLinuxSP new_thread_sp = std::static_pointer_cast<NativeThreadLinux>(GetThreadByID(tid)); 1060426bdf88SPavel Labath 1061426bdf88SPavel Labath if (new_thread_sp) 1062426bdf88SPavel Labath { 1063426bdf88SPavel Labath // We are already tracking the thread - we got the event on the new thread (see 1064426bdf88SPavel Labath // MonitorSignal) before this one. We are done. 1065426bdf88SPavel Labath return; 1066426bdf88SPavel Labath } 1067426bdf88SPavel Labath 1068426bdf88SPavel Labath // The thread is not tracked yet, let's wait for it to appear. 1069426bdf88SPavel Labath int status = -1; 1070426bdf88SPavel Labath ::pid_t wait_pid; 1071426bdf88SPavel Labath do 1072426bdf88SPavel Labath { 1073426bdf88SPavel Labath if (log) 1074426bdf88SPavel Labath log->Printf ("NativeProcessLinux::%s() received thread creation event for tid %" PRIu32 ". tid not tracked yet, waiting for thread to appear...", __FUNCTION__, tid); 1075426bdf88SPavel Labath wait_pid = waitpid(tid, &status, __WALL); 1076426bdf88SPavel Labath } 1077426bdf88SPavel Labath while (wait_pid == -1 && errno == EINTR); 1078426bdf88SPavel Labath // Since we are waiting on a specific tid, this must be the creation event. But let's do 1079426bdf88SPavel Labath // some checks just in case. 1080426bdf88SPavel Labath if (wait_pid != tid) { 1081426bdf88SPavel Labath if (log) 1082426bdf88SPavel Labath log->Printf ("NativeProcessLinux::%s() waiting for tid %" PRIu32 " failed. Assuming the thread has disappeared in the meantime", __FUNCTION__, tid); 1083426bdf88SPavel Labath // The only way I know of this could happen is if the whole process was 1084426bdf88SPavel Labath // SIGKILLed in the mean time. In any case, we can't do anything about that now. 1085426bdf88SPavel Labath return; 1086426bdf88SPavel Labath } 1087426bdf88SPavel Labath if (WIFEXITED(status)) 1088426bdf88SPavel Labath { 1089426bdf88SPavel Labath if (log) 1090426bdf88SPavel Labath log->Printf ("NativeProcessLinux::%s() waiting for tid %" PRIu32 " returned an 'exited' event. Not tracking the thread.", __FUNCTION__, tid); 1091426bdf88SPavel Labath // Also a very improbable event. 1092426bdf88SPavel Labath return; 1093426bdf88SPavel Labath } 1094426bdf88SPavel Labath 1095426bdf88SPavel Labath siginfo_t info; 1096426bdf88SPavel Labath Error error = GetSignalInfo(tid, &info); 1097426bdf88SPavel Labath if (error.Fail()) 1098426bdf88SPavel Labath { 1099426bdf88SPavel Labath if (log) 1100426bdf88SPavel Labath log->Printf ("NativeProcessLinux::%s() GetSignalInfo for tid %" PRIu32 " failed. Assuming the thread has disappeared in the meantime.", __FUNCTION__, tid); 1101426bdf88SPavel Labath return; 1102426bdf88SPavel Labath } 1103426bdf88SPavel Labath 1104426bdf88SPavel Labath if (((info.si_pid != 0) || (info.si_code != SI_USER)) && log) 1105426bdf88SPavel Labath { 1106426bdf88SPavel Labath // We should be getting a thread creation signal here, but we received something 1107426bdf88SPavel Labath // else. There isn't much we can do about it now, so we will just log that. Since the 1108426bdf88SPavel Labath // thread is alive and we are receiving events from it, we shall pretend that it was 1109426bdf88SPavel Labath // created properly. 1110426bdf88SPavel Labath log->Printf ("NativeProcessLinux::%s() GetSignalInfo for tid %" PRIu32 " received unexpected signal with code %d from pid %d.", __FUNCTION__, tid, info.si_code, info.si_pid); 1111426bdf88SPavel Labath } 1112426bdf88SPavel Labath 1113426bdf88SPavel Labath if (log) 1114426bdf88SPavel Labath log->Printf ("NativeProcessLinux::%s() pid = %" PRIu64 ": tracking new thread tid %" PRIu32, 1115426bdf88SPavel Labath __FUNCTION__, GetID (), tid); 1116426bdf88SPavel Labath 1117*0e1d729bSPavel Labath new_thread_sp = std::static_pointer_cast<NativeThreadLinux>(AddThread(tid)); 1118*0e1d729bSPavel Labath ResumeThread(new_thread_sp, eStateRunning, LLDB_INVALID_SIGNAL_NUMBER); 11191dbc6c9cSPavel Labath ThreadWasCreated(tid); 1120426bdf88SPavel Labath } 1121426bdf88SPavel Labath 1122426bdf88SPavel Labath void 1123af245d11STodd Fiala NativeProcessLinux::MonitorSIGTRAP(const siginfo_t *info, lldb::pid_t pid) 1124af245d11STodd Fiala { 1125af245d11STodd Fiala Log *log (GetLogIfAllCategoriesSet (LIBLLDB_LOG_PROCESS)); 1126af245d11STodd Fiala const bool is_main_thread = (pid == GetID ()); 1127af245d11STodd Fiala 1128af245d11STodd Fiala assert(info && info->si_signo == SIGTRAP && "Unexpected child signal!"); 1129af245d11STodd Fiala if (!info) 1130af245d11STodd Fiala return; 1131af245d11STodd Fiala 11325830aa75STamas Berghammer Mutex::Locker locker (m_threads_mutex); 11335830aa75STamas Berghammer 1134af245d11STodd Fiala // See if we can find a thread for this signal. 1135*0e1d729bSPavel Labath NativeThreadLinuxSP thread_sp = std::static_pointer_cast<NativeThreadLinux>(GetThreadByID(pid)); 1136af245d11STodd Fiala if (!thread_sp) 1137af245d11STodd Fiala { 1138af245d11STodd Fiala if (log) 1139af245d11STodd Fiala log->Printf ("NativeProcessLinux::%s() pid %" PRIu64 " no thread found for tid %" PRIu64, __FUNCTION__, GetID (), pid); 1140af245d11STodd Fiala } 1141af245d11STodd Fiala 1142af245d11STodd Fiala switch (info->si_code) 1143af245d11STodd Fiala { 1144af245d11STodd Fiala // TODO: these two cases are required if we want to support tracing of the inferiors' children. We'd need this to debug a monitor. 1145af245d11STodd Fiala // case (SIGTRAP | (PTRACE_EVENT_FORK << 8)): 1146af245d11STodd Fiala // case (SIGTRAP | (PTRACE_EVENT_VFORK << 8)): 1147af245d11STodd Fiala 1148af245d11STodd Fiala case (SIGTRAP | (PTRACE_EVENT_CLONE << 8)): 1149af245d11STodd Fiala { 11505fd24c67SPavel Labath // This is the notification on the parent thread which informs us of new thread 1151426bdf88SPavel Labath // creation. 1152426bdf88SPavel Labath // We don't want to do anything with the parent thread so we just resume it. In case we 1153426bdf88SPavel Labath // want to implement "break on thread creation" functionality, we would need to stop 1154426bdf88SPavel Labath // here. 1155af245d11STodd Fiala 1156af245d11STodd Fiala unsigned long event_message = 0; 1157426bdf88SPavel Labath if (GetEventMessage (pid, &event_message).Fail()) 1158fa03ad2eSChaoren Lin { 1159426bdf88SPavel Labath if (log) 1160fa03ad2eSChaoren Lin log->Printf ("NativeProcessLinux::%s() pid %" PRIu64 " received thread creation event but GetEventMessage failed so we don't know the new tid", __FUNCTION__, pid); 1161426bdf88SPavel Labath } else 1162426bdf88SPavel Labath WaitForNewThread(event_message); 1163af245d11STodd Fiala 1164*0e1d729bSPavel Labath ResumeThread(thread_sp, thread_sp->GetState(), LLDB_INVALID_SIGNAL_NUMBER); 1165af245d11STodd Fiala break; 1166af245d11STodd Fiala } 1167af245d11STodd Fiala 1168af245d11STodd Fiala case (SIGTRAP | (PTRACE_EVENT_EXEC << 8)): 1169a9882ceeSTodd Fiala { 1170a9882ceeSTodd Fiala NativeThreadProtocolSP main_thread_sp; 1171af245d11STodd Fiala if (log) 1172af245d11STodd Fiala log->Printf ("NativeProcessLinux::%s() received exec event, code = %d", __FUNCTION__, info->si_code ^ SIGTRAP); 1173a9882ceeSTodd Fiala 11741dbc6c9cSPavel Labath // Exec clears any pending notifications. 1175*0e1d729bSPavel Labath m_pending_notification_tid = LLDB_INVALID_THREAD_ID; 1176fa03ad2eSChaoren Lin 1177fa03ad2eSChaoren Lin // Remove all but the main thread here. Linux fork creates a new process which only copies the main thread. Mutexes are in undefined state. 1178a9882ceeSTodd Fiala if (log) 1179a9882ceeSTodd Fiala log->Printf ("NativeProcessLinux::%s exec received, stop tracking all but main thread", __FUNCTION__); 1180a9882ceeSTodd Fiala 1181a9882ceeSTodd Fiala for (auto thread_sp : m_threads) 1182a9882ceeSTodd Fiala { 1183a9882ceeSTodd Fiala const bool is_main_thread = thread_sp && thread_sp->GetID () == GetID (); 1184a9882ceeSTodd Fiala if (is_main_thread) 1185a9882ceeSTodd Fiala { 1186a9882ceeSTodd Fiala main_thread_sp = thread_sp; 1187a9882ceeSTodd Fiala if (log) 1188a9882ceeSTodd Fiala log->Printf ("NativeProcessLinux::%s found main thread with tid %" PRIu64 ", keeping", __FUNCTION__, main_thread_sp->GetID ()); 1189a9882ceeSTodd Fiala } 1190a9882ceeSTodd Fiala else 1191a9882ceeSTodd Fiala { 1192fa03ad2eSChaoren Lin // Tell thread coordinator this thread is dead. 1193a9882ceeSTodd Fiala if (log) 1194a9882ceeSTodd Fiala log->Printf ("NativeProcessLinux::%s discarding non-main-thread tid %" PRIu64 " due to exec", __FUNCTION__, thread_sp->GetID ()); 1195a9882ceeSTodd Fiala } 1196a9882ceeSTodd Fiala } 1197a9882ceeSTodd Fiala 1198a9882ceeSTodd Fiala m_threads.clear (); 1199a9882ceeSTodd Fiala 1200a9882ceeSTodd Fiala if (main_thread_sp) 1201a9882ceeSTodd Fiala { 1202a9882ceeSTodd Fiala m_threads.push_back (main_thread_sp); 1203a9882ceeSTodd Fiala SetCurrentThreadID (main_thread_sp->GetID ()); 1204cb84eebbSTamas Berghammer std::static_pointer_cast<NativeThreadLinux> (main_thread_sp)->SetStoppedByExec (); 1205a9882ceeSTodd Fiala } 1206a9882ceeSTodd Fiala else 1207a9882ceeSTodd Fiala { 1208a9882ceeSTodd Fiala SetCurrentThreadID (LLDB_INVALID_THREAD_ID); 1209a9882ceeSTodd Fiala if (log) 1210a9882ceeSTodd Fiala log->Printf ("NativeProcessLinux::%s pid %" PRIu64 "no main thread found, discarded all threads, we're in a no-thread state!", __FUNCTION__, GetID ()); 1211a9882ceeSTodd Fiala } 1212a9882ceeSTodd Fiala 1213fa03ad2eSChaoren Lin // Tell coordinator about about the "new" (since exec) stopped main thread. 1214fa03ad2eSChaoren Lin const lldb::tid_t main_thread_tid = GetID (); 12151dbc6c9cSPavel Labath ThreadWasCreated(main_thread_tid); 1216fa03ad2eSChaoren Lin 1217fa03ad2eSChaoren Lin // NOTE: ideally these next statements would execute at the same time as the coordinator thread create was executed. 1218fa03ad2eSChaoren Lin // Consider a handler that can execute when that happens. 1219a9882ceeSTodd Fiala // Let our delegate know we have just exec'd. 1220a9882ceeSTodd Fiala NotifyDidExec (); 1221a9882ceeSTodd Fiala 1222a9882ceeSTodd Fiala // If we have a main thread, indicate we are stopped. 1223a9882ceeSTodd Fiala assert (main_thread_sp && "exec called during ptraced process but no main thread metadata tracked"); 1224fa03ad2eSChaoren Lin 1225fa03ad2eSChaoren Lin // Let the process know we're stopped. 1226ed89c7feSPavel Labath StopRunningThreads (pid); 1227a9882ceeSTodd Fiala 1228af245d11STodd Fiala break; 1229a9882ceeSTodd Fiala } 1230af245d11STodd Fiala 1231af245d11STodd Fiala case (SIGTRAP | (PTRACE_EVENT_EXIT << 8)): 1232af245d11STodd Fiala { 1233af245d11STodd Fiala // The inferior process or one of its threads is about to exit. 12346e35163cSPavel Labath // We don't want to do anything with the thread so we just resume it. In case we 12356e35163cSPavel Labath // want to implement "break on thread exit" functionality, we would need to stop 12366e35163cSPavel Labath // here. 1237fa03ad2eSChaoren Lin 1238af245d11STodd Fiala unsigned long data = 0; 123997ccc294SChaoren Lin if (GetEventMessage(pid, &data).Fail()) 1240af245d11STodd Fiala data = -1; 1241af245d11STodd Fiala 1242af245d11STodd Fiala if (log) 1243af245d11STodd Fiala { 1244af245d11STodd Fiala log->Printf ("NativeProcessLinux::%s() received PTRACE_EVENT_EXIT, data = %lx (WIFEXITED=%s,WIFSIGNALED=%s), pid = %" PRIu64 " (%s)", 1245af245d11STodd Fiala __FUNCTION__, 1246af245d11STodd Fiala data, WIFEXITED (data) ? "true" : "false", WIFSIGNALED (data) ? "true" : "false", 1247af245d11STodd Fiala pid, 1248af245d11STodd Fiala is_main_thread ? "is main thread" : "not main thread"); 1249af245d11STodd Fiala } 1250af245d11STodd Fiala 1251af245d11STodd Fiala if (is_main_thread) 1252af245d11STodd Fiala { 1253af245d11STodd Fiala SetExitStatus (convert_pid_status_to_exit_type (data), convert_pid_status_to_return_code (data), nullptr, true); 125475f47c3aSTodd Fiala } 125575f47c3aSTodd Fiala 1256*0e1d729bSPavel Labath ResumeThread(thread_sp, thread_sp->GetState(), LLDB_INVALID_SIGNAL_NUMBER); 1257af245d11STodd Fiala 1258af245d11STodd Fiala break; 1259af245d11STodd Fiala } 1260af245d11STodd Fiala 1261af245d11STodd Fiala case 0: 1262c16f5dcaSChaoren Lin case TRAP_TRACE: // We receive this on single stepping. 1263c16f5dcaSChaoren Lin case TRAP_HWBKPT: // We receive this on watchpoint hit 126486fd8e45SChaoren Lin if (thread_sp) 126586fd8e45SChaoren Lin { 1266c16f5dcaSChaoren Lin // If a watchpoint was hit, report it 1267c16f5dcaSChaoren Lin uint32_t wp_index; 1268ea8c25a8SOmair Javaid Error error = thread_sp->GetRegisterContext()->GetWatchpointHitIndex(wp_index, (lldb::addr_t)info->si_addr); 1269c16f5dcaSChaoren Lin if (error.Fail() && log) 1270c16f5dcaSChaoren Lin log->Printf("NativeProcessLinux::%s() " 1271c16f5dcaSChaoren Lin "received error while checking for watchpoint hits, " 1272c16f5dcaSChaoren Lin "pid = %" PRIu64 " error = %s", 1273c16f5dcaSChaoren Lin __FUNCTION__, pid, error.AsCString()); 1274c16f5dcaSChaoren Lin if (wp_index != LLDB_INVALID_INDEX32) 12755830aa75STamas Berghammer { 1276c16f5dcaSChaoren Lin MonitorWatchpoint(pid, thread_sp, wp_index); 1277c16f5dcaSChaoren Lin break; 1278c16f5dcaSChaoren Lin } 1279c16f5dcaSChaoren Lin } 1280c16f5dcaSChaoren Lin // Otherwise, report step over 1281c16f5dcaSChaoren Lin MonitorTrace(pid, thread_sp); 1282af245d11STodd Fiala break; 1283af245d11STodd Fiala 1284af245d11STodd Fiala case SI_KERNEL: 128535799963SMohit K. Bhakkad #if defined __mips__ 128635799963SMohit K. Bhakkad // For mips there is no special signal for watchpoint 128735799963SMohit K. Bhakkad // So we check for watchpoint in kernel trap 128835799963SMohit K. Bhakkad if (thread_sp) 128935799963SMohit K. Bhakkad { 129035799963SMohit K. Bhakkad // If a watchpoint was hit, report it 129135799963SMohit K. Bhakkad uint32_t wp_index; 1292c60c9452SJaydeep Patil Error error = thread_sp->GetRegisterContext()->GetWatchpointHitIndex(wp_index, LLDB_INVALID_ADDRESS); 129335799963SMohit K. Bhakkad if (error.Fail() && log) 129435799963SMohit K. Bhakkad log->Printf("NativeProcessLinux::%s() " 129535799963SMohit K. Bhakkad "received error while checking for watchpoint hits, " 129635799963SMohit K. Bhakkad "pid = %" PRIu64 " error = %s", 129735799963SMohit K. Bhakkad __FUNCTION__, pid, error.AsCString()); 129835799963SMohit K. Bhakkad if (wp_index != LLDB_INVALID_INDEX32) 129935799963SMohit K. Bhakkad { 130035799963SMohit K. Bhakkad MonitorWatchpoint(pid, thread_sp, wp_index); 130135799963SMohit K. Bhakkad break; 130235799963SMohit K. Bhakkad } 130335799963SMohit K. Bhakkad } 130435799963SMohit K. Bhakkad // NO BREAK 130535799963SMohit K. Bhakkad #endif 1306af245d11STodd Fiala case TRAP_BRKPT: 1307c16f5dcaSChaoren Lin MonitorBreakpoint(pid, thread_sp); 1308af245d11STodd Fiala break; 1309af245d11STodd Fiala 1310af245d11STodd Fiala case SIGTRAP: 1311af245d11STodd Fiala case (SIGTRAP | 0x80): 1312af245d11STodd Fiala if (log) 1313fa03ad2eSChaoren Lin log->Printf ("NativeProcessLinux::%s() received unknown SIGTRAP system call stop event, pid %" PRIu64 "tid %" PRIu64 ", resuming", __FUNCTION__, GetID (), pid); 1314fa03ad2eSChaoren Lin 1315af245d11STodd Fiala // Ignore these signals until we know more about them. 1316*0e1d729bSPavel Labath ResumeThread(thread_sp, thread_sp->GetState(), LLDB_INVALID_SIGNAL_NUMBER); 1317af245d11STodd Fiala break; 1318af245d11STodd Fiala 1319af245d11STodd Fiala default: 1320af245d11STodd Fiala assert(false && "Unexpected SIGTRAP code!"); 1321af245d11STodd Fiala if (log) 13226e35163cSPavel Labath log->Printf ("NativeProcessLinux::%s() pid %" PRIu64 "tid %" PRIu64 " received unhandled SIGTRAP code: 0x%d", 13236e35163cSPavel Labath __FUNCTION__, GetID (), pid, info->si_code); 1324af245d11STodd Fiala break; 1325af245d11STodd Fiala 1326af245d11STodd Fiala } 1327af245d11STodd Fiala } 1328af245d11STodd Fiala 1329af245d11STodd Fiala void 1330c16f5dcaSChaoren Lin NativeProcessLinux::MonitorTrace(lldb::pid_t pid, NativeThreadProtocolSP thread_sp) 1331c16f5dcaSChaoren Lin { 1332c16f5dcaSChaoren Lin Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_PROCESS)); 1333c16f5dcaSChaoren Lin if (log) 1334c16f5dcaSChaoren Lin log->Printf("NativeProcessLinux::%s() received trace event, pid = %" PRIu64 " (single stepping)", 1335c16f5dcaSChaoren Lin __FUNCTION__, pid); 1336c16f5dcaSChaoren Lin 1337*0e1d729bSPavel Labath // This thread is currently stopped. 1338c16f5dcaSChaoren Lin if (thread_sp) 1339c16f5dcaSChaoren Lin std::static_pointer_cast<NativeThreadLinux>(thread_sp)->SetStoppedByTrace(); 1340c16f5dcaSChaoren Lin 1341c16f5dcaSChaoren Lin // Here we don't have to request the rest of the threads to stop or request a deferred stop. 1342c16f5dcaSChaoren Lin // This would have already happened at the time the Resume() with step operation was signaled. 1343c16f5dcaSChaoren Lin // At this point, we just need to say we stopped, and the deferred notifcation will fire off 1344c16f5dcaSChaoren Lin // once all running threads have checked in as stopped. 1345c16f5dcaSChaoren Lin SetCurrentThreadID(pid); 1346c16f5dcaSChaoren Lin // Tell the process we have a stop (from software breakpoint). 1347ed89c7feSPavel Labath StopRunningThreads(pid); 1348c16f5dcaSChaoren Lin } 1349c16f5dcaSChaoren Lin 1350c16f5dcaSChaoren Lin void 1351c16f5dcaSChaoren Lin NativeProcessLinux::MonitorBreakpoint(lldb::pid_t pid, NativeThreadProtocolSP thread_sp) 1352c16f5dcaSChaoren Lin { 1353c16f5dcaSChaoren Lin Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PROCESS | LIBLLDB_LOG_BREAKPOINTS)); 1354c16f5dcaSChaoren Lin if (log) 1355c16f5dcaSChaoren Lin log->Printf("NativeProcessLinux::%s() received breakpoint event, pid = %" PRIu64, 1356c16f5dcaSChaoren Lin __FUNCTION__, pid); 1357c16f5dcaSChaoren Lin 1358c16f5dcaSChaoren Lin // Mark the thread as stopped at breakpoint. 1359c16f5dcaSChaoren Lin if (thread_sp) 1360c16f5dcaSChaoren Lin { 1361c16f5dcaSChaoren Lin std::static_pointer_cast<NativeThreadLinux>(thread_sp)->SetStoppedByBreakpoint(); 1362c16f5dcaSChaoren Lin Error error = FixupBreakpointPCAsNeeded(thread_sp); 1363c16f5dcaSChaoren Lin if (error.Fail()) 1364c16f5dcaSChaoren Lin if (log) 1365c16f5dcaSChaoren Lin log->Printf("NativeProcessLinux::%s() pid = %" PRIu64 " fixup: %s", 1366c16f5dcaSChaoren Lin __FUNCTION__, pid, error.AsCString()); 1367d8c338d4STamas Berghammer 13689eb1ecb9SPavel Labath if (m_threads_stepping_with_breakpoint.find(pid) != m_threads_stepping_with_breakpoint.end()) 1369d8c338d4STamas Berghammer std::static_pointer_cast<NativeThreadLinux>(thread_sp)->SetStoppedByTrace(); 1370d8c338d4STamas Berghammer } 1371c16f5dcaSChaoren Lin else 1372c16f5dcaSChaoren Lin if (log) 1373c16f5dcaSChaoren Lin log->Printf("NativeProcessLinux::%s() pid = %" PRIu64 ": " 1374c16f5dcaSChaoren Lin "warning, cannot process software breakpoint since no thread metadata", 1375c16f5dcaSChaoren Lin __FUNCTION__, pid); 1376c16f5dcaSChaoren Lin 1377c16f5dcaSChaoren Lin 1378c16f5dcaSChaoren Lin // We need to tell all other running threads before we notify the delegate about this stop. 1379ed89c7feSPavel Labath StopRunningThreads(pid); 1380c16f5dcaSChaoren Lin } 1381c16f5dcaSChaoren Lin 1382c16f5dcaSChaoren Lin void 1383c16f5dcaSChaoren Lin NativeProcessLinux::MonitorWatchpoint(lldb::pid_t pid, NativeThreadProtocolSP thread_sp, uint32_t wp_index) 1384c16f5dcaSChaoren Lin { 1385c16f5dcaSChaoren Lin Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PROCESS | LIBLLDB_LOG_WATCHPOINTS)); 1386c16f5dcaSChaoren Lin if (log) 1387c16f5dcaSChaoren Lin log->Printf("NativeProcessLinux::%s() received watchpoint event, " 1388c16f5dcaSChaoren Lin "pid = %" PRIu64 ", wp_index = %" PRIu32, 1389c16f5dcaSChaoren Lin __FUNCTION__, pid, wp_index); 1390c16f5dcaSChaoren Lin 1391c16f5dcaSChaoren Lin // Mark the thread as stopped at watchpoint. 1392c16f5dcaSChaoren Lin // The address is at (lldb::addr_t)info->si_addr if we need it. 1393c16f5dcaSChaoren Lin lldbassert(thread_sp && "thread_sp cannot be NULL"); 1394c16f5dcaSChaoren Lin std::static_pointer_cast<NativeThreadLinux>(thread_sp)->SetStoppedByWatchpoint(wp_index); 1395c16f5dcaSChaoren Lin 1396c16f5dcaSChaoren Lin // We need to tell all other running threads before we notify the delegate about this stop. 1397ed89c7feSPavel Labath StopRunningThreads(pid); 1398c16f5dcaSChaoren Lin } 1399c16f5dcaSChaoren Lin 1400c16f5dcaSChaoren Lin void 1401af245d11STodd Fiala NativeProcessLinux::MonitorSignal(const siginfo_t *info, lldb::pid_t pid, bool exited) 1402af245d11STodd Fiala { 1403511e5cdcSTodd Fiala assert (info && "null info"); 1404511e5cdcSTodd Fiala if (!info) 1405511e5cdcSTodd Fiala return; 1406511e5cdcSTodd Fiala 1407511e5cdcSTodd Fiala const int signo = info->si_signo; 1408511e5cdcSTodd Fiala const bool is_from_llgs = info->si_pid == getpid (); 1409af245d11STodd Fiala 1410af245d11STodd Fiala Log *log (GetLogIfAllCategoriesSet (LIBLLDB_LOG_PROCESS)); 1411af245d11STodd Fiala 1412af245d11STodd Fiala // POSIX says that process behaviour is undefined after it ignores a SIGFPE, 1413af245d11STodd Fiala // SIGILL, SIGSEGV, or SIGBUS *unless* that signal was generated by a 1414af245d11STodd Fiala // kill(2) or raise(3). Similarly for tgkill(2) on Linux. 1415af245d11STodd Fiala // 1416af245d11STodd Fiala // IOW, user generated signals never generate what we consider to be a 1417af245d11STodd Fiala // "crash". 1418af245d11STodd Fiala // 1419af245d11STodd Fiala // Similarly, ACK signals generated by this monitor. 1420af245d11STodd Fiala 14215830aa75STamas Berghammer Mutex::Locker locker (m_threads_mutex); 14225830aa75STamas Berghammer 1423af245d11STodd Fiala // See if we can find a thread for this signal. 1424*0e1d729bSPavel Labath NativeThreadLinuxSP thread_sp = std::static_pointer_cast<NativeThreadLinux>(GetThreadByID(pid)); 1425af245d11STodd Fiala if (!thread_sp) 1426af245d11STodd Fiala { 1427af245d11STodd Fiala if (log) 1428af245d11STodd Fiala log->Printf ("NativeProcessLinux::%s() pid %" PRIu64 " no thread found for tid %" PRIu64, __FUNCTION__, GetID (), pid); 1429af245d11STodd Fiala } 1430af245d11STodd Fiala 1431af245d11STodd Fiala // Handle the signal. 1432af245d11STodd Fiala if (info->si_code == SI_TKILL || info->si_code == SI_USER) 1433af245d11STodd Fiala { 1434af245d11STodd Fiala if (log) 1435af245d11STodd Fiala log->Printf ("NativeProcessLinux::%s() received signal %s (%d) with code %s, (siginfo pid = %d (%s), waitpid pid = %" PRIu64 ")", 1436af245d11STodd Fiala __FUNCTION__, 143798d0a4b3SChaoren Lin Host::GetSignalAsCString(signo), 1438af245d11STodd Fiala signo, 1439af245d11STodd Fiala (info->si_code == SI_TKILL ? "SI_TKILL" : "SI_USER"), 1440af245d11STodd Fiala info->si_pid, 1441511e5cdcSTodd Fiala is_from_llgs ? "from llgs" : "not from llgs", 1442af245d11STodd Fiala pid); 144358a2f669STodd Fiala } 1444af245d11STodd Fiala 144558a2f669STodd Fiala // Check for new thread notification. 144658a2f669STodd Fiala if ((info->si_pid == 0) && (info->si_code == SI_USER)) 1447af245d11STodd Fiala { 1448af245d11STodd Fiala // A new thread creation is being signaled. This is one of two parts that come in 1449426bdf88SPavel Labath // a non-deterministic order. This code handles the case where the new thread event comes 1450426bdf88SPavel Labath // before the event on the parent thread. For the opposite case see code in 1451426bdf88SPavel Labath // MonitorSIGTRAP. 1452af245d11STodd Fiala if (log) 1453af245d11STodd Fiala log->Printf ("NativeProcessLinux::%s() pid = %" PRIu64 " tid %" PRIu64 ": new thread notification", 1454af245d11STodd Fiala __FUNCTION__, GetID (), pid); 1455af245d11STodd Fiala 1456*0e1d729bSPavel Labath thread_sp = std::static_pointer_cast<NativeThreadLinux>(AddThread(pid)); 14575fd24c67SPavel Labath assert (thread_sp.get() && "failed to create the tracking data for newly created inferior thread"); 14585fd24c67SPavel Labath // We can now resume the newly created thread. 1459*0e1d729bSPavel Labath ResumeThread(thread_sp, eStateRunning, LLDB_INVALID_SIGNAL_NUMBER); 14601dbc6c9cSPavel Labath ThreadWasCreated(pid); 146158a2f669STodd Fiala // Done handling. 146258a2f669STodd Fiala return; 1463af245d11STodd Fiala } 146458a2f669STodd Fiala 146558a2f669STodd Fiala // Check for thread stop notification. 1466511e5cdcSTodd Fiala if (is_from_llgs && (info->si_code == SI_TKILL) && (signo == SIGSTOP)) 1467af245d11STodd Fiala { 1468af245d11STodd Fiala // This is a tgkill()-based stop. 1469af245d11STodd Fiala if (thread_sp) 1470af245d11STodd Fiala { 1471fa03ad2eSChaoren Lin if (log) 1472fa03ad2eSChaoren Lin log->Printf ("NativeProcessLinux::%s() pid %" PRIu64 " tid %" PRIu64 ", thread stopped", 1473fa03ad2eSChaoren Lin __FUNCTION__, 1474fa03ad2eSChaoren Lin GetID (), 1475fa03ad2eSChaoren Lin pid); 1476fa03ad2eSChaoren Lin 1477aab58633SChaoren Lin // Check that we're not already marked with a stop reason. 1478aab58633SChaoren Lin // Note this thread really shouldn't already be marked as stopped - if we were, that would imply that 1479aab58633SChaoren Lin // the kernel signaled us with the thread stopping which we handled and marked as stopped, 1480aab58633SChaoren Lin // and that, without an intervening resume, we received another stop. It is more likely 1481aab58633SChaoren Lin // that we are missing the marking of a run state somewhere if we find that the thread was 1482aab58633SChaoren Lin // marked as stopped. 1483cb84eebbSTamas Berghammer std::shared_ptr<NativeThreadLinux> linux_thread_sp = std::static_pointer_cast<NativeThreadLinux> (thread_sp); 1484cb84eebbSTamas Berghammer assert (linux_thread_sp && "linux_thread_sp is null!"); 1485aab58633SChaoren Lin 1486cb84eebbSTamas Berghammer const StateType thread_state = linux_thread_sp->GetState (); 1487aab58633SChaoren Lin if (!StateIsStoppedState (thread_state, false)) 1488aab58633SChaoren Lin { 1489ed89c7feSPavel Labath // An inferior thread has stopped because of a SIGSTOP we have sent it. 1490ed89c7feSPavel Labath // Generally, these are not important stops and we don't want to report them as 1491ed89c7feSPavel Labath // they are just used to stop other threads when one thread (the one with the 1492ed89c7feSPavel Labath // *real* stop reason) hits a breakpoint (watchpoint, etc...). However, in the 1493ed89c7feSPavel Labath // case of an asynchronous Interrupt(), this *is* the real stop reason, so we 1494ed89c7feSPavel Labath // leave the signal intact if this is the thread that was chosen as the 1495ed89c7feSPavel Labath // triggering thread. 1496*0e1d729bSPavel Labath if (m_pending_notification_tid != LLDB_INVALID_THREAD_ID) 1497*0e1d729bSPavel Labath { 1498*0e1d729bSPavel Labath if (m_pending_notification_tid == pid) 1499c4e25c96SPavel Labath linux_thread_sp->SetStoppedBySignal(SIGSTOP, info); 1500ed89c7feSPavel Labath else 150105569f67SPavel Labath linux_thread_sp->SetStoppedWithNoReason(); 1502ed89c7feSPavel Labath 1503af245d11STodd Fiala SetCurrentThreadID (thread_sp->GetID ()); 1504*0e1d729bSPavel Labath SignalIfAllThreadsStopped(); 1505*0e1d729bSPavel Labath } 1506*0e1d729bSPavel Labath else 1507*0e1d729bSPavel Labath { 1508*0e1d729bSPavel Labath // We can end up here if stop was initiated by LLGS but by this time a 1509*0e1d729bSPavel Labath // thread stop has occurred - maybe initiated by another event. 1510*0e1d729bSPavel Labath Error error = ResumeThread(linux_thread_sp, linux_thread_sp->GetState(), 0); 1511*0e1d729bSPavel Labath if (error.Fail() && log) 1512*0e1d729bSPavel Labath { 1513*0e1d729bSPavel Labath log->Printf("NativeProcessLinux::%s failed to resume thread tid %" PRIu64 ": %s", 1514*0e1d729bSPavel Labath __FUNCTION__, linux_thread_sp->GetID(), error.AsCString ()); 1515*0e1d729bSPavel Labath } 1516*0e1d729bSPavel Labath } 1517aab58633SChaoren Lin } 1518aab58633SChaoren Lin else 1519aab58633SChaoren Lin { 1520aab58633SChaoren Lin if (log) 1521aab58633SChaoren Lin { 1522aab58633SChaoren Lin // Retrieve the signal name if the thread was stopped by a signal. 1523aab58633SChaoren Lin int stop_signo = 0; 1524cb84eebbSTamas Berghammer const bool stopped_by_signal = linux_thread_sp->IsStopped (&stop_signo); 152598d0a4b3SChaoren Lin const char *signal_name = stopped_by_signal ? Host::GetSignalAsCString(stop_signo) : "<not stopped by signal>"; 1526aab58633SChaoren Lin if (!signal_name) 1527aab58633SChaoren Lin signal_name = "<no-signal-name>"; 1528aab58633SChaoren Lin 1529aab58633SChaoren Lin log->Printf ("NativeProcessLinux::%s() pid %" PRIu64 " tid %" PRIu64 ", thread was already marked as a stopped state (state=%s, signal=%d (%s)), leaving stop signal as is", 1530aab58633SChaoren Lin __FUNCTION__, 1531aab58633SChaoren Lin GetID (), 1532cb84eebbSTamas Berghammer linux_thread_sp->GetID (), 1533aab58633SChaoren Lin StateAsCString (thread_state), 1534aab58633SChaoren Lin stop_signo, 1535aab58633SChaoren Lin signal_name); 1536aab58633SChaoren Lin } 1537*0e1d729bSPavel Labath SignalIfAllThreadsStopped(); 1538af245d11STodd Fiala } 153986fd8e45SChaoren Lin } 1540af245d11STodd Fiala 154158a2f669STodd Fiala // Done handling. 1542af245d11STodd Fiala return; 1543af245d11STodd Fiala } 1544af245d11STodd Fiala 1545af245d11STodd Fiala if (log) 154698d0a4b3SChaoren Lin log->Printf ("NativeProcessLinux::%s() received signal %s", __FUNCTION__, Host::GetSignalAsCString(signo)); 1547af245d11STodd Fiala 154886fd8e45SChaoren Lin // This thread is stopped. 154986fd8e45SChaoren Lin if (thread_sp) 1550c4e25c96SPavel Labath std::static_pointer_cast<NativeThreadLinux> (thread_sp)->SetStoppedBySignal(signo, info); 155186fd8e45SChaoren Lin 155286fd8e45SChaoren Lin // Send a stop to the debugger after we get all other threads to stop. 1553ed89c7feSPavel Labath StopRunningThreads (pid); 1554511e5cdcSTodd Fiala } 1555af245d11STodd Fiala 1556e7708688STamas Berghammer namespace { 1557e7708688STamas Berghammer 1558e7708688STamas Berghammer struct EmulatorBaton 1559e7708688STamas Berghammer { 1560e7708688STamas Berghammer NativeProcessLinux* m_process; 1561e7708688STamas Berghammer NativeRegisterContext* m_reg_context; 15626648fcc3SPavel Labath 15636648fcc3SPavel Labath // eRegisterKindDWARF -> RegsiterValue 15646648fcc3SPavel Labath std::unordered_map<uint32_t, RegisterValue> m_register_values; 1565e7708688STamas Berghammer 1566e7708688STamas Berghammer EmulatorBaton(NativeProcessLinux* process, NativeRegisterContext* reg_context) : 1567e7708688STamas Berghammer m_process(process), m_reg_context(reg_context) {} 1568e7708688STamas Berghammer }; 1569e7708688STamas Berghammer 1570e7708688STamas Berghammer } // anonymous namespace 1571e7708688STamas Berghammer 1572e7708688STamas Berghammer static size_t 1573e7708688STamas Berghammer ReadMemoryCallback (EmulateInstruction *instruction, 1574e7708688STamas Berghammer void *baton, 1575e7708688STamas Berghammer const EmulateInstruction::Context &context, 1576e7708688STamas Berghammer lldb::addr_t addr, 1577e7708688STamas Berghammer void *dst, 1578e7708688STamas Berghammer size_t length) 1579e7708688STamas Berghammer { 1580e7708688STamas Berghammer EmulatorBaton* emulator_baton = static_cast<EmulatorBaton*>(baton); 1581e7708688STamas Berghammer 15823eb4b458SChaoren Lin size_t bytes_read; 1583e7708688STamas Berghammer emulator_baton->m_process->ReadMemory(addr, dst, length, bytes_read); 1584e7708688STamas Berghammer return bytes_read; 1585e7708688STamas Berghammer } 1586e7708688STamas Berghammer 1587e7708688STamas Berghammer static bool 1588e7708688STamas Berghammer ReadRegisterCallback (EmulateInstruction *instruction, 1589e7708688STamas Berghammer void *baton, 1590e7708688STamas Berghammer const RegisterInfo *reg_info, 1591e7708688STamas Berghammer RegisterValue ®_value) 1592e7708688STamas Berghammer { 1593e7708688STamas Berghammer EmulatorBaton* emulator_baton = static_cast<EmulatorBaton*>(baton); 1594e7708688STamas Berghammer 15956648fcc3SPavel Labath auto it = emulator_baton->m_register_values.find(reg_info->kinds[eRegisterKindDWARF]); 15966648fcc3SPavel Labath if (it != emulator_baton->m_register_values.end()) 15976648fcc3SPavel Labath { 15986648fcc3SPavel Labath reg_value = it->second; 15996648fcc3SPavel Labath return true; 16006648fcc3SPavel Labath } 16016648fcc3SPavel Labath 1602e7708688STamas Berghammer // The emulator only fill in the dwarf regsiter numbers (and in some case 1603e7708688STamas Berghammer // the generic register numbers). Get the full register info from the 1604e7708688STamas Berghammer // register context based on the dwarf register numbers. 1605e7708688STamas Berghammer const RegisterInfo* full_reg_info = emulator_baton->m_reg_context->GetRegisterInfo( 1606e7708688STamas Berghammer eRegisterKindDWARF, reg_info->kinds[eRegisterKindDWARF]); 1607e7708688STamas Berghammer 1608e7708688STamas Berghammer Error error = emulator_baton->m_reg_context->ReadRegister(full_reg_info, reg_value); 16096648fcc3SPavel Labath if (error.Success()) 16106648fcc3SPavel Labath return true; 1611cdc22a88SMohit K. Bhakkad 16126648fcc3SPavel Labath return false; 1613e7708688STamas Berghammer } 1614e7708688STamas Berghammer 1615e7708688STamas Berghammer static bool 1616e7708688STamas Berghammer WriteRegisterCallback (EmulateInstruction *instruction, 1617e7708688STamas Berghammer void *baton, 1618e7708688STamas Berghammer const EmulateInstruction::Context &context, 1619e7708688STamas Berghammer const RegisterInfo *reg_info, 1620e7708688STamas Berghammer const RegisterValue ®_value) 1621e7708688STamas Berghammer { 1622e7708688STamas Berghammer EmulatorBaton* emulator_baton = static_cast<EmulatorBaton*>(baton); 16236648fcc3SPavel Labath emulator_baton->m_register_values[reg_info->kinds[eRegisterKindDWARF]] = reg_value; 1624e7708688STamas Berghammer return true; 1625e7708688STamas Berghammer } 1626e7708688STamas Berghammer 1627e7708688STamas Berghammer static size_t 1628e7708688STamas Berghammer WriteMemoryCallback (EmulateInstruction *instruction, 1629e7708688STamas Berghammer void *baton, 1630e7708688STamas Berghammer const EmulateInstruction::Context &context, 1631e7708688STamas Berghammer lldb::addr_t addr, 1632e7708688STamas Berghammer const void *dst, 1633e7708688STamas Berghammer size_t length) 1634e7708688STamas Berghammer { 1635e7708688STamas Berghammer return length; 1636e7708688STamas Berghammer } 1637e7708688STamas Berghammer 1638e7708688STamas Berghammer static lldb::addr_t 1639e7708688STamas Berghammer ReadFlags (NativeRegisterContext* regsiter_context) 1640e7708688STamas Berghammer { 1641e7708688STamas Berghammer const RegisterInfo* flags_info = regsiter_context->GetRegisterInfo( 1642e7708688STamas Berghammer eRegisterKindGeneric, LLDB_REGNUM_GENERIC_FLAGS); 1643e7708688STamas Berghammer return regsiter_context->ReadRegisterAsUnsigned(flags_info, LLDB_INVALID_ADDRESS); 1644e7708688STamas Berghammer } 1645e7708688STamas Berghammer 1646e7708688STamas Berghammer Error 1647e7708688STamas Berghammer NativeProcessLinux::SetupSoftwareSingleStepping(NativeThreadProtocolSP thread_sp) 1648e7708688STamas Berghammer { 1649e7708688STamas Berghammer Error error; 1650e7708688STamas Berghammer NativeRegisterContextSP register_context_sp = thread_sp->GetRegisterContext(); 1651e7708688STamas Berghammer 1652e7708688STamas Berghammer std::unique_ptr<EmulateInstruction> emulator_ap( 1653e7708688STamas Berghammer EmulateInstruction::FindPlugin(m_arch, eInstructionTypePCModifying, nullptr)); 1654e7708688STamas Berghammer 1655e7708688STamas Berghammer if (emulator_ap == nullptr) 1656e7708688STamas Berghammer return Error("Instruction emulator not found!"); 1657e7708688STamas Berghammer 1658e7708688STamas Berghammer EmulatorBaton baton(this, register_context_sp.get()); 1659e7708688STamas Berghammer emulator_ap->SetBaton(&baton); 1660e7708688STamas Berghammer emulator_ap->SetReadMemCallback(&ReadMemoryCallback); 1661e7708688STamas Berghammer emulator_ap->SetReadRegCallback(&ReadRegisterCallback); 1662e7708688STamas Berghammer emulator_ap->SetWriteMemCallback(&WriteMemoryCallback); 1663e7708688STamas Berghammer emulator_ap->SetWriteRegCallback(&WriteRegisterCallback); 1664e7708688STamas Berghammer 1665e7708688STamas Berghammer if (!emulator_ap->ReadInstruction()) 1666e7708688STamas Berghammer return Error("Read instruction failed!"); 1667e7708688STamas Berghammer 16686648fcc3SPavel Labath bool emulation_result = emulator_ap->EvaluateInstruction(eEmulateInstructionOptionAutoAdvancePC); 16696648fcc3SPavel Labath 16706648fcc3SPavel Labath const RegisterInfo* reg_info_pc = register_context_sp->GetRegisterInfo(eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC); 16716648fcc3SPavel Labath const RegisterInfo* reg_info_flags = register_context_sp->GetRegisterInfo(eRegisterKindGeneric, LLDB_REGNUM_GENERIC_FLAGS); 16726648fcc3SPavel Labath 16736648fcc3SPavel Labath auto pc_it = baton.m_register_values.find(reg_info_pc->kinds[eRegisterKindDWARF]); 16746648fcc3SPavel Labath auto flags_it = baton.m_register_values.find(reg_info_flags->kinds[eRegisterKindDWARF]); 16756648fcc3SPavel Labath 1676e7708688STamas Berghammer lldb::addr_t next_pc; 1677e7708688STamas Berghammer lldb::addr_t next_flags; 16786648fcc3SPavel Labath if (emulation_result) 1679e7708688STamas Berghammer { 16806648fcc3SPavel Labath assert(pc_it != baton.m_register_values.end() && "Emulation was successfull but PC wasn't updated"); 16816648fcc3SPavel Labath next_pc = pc_it->second.GetAsUInt64(); 16826648fcc3SPavel Labath 16836648fcc3SPavel Labath if (flags_it != baton.m_register_values.end()) 16846648fcc3SPavel Labath next_flags = flags_it->second.GetAsUInt64(); 1685e7708688STamas Berghammer else 1686e7708688STamas Berghammer next_flags = ReadFlags (register_context_sp.get()); 1687e7708688STamas Berghammer } 16886648fcc3SPavel Labath else if (pc_it == baton.m_register_values.end()) 1689e7708688STamas Berghammer { 1690e7708688STamas Berghammer // Emulate instruction failed and it haven't changed PC. Advance PC 1691e7708688STamas Berghammer // with the size of the current opcode because the emulation of all 1692e7708688STamas Berghammer // PC modifying instruction should be successful. The failure most 1693e7708688STamas Berghammer // likely caused by a not supported instruction which don't modify PC. 1694e7708688STamas Berghammer next_pc = register_context_sp->GetPC() + emulator_ap->GetOpcode().GetByteSize(); 1695e7708688STamas Berghammer next_flags = ReadFlags (register_context_sp.get()); 1696e7708688STamas Berghammer } 1697e7708688STamas Berghammer else 1698e7708688STamas Berghammer { 1699e7708688STamas Berghammer // The instruction emulation failed after it modified the PC. It is an 1700e7708688STamas Berghammer // unknown error where we can't continue because the next instruction is 1701e7708688STamas Berghammer // modifying the PC but we don't know how. 1702e7708688STamas Berghammer return Error ("Instruction emulation failed unexpectedly."); 1703e7708688STamas Berghammer } 1704e7708688STamas Berghammer 1705e7708688STamas Berghammer if (m_arch.GetMachine() == llvm::Triple::arm) 1706e7708688STamas Berghammer { 1707e7708688STamas Berghammer if (next_flags & 0x20) 1708e7708688STamas Berghammer { 1709e7708688STamas Berghammer // Thumb mode 1710e7708688STamas Berghammer error = SetSoftwareBreakpoint(next_pc, 2); 1711e7708688STamas Berghammer } 1712e7708688STamas Berghammer else 1713e7708688STamas Berghammer { 1714e7708688STamas Berghammer // Arm mode 1715e7708688STamas Berghammer error = SetSoftwareBreakpoint(next_pc, 4); 1716e7708688STamas Berghammer } 1717e7708688STamas Berghammer } 1718cdc22a88SMohit K. Bhakkad else if (m_arch.GetMachine() == llvm::Triple::mips64 1719c60c9452SJaydeep Patil || m_arch.GetMachine() == llvm::Triple::mips64el 1720c60c9452SJaydeep Patil || m_arch.GetMachine() == llvm::Triple::mips 1721c60c9452SJaydeep Patil || m_arch.GetMachine() == llvm::Triple::mipsel) 1722cdc22a88SMohit K. Bhakkad error = SetSoftwareBreakpoint(next_pc, 4); 1723e7708688STamas Berghammer else 1724e7708688STamas Berghammer { 1725e7708688STamas Berghammer // No size hint is given for the next breakpoint 1726e7708688STamas Berghammer error = SetSoftwareBreakpoint(next_pc, 0); 1727e7708688STamas Berghammer } 1728e7708688STamas Berghammer 1729e7708688STamas Berghammer if (error.Fail()) 1730e7708688STamas Berghammer return error; 1731e7708688STamas Berghammer 1732e7708688STamas Berghammer m_threads_stepping_with_breakpoint.insert({thread_sp->GetID(), next_pc}); 1733e7708688STamas Berghammer 1734e7708688STamas Berghammer return Error(); 1735e7708688STamas Berghammer } 1736e7708688STamas Berghammer 1737e7708688STamas Berghammer bool 1738e7708688STamas Berghammer NativeProcessLinux::SupportHardwareSingleStepping() const 1739e7708688STamas Berghammer { 1740cdc22a88SMohit K. Bhakkad if (m_arch.GetMachine() == llvm::Triple::arm 1741c60c9452SJaydeep Patil || m_arch.GetMachine() == llvm::Triple::mips64 || m_arch.GetMachine() == llvm::Triple::mips64el 1742c60c9452SJaydeep Patil || m_arch.GetMachine() == llvm::Triple::mips || m_arch.GetMachine() == llvm::Triple::mipsel) 1743cdc22a88SMohit K. Bhakkad return false; 1744cdc22a88SMohit K. Bhakkad return true; 1745e7708688STamas Berghammer } 1746e7708688STamas Berghammer 1747af245d11STodd Fiala Error 1748af245d11STodd Fiala NativeProcessLinux::Resume (const ResumeActionList &resume_actions) 1749af245d11STodd Fiala { 1750af245d11STodd Fiala Log *log (GetLogIfAllCategoriesSet (LIBLLDB_LOG_PROCESS | LIBLLDB_LOG_THREAD)); 1751af245d11STodd Fiala if (log) 1752af245d11STodd Fiala log->Printf ("NativeProcessLinux::%s called: pid %" PRIu64, __FUNCTION__, GetID ()); 1753af245d11STodd Fiala 1754e7708688STamas Berghammer bool software_single_step = !SupportHardwareSingleStepping(); 1755af245d11STodd Fiala 1756af245d11STodd Fiala Mutex::Locker locker (m_threads_mutex); 17575830aa75STamas Berghammer 1758e7708688STamas Berghammer if (software_single_step) 1759e7708688STamas Berghammer { 1760e7708688STamas Berghammer for (auto thread_sp : m_threads) 1761e7708688STamas Berghammer { 1762e7708688STamas Berghammer assert (thread_sp && "thread list should not contain NULL threads"); 1763e7708688STamas Berghammer 1764e7708688STamas Berghammer const ResumeAction *const action = resume_actions.GetActionForThread (thread_sp->GetID (), true); 1765e7708688STamas Berghammer if (action == nullptr) 1766e7708688STamas Berghammer continue; 1767e7708688STamas Berghammer 1768e7708688STamas Berghammer if (action->state == eStateStepping) 1769e7708688STamas Berghammer { 1770e7708688STamas Berghammer Error error = SetupSoftwareSingleStepping(thread_sp); 1771e7708688STamas Berghammer if (error.Fail()) 1772e7708688STamas Berghammer return error; 1773e7708688STamas Berghammer } 1774e7708688STamas Berghammer } 1775e7708688STamas Berghammer } 1776e7708688STamas Berghammer 1777af245d11STodd Fiala for (auto thread_sp : m_threads) 1778af245d11STodd Fiala { 1779af245d11STodd Fiala assert (thread_sp && "thread list should not contain NULL threads"); 1780af245d11STodd Fiala 1781af245d11STodd Fiala const ResumeAction *const action = resume_actions.GetActionForThread (thread_sp->GetID (), true); 17826a196ce6SChaoren Lin 17836a196ce6SChaoren Lin if (action == nullptr) 17846a196ce6SChaoren Lin { 17856a196ce6SChaoren Lin if (log) 17866a196ce6SChaoren Lin log->Printf ("NativeProcessLinux::%s no action specified for pid %" PRIu64 " tid %" PRIu64, 17876a196ce6SChaoren Lin __FUNCTION__, GetID (), thread_sp->GetID ()); 17886a196ce6SChaoren Lin continue; 17896a196ce6SChaoren Lin } 1790af245d11STodd Fiala 1791af245d11STodd Fiala if (log) 1792af245d11STodd Fiala { 1793af245d11STodd Fiala log->Printf ("NativeProcessLinux::%s processing resume action state %s for pid %" PRIu64 " tid %" PRIu64, 1794af245d11STodd Fiala __FUNCTION__, StateAsCString (action->state), GetID (), thread_sp->GetID ()); 1795af245d11STodd Fiala } 1796af245d11STodd Fiala 1797af245d11STodd Fiala switch (action->state) 1798af245d11STodd Fiala { 1799af245d11STodd Fiala case eStateRunning: 1800*0e1d729bSPavel Labath case eStateStepping: 1801fa03ad2eSChaoren Lin { 1802af245d11STodd Fiala // Run the thread, possibly feeding it the signal. 1803fa03ad2eSChaoren Lin const int signo = action->signal; 1804*0e1d729bSPavel Labath ResumeThread(std::static_pointer_cast<NativeThreadLinux>(thread_sp), action->state, signo); 1805af245d11STodd Fiala break; 1806ae29d395SChaoren Lin } 1807af245d11STodd Fiala 1808af245d11STodd Fiala case eStateSuspended: 1809af245d11STodd Fiala case eStateStopped: 1810108c325dSPavel Labath lldbassert(0 && "Unexpected state"); 1811af245d11STodd Fiala 1812af245d11STodd Fiala default: 1813af245d11STodd Fiala return Error ("NativeProcessLinux::%s (): unexpected state %s specified for pid %" PRIu64 ", tid %" PRIu64, 1814af245d11STodd Fiala __FUNCTION__, StateAsCString (action->state), GetID (), thread_sp->GetID ()); 1815af245d11STodd Fiala } 1816af245d11STodd Fiala } 1817af245d11STodd Fiala 18185830aa75STamas Berghammer return Error(); 1819af245d11STodd Fiala } 1820af245d11STodd Fiala 1821af245d11STodd Fiala Error 1822af245d11STodd Fiala NativeProcessLinux::Halt () 1823af245d11STodd Fiala { 1824af245d11STodd Fiala Error error; 1825af245d11STodd Fiala 1826af245d11STodd Fiala if (kill (GetID (), SIGSTOP) != 0) 1827af245d11STodd Fiala error.SetErrorToErrno (); 1828af245d11STodd Fiala 1829af245d11STodd Fiala return error; 1830af245d11STodd Fiala } 1831af245d11STodd Fiala 1832af245d11STodd Fiala Error 1833af245d11STodd Fiala NativeProcessLinux::Detach () 1834af245d11STodd Fiala { 1835af245d11STodd Fiala Error error; 1836af245d11STodd Fiala 1837af245d11STodd Fiala // Tell ptrace to detach from the process. 1838af245d11STodd Fiala if (GetID () != LLDB_INVALID_PROCESS_ID) 1839af245d11STodd Fiala error = Detach (GetID ()); 1840af245d11STodd Fiala 1841af245d11STodd Fiala // Stop monitoring the inferior. 184219cbe96aSPavel Labath m_sigchld_handle.reset(); 1843af245d11STodd Fiala 1844af245d11STodd Fiala // No error. 1845af245d11STodd Fiala return error; 1846af245d11STodd Fiala } 1847af245d11STodd Fiala 1848af245d11STodd Fiala Error 1849af245d11STodd Fiala NativeProcessLinux::Signal (int signo) 1850af245d11STodd Fiala { 1851af245d11STodd Fiala Error error; 1852af245d11STodd Fiala 1853af245d11STodd Fiala Log *log (GetLogIfAllCategoriesSet (LIBLLDB_LOG_PROCESS)); 1854af245d11STodd Fiala if (log) 1855af245d11STodd Fiala log->Printf ("NativeProcessLinux::%s: sending signal %d (%s) to pid %" PRIu64, 185698d0a4b3SChaoren Lin __FUNCTION__, signo, Host::GetSignalAsCString(signo), GetID()); 1857af245d11STodd Fiala 1858af245d11STodd Fiala if (kill(GetID(), signo)) 1859af245d11STodd Fiala error.SetErrorToErrno(); 1860af245d11STodd Fiala 1861af245d11STodd Fiala return error; 1862af245d11STodd Fiala } 1863af245d11STodd Fiala 1864af245d11STodd Fiala Error 1865e9547b80SChaoren Lin NativeProcessLinux::Interrupt () 1866e9547b80SChaoren Lin { 1867e9547b80SChaoren Lin // Pick a running thread (or if none, a not-dead stopped thread) as 1868e9547b80SChaoren Lin // the chosen thread that will be the stop-reason thread. 1869e9547b80SChaoren Lin Log *log (GetLogIfAllCategoriesSet (LIBLLDB_LOG_PROCESS)); 1870e9547b80SChaoren Lin 1871e9547b80SChaoren Lin NativeThreadProtocolSP running_thread_sp; 1872e9547b80SChaoren Lin NativeThreadProtocolSP stopped_thread_sp; 1873e9547b80SChaoren Lin 1874e9547b80SChaoren Lin if (log) 1875e9547b80SChaoren Lin log->Printf ("NativeProcessLinux::%s selecting running thread for interrupt target", __FUNCTION__); 1876e9547b80SChaoren Lin 18775830aa75STamas Berghammer Mutex::Locker locker (m_threads_mutex); 18785830aa75STamas Berghammer 1879e9547b80SChaoren Lin for (auto thread_sp : m_threads) 1880e9547b80SChaoren Lin { 1881e9547b80SChaoren Lin // The thread shouldn't be null but lets just cover that here. 1882e9547b80SChaoren Lin if (!thread_sp) 1883e9547b80SChaoren Lin continue; 1884e9547b80SChaoren Lin 1885e9547b80SChaoren Lin // If we have a running or stepping thread, we'll call that the 1886e9547b80SChaoren Lin // target of the interrupt. 1887e9547b80SChaoren Lin const auto thread_state = thread_sp->GetState (); 1888e9547b80SChaoren Lin if (thread_state == eStateRunning || 1889e9547b80SChaoren Lin thread_state == eStateStepping) 1890e9547b80SChaoren Lin { 1891e9547b80SChaoren Lin running_thread_sp = thread_sp; 1892e9547b80SChaoren Lin break; 1893e9547b80SChaoren Lin } 1894e9547b80SChaoren Lin else if (!stopped_thread_sp && StateIsStoppedState (thread_state, true)) 1895e9547b80SChaoren Lin { 1896e9547b80SChaoren Lin // Remember the first non-dead stopped thread. We'll use that as a backup if there are no running threads. 1897e9547b80SChaoren Lin stopped_thread_sp = thread_sp; 1898e9547b80SChaoren Lin } 1899e9547b80SChaoren Lin } 1900e9547b80SChaoren Lin 1901e9547b80SChaoren Lin if (!running_thread_sp && !stopped_thread_sp) 1902e9547b80SChaoren Lin { 19035830aa75STamas Berghammer Error error("found no running/stepping or live stopped threads as target for interrupt"); 1904e9547b80SChaoren Lin if (log) 1905e9547b80SChaoren Lin log->Printf ("NativeProcessLinux::%s skipping due to error: %s", __FUNCTION__, error.AsCString ()); 19065830aa75STamas Berghammer 1907e9547b80SChaoren Lin return error; 1908e9547b80SChaoren Lin } 1909e9547b80SChaoren Lin 1910e9547b80SChaoren Lin NativeThreadProtocolSP deferred_signal_thread_sp = running_thread_sp ? running_thread_sp : stopped_thread_sp; 1911e9547b80SChaoren Lin 1912e9547b80SChaoren Lin if (log) 1913e9547b80SChaoren Lin log->Printf ("NativeProcessLinux::%s pid %" PRIu64 " %s tid %" PRIu64 " chosen for interrupt target", 1914e9547b80SChaoren Lin __FUNCTION__, 1915e9547b80SChaoren Lin GetID (), 1916e9547b80SChaoren Lin running_thread_sp ? "running" : "stopped", 1917e9547b80SChaoren Lin deferred_signal_thread_sp->GetID ()); 1918e9547b80SChaoren Lin 1919ed89c7feSPavel Labath StopRunningThreads(deferred_signal_thread_sp->GetID()); 192045f5cb31SPavel Labath 19215830aa75STamas Berghammer return Error(); 1922e9547b80SChaoren Lin } 1923e9547b80SChaoren Lin 1924e9547b80SChaoren Lin Error 1925af245d11STodd Fiala NativeProcessLinux::Kill () 1926af245d11STodd Fiala { 1927af245d11STodd Fiala Log *log (GetLogIfAllCategoriesSet (LIBLLDB_LOG_PROCESS)); 1928af245d11STodd Fiala if (log) 1929af245d11STodd Fiala log->Printf ("NativeProcessLinux::%s called for PID %" PRIu64, __FUNCTION__, GetID ()); 1930af245d11STodd Fiala 1931af245d11STodd Fiala Error error; 1932af245d11STodd Fiala 1933af245d11STodd Fiala switch (m_state) 1934af245d11STodd Fiala { 1935af245d11STodd Fiala case StateType::eStateInvalid: 1936af245d11STodd Fiala case StateType::eStateExited: 1937af245d11STodd Fiala case StateType::eStateCrashed: 1938af245d11STodd Fiala case StateType::eStateDetached: 1939af245d11STodd Fiala case StateType::eStateUnloaded: 1940af245d11STodd Fiala // Nothing to do - the process is already dead. 1941af245d11STodd Fiala if (log) 1942af245d11STodd Fiala log->Printf ("NativeProcessLinux::%s ignored for PID %" PRIu64 " due to current state: %s", __FUNCTION__, GetID (), StateAsCString (m_state)); 1943af245d11STodd Fiala return error; 1944af245d11STodd Fiala 1945af245d11STodd Fiala case StateType::eStateConnected: 1946af245d11STodd Fiala case StateType::eStateAttaching: 1947af245d11STodd Fiala case StateType::eStateLaunching: 1948af245d11STodd Fiala case StateType::eStateStopped: 1949af245d11STodd Fiala case StateType::eStateRunning: 1950af245d11STodd Fiala case StateType::eStateStepping: 1951af245d11STodd Fiala case StateType::eStateSuspended: 1952af245d11STodd Fiala // We can try to kill a process in these states. 1953af245d11STodd Fiala break; 1954af245d11STodd Fiala } 1955af245d11STodd Fiala 1956af245d11STodd Fiala if (kill (GetID (), SIGKILL) != 0) 1957af245d11STodd Fiala { 1958af245d11STodd Fiala error.SetErrorToErrno (); 1959af245d11STodd Fiala return error; 1960af245d11STodd Fiala } 1961af245d11STodd Fiala 1962af245d11STodd Fiala return error; 1963af245d11STodd Fiala } 1964af245d11STodd Fiala 1965af245d11STodd Fiala static Error 1966af245d11STodd Fiala ParseMemoryRegionInfoFromProcMapsLine (const std::string &maps_line, MemoryRegionInfo &memory_region_info) 1967af245d11STodd Fiala { 1968af245d11STodd Fiala memory_region_info.Clear(); 1969af245d11STodd Fiala 1970af245d11STodd Fiala StringExtractor line_extractor (maps_line.c_str ()); 1971af245d11STodd Fiala 1972af245d11STodd Fiala // Format: {address_start_hex}-{address_end_hex} perms offset dev inode pathname 1973af245d11STodd Fiala // perms: rwxp (letter is present if set, '-' if not, final character is p=private, s=shared). 1974af245d11STodd Fiala 1975af245d11STodd Fiala // Parse out the starting address 1976af245d11STodd Fiala lldb::addr_t start_address = line_extractor.GetHexMaxU64 (false, 0); 1977af245d11STodd Fiala 1978af245d11STodd Fiala // Parse out hyphen separating start and end address from range. 1979af245d11STodd Fiala if (!line_extractor.GetBytesLeft () || (line_extractor.GetChar () != '-')) 1980af245d11STodd Fiala return Error ("malformed /proc/{pid}/maps entry, missing dash between address range"); 1981af245d11STodd Fiala 1982af245d11STodd Fiala // Parse out the ending address 1983af245d11STodd Fiala lldb::addr_t end_address = line_extractor.GetHexMaxU64 (false, start_address); 1984af245d11STodd Fiala 1985af245d11STodd Fiala // Parse out the space after the address. 1986af245d11STodd Fiala if (!line_extractor.GetBytesLeft () || (line_extractor.GetChar () != ' ')) 1987af245d11STodd Fiala return Error ("malformed /proc/{pid}/maps entry, missing space after range"); 1988af245d11STodd Fiala 1989af245d11STodd Fiala // Save the range. 1990af245d11STodd Fiala memory_region_info.GetRange ().SetRangeBase (start_address); 1991af245d11STodd Fiala memory_region_info.GetRange ().SetRangeEnd (end_address); 1992af245d11STodd Fiala 1993af245d11STodd Fiala // Parse out each permission entry. 1994af245d11STodd Fiala if (line_extractor.GetBytesLeft () < 4) 1995af245d11STodd Fiala return Error ("malformed /proc/{pid}/maps entry, missing some portion of permissions"); 1996af245d11STodd Fiala 1997af245d11STodd Fiala // Handle read permission. 1998af245d11STodd Fiala const char read_perm_char = line_extractor.GetChar (); 1999af245d11STodd Fiala if (read_perm_char == 'r') 2000af245d11STodd Fiala memory_region_info.SetReadable (MemoryRegionInfo::OptionalBool::eYes); 2001af245d11STodd Fiala else 2002af245d11STodd Fiala { 2003af245d11STodd Fiala assert ( (read_perm_char == '-') && "unexpected /proc/{pid}/maps read permission char" ); 2004af245d11STodd Fiala memory_region_info.SetReadable (MemoryRegionInfo::OptionalBool::eNo); 2005af245d11STodd Fiala } 2006af245d11STodd Fiala 2007af245d11STodd Fiala // Handle write permission. 2008af245d11STodd Fiala const char write_perm_char = line_extractor.GetChar (); 2009af245d11STodd Fiala if (write_perm_char == 'w') 2010af245d11STodd Fiala memory_region_info.SetWritable (MemoryRegionInfo::OptionalBool::eYes); 2011af245d11STodd Fiala else 2012af245d11STodd Fiala { 2013af245d11STodd Fiala assert ( (write_perm_char == '-') && "unexpected /proc/{pid}/maps write permission char" ); 2014af245d11STodd Fiala memory_region_info.SetWritable (MemoryRegionInfo::OptionalBool::eNo); 2015af245d11STodd Fiala } 2016af245d11STodd Fiala 2017af245d11STodd Fiala // Handle execute permission. 2018af245d11STodd Fiala const char exec_perm_char = line_extractor.GetChar (); 2019af245d11STodd Fiala if (exec_perm_char == 'x') 2020af245d11STodd Fiala memory_region_info.SetExecutable (MemoryRegionInfo::OptionalBool::eYes); 2021af245d11STodd Fiala else 2022af245d11STodd Fiala { 2023af245d11STodd Fiala assert ( (exec_perm_char == '-') && "unexpected /proc/{pid}/maps exec permission char" ); 2024af245d11STodd Fiala memory_region_info.SetExecutable (MemoryRegionInfo::OptionalBool::eNo); 2025af245d11STodd Fiala } 2026af245d11STodd Fiala 2027af245d11STodd Fiala return Error (); 2028af245d11STodd Fiala } 2029af245d11STodd Fiala 2030af245d11STodd Fiala Error 2031af245d11STodd Fiala NativeProcessLinux::GetMemoryRegionInfo (lldb::addr_t load_addr, MemoryRegionInfo &range_info) 2032af245d11STodd Fiala { 2033af245d11STodd Fiala // FIXME review that the final memory region returned extends to the end of the virtual address space, 2034af245d11STodd Fiala // with no perms if it is not mapped. 2035af245d11STodd Fiala 2036af245d11STodd Fiala // Use an approach that reads memory regions from /proc/{pid}/maps. 2037af245d11STodd Fiala // Assume proc maps entries are in ascending order. 2038af245d11STodd Fiala // FIXME assert if we find differently. 2039af245d11STodd Fiala Mutex::Locker locker (m_mem_region_cache_mutex); 2040af245d11STodd Fiala 2041af245d11STodd Fiala Log *log (GetLogIfAllCategoriesSet (LIBLLDB_LOG_PROCESS)); 2042af245d11STodd Fiala Error error; 2043af245d11STodd Fiala 2044af245d11STodd Fiala if (m_supports_mem_region == LazyBool::eLazyBoolNo) 2045af245d11STodd Fiala { 2046af245d11STodd Fiala // We're done. 2047af245d11STodd Fiala error.SetErrorString ("unsupported"); 2048af245d11STodd Fiala return error; 2049af245d11STodd Fiala } 2050af245d11STodd Fiala 2051af245d11STodd Fiala // If our cache is empty, pull the latest. There should always be at least one memory region 2052af245d11STodd Fiala // if memory region handling is supported. 2053af245d11STodd Fiala if (m_mem_region_cache.empty ()) 2054af245d11STodd Fiala { 2055af245d11STodd Fiala error = ProcFileReader::ProcessLineByLine (GetID (), "maps", 2056af245d11STodd Fiala [&] (const std::string &line) -> bool 2057af245d11STodd Fiala { 2058af245d11STodd Fiala MemoryRegionInfo info; 2059af245d11STodd Fiala const Error parse_error = ParseMemoryRegionInfoFromProcMapsLine (line, info); 2060af245d11STodd Fiala if (parse_error.Success ()) 2061af245d11STodd Fiala { 2062af245d11STodd Fiala m_mem_region_cache.push_back (info); 2063af245d11STodd Fiala return true; 2064af245d11STodd Fiala } 2065af245d11STodd Fiala else 2066af245d11STodd Fiala { 2067af245d11STodd Fiala if (log) 2068af245d11STodd Fiala log->Printf ("NativeProcessLinux::%s failed to parse proc maps line '%s': %s", __FUNCTION__, line.c_str (), error.AsCString ()); 2069af245d11STodd Fiala return false; 2070af245d11STodd Fiala } 2071af245d11STodd Fiala }); 2072af245d11STodd Fiala 2073af245d11STodd Fiala // If we had an error, we'll mark unsupported. 2074af245d11STodd Fiala if (error.Fail ()) 2075af245d11STodd Fiala { 2076af245d11STodd Fiala m_supports_mem_region = LazyBool::eLazyBoolNo; 2077af245d11STodd Fiala return error; 2078af245d11STodd Fiala } 2079af245d11STodd Fiala else if (m_mem_region_cache.empty ()) 2080af245d11STodd Fiala { 2081af245d11STodd Fiala // No entries after attempting to read them. This shouldn't happen if /proc/{pid}/maps 2082af245d11STodd Fiala // is supported. Assume we don't support map entries via procfs. 2083af245d11STodd Fiala if (log) 2084af245d11STodd Fiala log->Printf ("NativeProcessLinux::%s failed to find any procfs maps entries, assuming no support for memory region metadata retrieval", __FUNCTION__); 2085af245d11STodd Fiala m_supports_mem_region = LazyBool::eLazyBoolNo; 2086af245d11STodd Fiala error.SetErrorString ("not supported"); 2087af245d11STodd Fiala return error; 2088af245d11STodd Fiala } 2089af245d11STodd Fiala 2090af245d11STodd Fiala if (log) 2091af245d11STodd Fiala log->Printf ("NativeProcessLinux::%s read %" PRIu64 " memory region entries from /proc/%" PRIu64 "/maps", __FUNCTION__, static_cast<uint64_t> (m_mem_region_cache.size ()), GetID ()); 2092af245d11STodd Fiala 2093af245d11STodd Fiala // We support memory retrieval, remember that. 2094af245d11STodd Fiala m_supports_mem_region = LazyBool::eLazyBoolYes; 2095af245d11STodd Fiala } 2096af245d11STodd Fiala else 2097af245d11STodd Fiala { 2098af245d11STodd Fiala if (log) 2099af245d11STodd Fiala log->Printf ("NativeProcessLinux::%s reusing %" PRIu64 " cached memory region entries", __FUNCTION__, static_cast<uint64_t> (m_mem_region_cache.size ())); 2100af245d11STodd Fiala } 2101af245d11STodd Fiala 2102af245d11STodd Fiala lldb::addr_t prev_base_address = 0; 2103af245d11STodd Fiala 2104af245d11STodd Fiala // FIXME start by finding the last region that is <= target address using binary search. Data is sorted. 2105af245d11STodd Fiala // There can be a ton of regions on pthreads apps with lots of threads. 2106af245d11STodd Fiala for (auto it = m_mem_region_cache.begin(); it != m_mem_region_cache.end (); ++it) 2107af245d11STodd Fiala { 2108af245d11STodd Fiala MemoryRegionInfo &proc_entry_info = *it; 2109af245d11STodd Fiala 2110af245d11STodd Fiala // Sanity check assumption that /proc/{pid}/maps entries are ascending. 2111af245d11STodd Fiala assert ((proc_entry_info.GetRange ().GetRangeBase () >= prev_base_address) && "descending /proc/pid/maps entries detected, unexpected"); 2112af245d11STodd Fiala prev_base_address = proc_entry_info.GetRange ().GetRangeBase (); 2113af245d11STodd Fiala 2114af245d11STodd Fiala // If the target address comes before this entry, indicate distance to next region. 2115af245d11STodd Fiala if (load_addr < proc_entry_info.GetRange ().GetRangeBase ()) 2116af245d11STodd Fiala { 2117af245d11STodd Fiala range_info.GetRange ().SetRangeBase (load_addr); 2118af245d11STodd Fiala range_info.GetRange ().SetByteSize (proc_entry_info.GetRange ().GetRangeBase () - load_addr); 2119af245d11STodd Fiala range_info.SetReadable (MemoryRegionInfo::OptionalBool::eNo); 2120af245d11STodd Fiala range_info.SetWritable (MemoryRegionInfo::OptionalBool::eNo); 2121af245d11STodd Fiala range_info.SetExecutable (MemoryRegionInfo::OptionalBool::eNo); 2122af245d11STodd Fiala 2123af245d11STodd Fiala return error; 2124af245d11STodd Fiala } 2125af245d11STodd Fiala else if (proc_entry_info.GetRange ().Contains (load_addr)) 2126af245d11STodd Fiala { 2127af245d11STodd Fiala // The target address is within the memory region we're processing here. 2128af245d11STodd Fiala range_info = proc_entry_info; 2129af245d11STodd Fiala return error; 2130af245d11STodd Fiala } 2131af245d11STodd Fiala 2132af245d11STodd Fiala // The target memory address comes somewhere after the region we just parsed. 2133af245d11STodd Fiala } 2134af245d11STodd Fiala 213509839c33STamas Berghammer // If we made it here, we didn't find an entry that contained the given address. Return the 213609839c33STamas Berghammer // load_addr as start and the amount of bytes betwwen load address and the end of the memory as 213709839c33STamas Berghammer // size. 213809839c33STamas Berghammer range_info.GetRange ().SetRangeBase (load_addr); 213909839c33STamas Berghammer switch (m_arch.GetAddressByteSize()) 214009839c33STamas Berghammer { 214109839c33STamas Berghammer case 4: 214209839c33STamas Berghammer range_info.GetRange ().SetByteSize (0x100000000ull - load_addr); 214309839c33STamas Berghammer break; 214409839c33STamas Berghammer case 8: 214509839c33STamas Berghammer range_info.GetRange ().SetByteSize (0ull - load_addr); 214609839c33STamas Berghammer break; 214709839c33STamas Berghammer default: 214809839c33STamas Berghammer assert(false && "Unrecognized data byte size"); 214909839c33STamas Berghammer break; 215009839c33STamas Berghammer } 215109839c33STamas Berghammer range_info.SetReadable (MemoryRegionInfo::OptionalBool::eNo); 215209839c33STamas Berghammer range_info.SetWritable (MemoryRegionInfo::OptionalBool::eNo); 215309839c33STamas Berghammer range_info.SetExecutable (MemoryRegionInfo::OptionalBool::eNo); 2154af245d11STodd Fiala return error; 2155af245d11STodd Fiala } 2156af245d11STodd Fiala 2157af245d11STodd Fiala void 2158af245d11STodd Fiala NativeProcessLinux::DoStopIDBumped (uint32_t newBumpId) 2159af245d11STodd Fiala { 2160af245d11STodd Fiala Log *log (GetLogIfAllCategoriesSet (LIBLLDB_LOG_PROCESS)); 2161af245d11STodd Fiala if (log) 2162af245d11STodd Fiala log->Printf ("NativeProcessLinux::%s(newBumpId=%" PRIu32 ") called", __FUNCTION__, newBumpId); 2163af245d11STodd Fiala 2164af245d11STodd Fiala { 2165af245d11STodd Fiala Mutex::Locker locker (m_mem_region_cache_mutex); 2166af245d11STodd Fiala if (log) 2167af245d11STodd Fiala log->Printf ("NativeProcessLinux::%s clearing %" PRIu64 " entries from the cache", __FUNCTION__, static_cast<uint64_t> (m_mem_region_cache.size ())); 2168af245d11STodd Fiala m_mem_region_cache.clear (); 2169af245d11STodd Fiala } 2170af245d11STodd Fiala } 2171af245d11STodd Fiala 2172af245d11STodd Fiala Error 21733eb4b458SChaoren Lin NativeProcessLinux::AllocateMemory(size_t size, uint32_t permissions, lldb::addr_t &addr) 2174af245d11STodd Fiala { 2175af245d11STodd Fiala // FIXME implementing this requires the equivalent of 2176af245d11STodd Fiala // InferiorCallPOSIX::InferiorCallMmap, which depends on 2177af245d11STodd Fiala // functional ThreadPlans working with Native*Protocol. 2178af245d11STodd Fiala #if 1 2179af245d11STodd Fiala return Error ("not implemented yet"); 2180af245d11STodd Fiala #else 2181af245d11STodd Fiala addr = LLDB_INVALID_ADDRESS; 2182af245d11STodd Fiala 2183af245d11STodd Fiala unsigned prot = 0; 2184af245d11STodd Fiala if (permissions & lldb::ePermissionsReadable) 2185af245d11STodd Fiala prot |= eMmapProtRead; 2186af245d11STodd Fiala if (permissions & lldb::ePermissionsWritable) 2187af245d11STodd Fiala prot |= eMmapProtWrite; 2188af245d11STodd Fiala if (permissions & lldb::ePermissionsExecutable) 2189af245d11STodd Fiala prot |= eMmapProtExec; 2190af245d11STodd Fiala 2191af245d11STodd Fiala // TODO implement this directly in NativeProcessLinux 2192af245d11STodd Fiala // (and lift to NativeProcessPOSIX if/when that class is 2193af245d11STodd Fiala // refactored out). 2194af245d11STodd Fiala if (InferiorCallMmap(this, addr, 0, size, prot, 2195af245d11STodd Fiala eMmapFlagsAnon | eMmapFlagsPrivate, -1, 0)) { 2196af245d11STodd Fiala m_addr_to_mmap_size[addr] = size; 2197af245d11STodd Fiala return Error (); 2198af245d11STodd Fiala } else { 2199af245d11STodd Fiala addr = LLDB_INVALID_ADDRESS; 2200af245d11STodd Fiala return Error("unable to allocate %" PRIu64 " bytes of memory with permissions %s", size, GetPermissionsAsCString (permissions)); 2201af245d11STodd Fiala } 2202af245d11STodd Fiala #endif 2203af245d11STodd Fiala } 2204af245d11STodd Fiala 2205af245d11STodd Fiala Error 2206af245d11STodd Fiala NativeProcessLinux::DeallocateMemory (lldb::addr_t addr) 2207af245d11STodd Fiala { 2208af245d11STodd Fiala // FIXME see comments in AllocateMemory - required lower-level 2209af245d11STodd Fiala // bits not in place yet (ThreadPlans) 2210af245d11STodd Fiala return Error ("not implemented"); 2211af245d11STodd Fiala } 2212af245d11STodd Fiala 2213af245d11STodd Fiala lldb::addr_t 2214af245d11STodd Fiala NativeProcessLinux::GetSharedLibraryInfoAddress () 2215af245d11STodd Fiala { 2216af245d11STodd Fiala #if 1 2217af245d11STodd Fiala // punt on this for now 2218af245d11STodd Fiala return LLDB_INVALID_ADDRESS; 2219af245d11STodd Fiala #else 2220af245d11STodd Fiala // Return the image info address for the exe module 2221af245d11STodd Fiala #if 1 2222af245d11STodd Fiala Log *log (GetLogIfAllCategoriesSet (LIBLLDB_LOG_PROCESS)); 2223af245d11STodd Fiala 2224af245d11STodd Fiala ModuleSP module_sp; 2225af245d11STodd Fiala Error error = GetExeModuleSP (module_sp); 2226af245d11STodd Fiala if (error.Fail ()) 2227af245d11STodd Fiala { 2228af245d11STodd Fiala if (log) 2229af245d11STodd Fiala log->Warning ("NativeProcessLinux::%s failed to retrieve exe module: %s", __FUNCTION__, error.AsCString ()); 2230af245d11STodd Fiala return LLDB_INVALID_ADDRESS; 2231af245d11STodd Fiala } 2232af245d11STodd Fiala 2233af245d11STodd Fiala if (module_sp == nullptr) 2234af245d11STodd Fiala { 2235af245d11STodd Fiala if (log) 2236af245d11STodd Fiala log->Warning ("NativeProcessLinux::%s exe module returned was NULL", __FUNCTION__); 2237af245d11STodd Fiala return LLDB_INVALID_ADDRESS; 2238af245d11STodd Fiala } 2239af245d11STodd Fiala 2240af245d11STodd Fiala ObjectFileSP object_file_sp = module_sp->GetObjectFile (); 2241af245d11STodd Fiala if (object_file_sp == nullptr) 2242af245d11STodd Fiala { 2243af245d11STodd Fiala if (log) 2244af245d11STodd Fiala log->Warning ("NativeProcessLinux::%s exe module returned a NULL object file", __FUNCTION__); 2245af245d11STodd Fiala return LLDB_INVALID_ADDRESS; 2246af245d11STodd Fiala } 2247af245d11STodd Fiala 2248af245d11STodd Fiala return obj_file_sp->GetImageInfoAddress(); 2249af245d11STodd Fiala #else 2250af245d11STodd Fiala Target *target = &GetTarget(); 2251af245d11STodd Fiala ObjectFile *obj_file = target->GetExecutableModule()->GetObjectFile(); 2252af245d11STodd Fiala Address addr = obj_file->GetImageInfoAddress(target); 2253af245d11STodd Fiala 2254af245d11STodd Fiala if (addr.IsValid()) 2255af245d11STodd Fiala return addr.GetLoadAddress(target); 2256af245d11STodd Fiala return LLDB_INVALID_ADDRESS; 2257af245d11STodd Fiala #endif 2258af245d11STodd Fiala #endif // punt on this for now 2259af245d11STodd Fiala } 2260af245d11STodd Fiala 2261af245d11STodd Fiala size_t 2262af245d11STodd Fiala NativeProcessLinux::UpdateThreads () 2263af245d11STodd Fiala { 2264af245d11STodd Fiala // The NativeProcessLinux monitoring threads are always up to date 2265af245d11STodd Fiala // with respect to thread state and they keep the thread list 2266af245d11STodd Fiala // populated properly. All this method needs to do is return the 2267af245d11STodd Fiala // thread count. 2268af245d11STodd Fiala Mutex::Locker locker (m_threads_mutex); 2269af245d11STodd Fiala return m_threads.size (); 2270af245d11STodd Fiala } 2271af245d11STodd Fiala 2272af245d11STodd Fiala bool 2273af245d11STodd Fiala NativeProcessLinux::GetArchitecture (ArchSpec &arch) const 2274af245d11STodd Fiala { 2275af245d11STodd Fiala arch = m_arch; 2276af245d11STodd Fiala return true; 2277af245d11STodd Fiala } 2278af245d11STodd Fiala 2279af245d11STodd Fiala Error 228063c8be95STamas Berghammer NativeProcessLinux::GetSoftwareBreakpointPCOffset (NativeRegisterContextSP context_sp, uint32_t &actual_opcode_size) 2281af245d11STodd Fiala { 2282af245d11STodd Fiala // FIXME put this behind a breakpoint protocol class that can be 2283af245d11STodd Fiala // set per architecture. Need ARM, MIPS support here. 2284af245d11STodd Fiala static const uint8_t g_i386_opcode [] = { 0xCC }; 2285af245d11STodd Fiala 2286af245d11STodd Fiala switch (m_arch.GetMachine ()) 2287af245d11STodd Fiala { 2288af245d11STodd Fiala case llvm::Triple::x86: 2289af245d11STodd Fiala case llvm::Triple::x86_64: 2290af245d11STodd Fiala actual_opcode_size = static_cast<uint32_t> (sizeof(g_i386_opcode)); 2291af245d11STodd Fiala return Error (); 2292af245d11STodd Fiala 2293ff7fd900STamas Berghammer case llvm::Triple::arm: 2294ff7fd900STamas Berghammer case llvm::Triple::aarch64: 2295e8659b5dSMohit K. Bhakkad case llvm::Triple::mips64: 2296e8659b5dSMohit K. Bhakkad case llvm::Triple::mips64el: 2297ce815e45SSagar Thakur case llvm::Triple::mips: 2298ce815e45SSagar Thakur case llvm::Triple::mipsel: 2299ff7fd900STamas Berghammer // On these architectures the PC don't get updated for breakpoint hits 2300c60c9452SJaydeep Patil actual_opcode_size = 0; 2301e8659b5dSMohit K. Bhakkad return Error (); 2302e8659b5dSMohit K. Bhakkad 2303af245d11STodd Fiala default: 2304af245d11STodd Fiala assert(false && "CPU type not supported!"); 2305af245d11STodd Fiala return Error ("CPU type not supported"); 2306af245d11STodd Fiala } 2307af245d11STodd Fiala } 2308af245d11STodd Fiala 2309af245d11STodd Fiala Error 2310af245d11STodd Fiala NativeProcessLinux::SetBreakpoint (lldb::addr_t addr, uint32_t size, bool hardware) 2311af245d11STodd Fiala { 2312af245d11STodd Fiala if (hardware) 2313af245d11STodd Fiala return Error ("NativeProcessLinux does not support hardware breakpoints"); 2314af245d11STodd Fiala else 2315af245d11STodd Fiala return SetSoftwareBreakpoint (addr, size); 2316af245d11STodd Fiala } 2317af245d11STodd Fiala 2318af245d11STodd Fiala Error 231963c8be95STamas Berghammer NativeProcessLinux::GetSoftwareBreakpointTrapOpcode (size_t trap_opcode_size_hint, 232063c8be95STamas Berghammer size_t &actual_opcode_size, 232163c8be95STamas Berghammer const uint8_t *&trap_opcode_bytes) 2322af245d11STodd Fiala { 232363c8be95STamas Berghammer // FIXME put this behind a breakpoint protocol class that can be set per 232463c8be95STamas Berghammer // architecture. Need MIPS support here. 23252afc5966STodd Fiala static const uint8_t g_aarch64_opcode[] = { 0x00, 0x00, 0x20, 0xd4 }; 232663c8be95STamas Berghammer // The ARM reference recommends the use of 0xe7fddefe and 0xdefe but the 232763c8be95STamas Berghammer // linux kernel does otherwise. 232863c8be95STamas Berghammer static const uint8_t g_arm_breakpoint_opcode[] = { 0xf0, 0x01, 0xf0, 0xe7 }; 2329af245d11STodd Fiala static const uint8_t g_i386_opcode [] = { 0xCC }; 23303df471c3SMohit K. Bhakkad static const uint8_t g_mips64_opcode[] = { 0x00, 0x00, 0x00, 0x0d }; 23312c2acf96SMohit K. Bhakkad static const uint8_t g_mips64el_opcode[] = { 0x0d, 0x00, 0x00, 0x00 }; 233263c8be95STamas Berghammer static const uint8_t g_thumb_breakpoint_opcode[] = { 0x01, 0xde }; 2333af245d11STodd Fiala 2334af245d11STodd Fiala switch (m_arch.GetMachine ()) 2335af245d11STodd Fiala { 23362afc5966STodd Fiala case llvm::Triple::aarch64: 23372afc5966STodd Fiala trap_opcode_bytes = g_aarch64_opcode; 23382afc5966STodd Fiala actual_opcode_size = sizeof(g_aarch64_opcode); 23392afc5966STodd Fiala return Error (); 23402afc5966STodd Fiala 234163c8be95STamas Berghammer case llvm::Triple::arm: 234263c8be95STamas Berghammer switch (trap_opcode_size_hint) 234363c8be95STamas Berghammer { 234463c8be95STamas Berghammer case 2: 234563c8be95STamas Berghammer trap_opcode_bytes = g_thumb_breakpoint_opcode; 234663c8be95STamas Berghammer actual_opcode_size = sizeof(g_thumb_breakpoint_opcode); 234763c8be95STamas Berghammer return Error (); 234863c8be95STamas Berghammer case 4: 234963c8be95STamas Berghammer trap_opcode_bytes = g_arm_breakpoint_opcode; 235063c8be95STamas Berghammer actual_opcode_size = sizeof(g_arm_breakpoint_opcode); 235163c8be95STamas Berghammer return Error (); 235263c8be95STamas Berghammer default: 235363c8be95STamas Berghammer assert(false && "Unrecognised trap opcode size hint!"); 235463c8be95STamas Berghammer return Error ("Unrecognised trap opcode size hint!"); 235563c8be95STamas Berghammer } 235663c8be95STamas Berghammer 2357af245d11STodd Fiala case llvm::Triple::x86: 2358af245d11STodd Fiala case llvm::Triple::x86_64: 2359af245d11STodd Fiala trap_opcode_bytes = g_i386_opcode; 2360af245d11STodd Fiala actual_opcode_size = sizeof(g_i386_opcode); 2361af245d11STodd Fiala return Error (); 2362af245d11STodd Fiala 2363ce815e45SSagar Thakur case llvm::Triple::mips: 23643df471c3SMohit K. Bhakkad case llvm::Triple::mips64: 23653df471c3SMohit K. Bhakkad trap_opcode_bytes = g_mips64_opcode; 23663df471c3SMohit K. Bhakkad actual_opcode_size = sizeof(g_mips64_opcode); 23673df471c3SMohit K. Bhakkad return Error (); 23683df471c3SMohit K. Bhakkad 2369ce815e45SSagar Thakur case llvm::Triple::mipsel: 23702c2acf96SMohit K. Bhakkad case llvm::Triple::mips64el: 23712c2acf96SMohit K. Bhakkad trap_opcode_bytes = g_mips64el_opcode; 23722c2acf96SMohit K. Bhakkad actual_opcode_size = sizeof(g_mips64el_opcode); 23732c2acf96SMohit K. Bhakkad return Error (); 23742c2acf96SMohit K. Bhakkad 2375af245d11STodd Fiala default: 2376af245d11STodd Fiala assert(false && "CPU type not supported!"); 2377af245d11STodd Fiala return Error ("CPU type not supported"); 2378af245d11STodd Fiala } 2379af245d11STodd Fiala } 2380af245d11STodd Fiala 2381af245d11STodd Fiala #if 0 2382af245d11STodd Fiala ProcessMessage::CrashReason 2383af245d11STodd Fiala NativeProcessLinux::GetCrashReasonForSIGSEGV(const siginfo_t *info) 2384af245d11STodd Fiala { 2385af245d11STodd Fiala ProcessMessage::CrashReason reason; 2386af245d11STodd Fiala assert(info->si_signo == SIGSEGV); 2387af245d11STodd Fiala 2388af245d11STodd Fiala reason = ProcessMessage::eInvalidCrashReason; 2389af245d11STodd Fiala 2390af245d11STodd Fiala switch (info->si_code) 2391af245d11STodd Fiala { 2392af245d11STodd Fiala default: 2393af245d11STodd Fiala assert(false && "unexpected si_code for SIGSEGV"); 2394af245d11STodd Fiala break; 2395af245d11STodd Fiala case SI_KERNEL: 2396af245d11STodd Fiala // Linux will occasionally send spurious SI_KERNEL codes. 2397af245d11STodd Fiala // (this is poorly documented in sigaction) 2398af245d11STodd Fiala // One way to get this is via unaligned SIMD loads. 2399af245d11STodd Fiala reason = ProcessMessage::eInvalidAddress; // for lack of anything better 2400af245d11STodd Fiala break; 2401af245d11STodd Fiala case SEGV_MAPERR: 2402af245d11STodd Fiala reason = ProcessMessage::eInvalidAddress; 2403af245d11STodd Fiala break; 2404af245d11STodd Fiala case SEGV_ACCERR: 2405af245d11STodd Fiala reason = ProcessMessage::ePrivilegedAddress; 2406af245d11STodd Fiala break; 2407af245d11STodd Fiala } 2408af245d11STodd Fiala 2409af245d11STodd Fiala return reason; 2410af245d11STodd Fiala } 2411af245d11STodd Fiala #endif 2412af245d11STodd Fiala 2413af245d11STodd Fiala 2414af245d11STodd Fiala #if 0 2415af245d11STodd Fiala ProcessMessage::CrashReason 2416af245d11STodd Fiala NativeProcessLinux::GetCrashReasonForSIGILL(const siginfo_t *info) 2417af245d11STodd Fiala { 2418af245d11STodd Fiala ProcessMessage::CrashReason reason; 2419af245d11STodd Fiala assert(info->si_signo == SIGILL); 2420af245d11STodd Fiala 2421af245d11STodd Fiala reason = ProcessMessage::eInvalidCrashReason; 2422af245d11STodd Fiala 2423af245d11STodd Fiala switch (info->si_code) 2424af245d11STodd Fiala { 2425af245d11STodd Fiala default: 2426af245d11STodd Fiala assert(false && "unexpected si_code for SIGILL"); 2427af245d11STodd Fiala break; 2428af245d11STodd Fiala case ILL_ILLOPC: 2429af245d11STodd Fiala reason = ProcessMessage::eIllegalOpcode; 2430af245d11STodd Fiala break; 2431af245d11STodd Fiala case ILL_ILLOPN: 2432af245d11STodd Fiala reason = ProcessMessage::eIllegalOperand; 2433af245d11STodd Fiala break; 2434af245d11STodd Fiala case ILL_ILLADR: 2435af245d11STodd Fiala reason = ProcessMessage::eIllegalAddressingMode; 2436af245d11STodd Fiala break; 2437af245d11STodd Fiala case ILL_ILLTRP: 2438af245d11STodd Fiala reason = ProcessMessage::eIllegalTrap; 2439af245d11STodd Fiala break; 2440af245d11STodd Fiala case ILL_PRVOPC: 2441af245d11STodd Fiala reason = ProcessMessage::ePrivilegedOpcode; 2442af245d11STodd Fiala break; 2443af245d11STodd Fiala case ILL_PRVREG: 2444af245d11STodd Fiala reason = ProcessMessage::ePrivilegedRegister; 2445af245d11STodd Fiala break; 2446af245d11STodd Fiala case ILL_COPROC: 2447af245d11STodd Fiala reason = ProcessMessage::eCoprocessorError; 2448af245d11STodd Fiala break; 2449af245d11STodd Fiala case ILL_BADSTK: 2450af245d11STodd Fiala reason = ProcessMessage::eInternalStackError; 2451af245d11STodd Fiala break; 2452af245d11STodd Fiala } 2453af245d11STodd Fiala 2454af245d11STodd Fiala return reason; 2455af245d11STodd Fiala } 2456af245d11STodd Fiala #endif 2457af245d11STodd Fiala 2458af245d11STodd Fiala #if 0 2459af245d11STodd Fiala ProcessMessage::CrashReason 2460af245d11STodd Fiala NativeProcessLinux::GetCrashReasonForSIGFPE(const siginfo_t *info) 2461af245d11STodd Fiala { 2462af245d11STodd Fiala ProcessMessage::CrashReason reason; 2463af245d11STodd Fiala assert(info->si_signo == SIGFPE); 2464af245d11STodd Fiala 2465af245d11STodd Fiala reason = ProcessMessage::eInvalidCrashReason; 2466af245d11STodd Fiala 2467af245d11STodd Fiala switch (info->si_code) 2468af245d11STodd Fiala { 2469af245d11STodd Fiala default: 2470af245d11STodd Fiala assert(false && "unexpected si_code for SIGFPE"); 2471af245d11STodd Fiala break; 2472af245d11STodd Fiala case FPE_INTDIV: 2473af245d11STodd Fiala reason = ProcessMessage::eIntegerDivideByZero; 2474af245d11STodd Fiala break; 2475af245d11STodd Fiala case FPE_INTOVF: 2476af245d11STodd Fiala reason = ProcessMessage::eIntegerOverflow; 2477af245d11STodd Fiala break; 2478af245d11STodd Fiala case FPE_FLTDIV: 2479af245d11STodd Fiala reason = ProcessMessage::eFloatDivideByZero; 2480af245d11STodd Fiala break; 2481af245d11STodd Fiala case FPE_FLTOVF: 2482af245d11STodd Fiala reason = ProcessMessage::eFloatOverflow; 2483af245d11STodd Fiala break; 2484af245d11STodd Fiala case FPE_FLTUND: 2485af245d11STodd Fiala reason = ProcessMessage::eFloatUnderflow; 2486af245d11STodd Fiala break; 2487af245d11STodd Fiala case FPE_FLTRES: 2488af245d11STodd Fiala reason = ProcessMessage::eFloatInexactResult; 2489af245d11STodd Fiala break; 2490af245d11STodd Fiala case FPE_FLTINV: 2491af245d11STodd Fiala reason = ProcessMessage::eFloatInvalidOperation; 2492af245d11STodd Fiala break; 2493af245d11STodd Fiala case FPE_FLTSUB: 2494af245d11STodd Fiala reason = ProcessMessage::eFloatSubscriptRange; 2495af245d11STodd Fiala break; 2496af245d11STodd Fiala } 2497af245d11STodd Fiala 2498af245d11STodd Fiala return reason; 2499af245d11STodd Fiala } 2500af245d11STodd Fiala #endif 2501af245d11STodd Fiala 2502af245d11STodd Fiala #if 0 2503af245d11STodd Fiala ProcessMessage::CrashReason 2504af245d11STodd Fiala NativeProcessLinux::GetCrashReasonForSIGBUS(const siginfo_t *info) 2505af245d11STodd Fiala { 2506af245d11STodd Fiala ProcessMessage::CrashReason reason; 2507af245d11STodd Fiala assert(info->si_signo == SIGBUS); 2508af245d11STodd Fiala 2509af245d11STodd Fiala reason = ProcessMessage::eInvalidCrashReason; 2510af245d11STodd Fiala 2511af245d11STodd Fiala switch (info->si_code) 2512af245d11STodd Fiala { 2513af245d11STodd Fiala default: 2514af245d11STodd Fiala assert(false && "unexpected si_code for SIGBUS"); 2515af245d11STodd Fiala break; 2516af245d11STodd Fiala case BUS_ADRALN: 2517af245d11STodd Fiala reason = ProcessMessage::eIllegalAlignment; 2518af245d11STodd Fiala break; 2519af245d11STodd Fiala case BUS_ADRERR: 2520af245d11STodd Fiala reason = ProcessMessage::eIllegalAddress; 2521af245d11STodd Fiala break; 2522af245d11STodd Fiala case BUS_OBJERR: 2523af245d11STodd Fiala reason = ProcessMessage::eHardwareError; 2524af245d11STodd Fiala break; 2525af245d11STodd Fiala } 2526af245d11STodd Fiala 2527af245d11STodd Fiala return reason; 2528af245d11STodd Fiala } 2529af245d11STodd Fiala #endif 2530af245d11STodd Fiala 2531af245d11STodd Fiala Error 253226438d26SChaoren Lin NativeProcessLinux::ReadMemory (lldb::addr_t addr, void *buf, size_t size, size_t &bytes_read) 2533af245d11STodd Fiala { 2534df7c6995SPavel Labath if (ProcessVmReadvSupported()) { 2535df7c6995SPavel Labath // The process_vm_readv path is about 50 times faster than ptrace api. We want to use 2536df7c6995SPavel Labath // this syscall if it is supported. 2537df7c6995SPavel Labath 2538df7c6995SPavel Labath const ::pid_t pid = GetID(); 2539df7c6995SPavel Labath 2540df7c6995SPavel Labath struct iovec local_iov, remote_iov; 2541df7c6995SPavel Labath local_iov.iov_base = buf; 2542df7c6995SPavel Labath local_iov.iov_len = size; 2543df7c6995SPavel Labath remote_iov.iov_base = reinterpret_cast<void *>(addr); 2544df7c6995SPavel Labath remote_iov.iov_len = size; 2545df7c6995SPavel Labath 2546df7c6995SPavel Labath bytes_read = process_vm_readv(pid, &local_iov, 1, &remote_iov, 1, 0); 2547df7c6995SPavel Labath const bool success = bytes_read == size; 2548df7c6995SPavel Labath 2549df7c6995SPavel Labath Log *log(GetLogIfAllCategoriesSet (LIBLLDB_LOG_PROCESS)); 2550df7c6995SPavel Labath if (log) 2551df7c6995SPavel Labath log->Printf ("NativeProcessLinux::%s using process_vm_readv to read %zd bytes from inferior address 0x%" PRIx64": %s", 2552df7c6995SPavel Labath __FUNCTION__, size, addr, success ? "Success" : strerror(errno)); 2553df7c6995SPavel Labath 2554df7c6995SPavel Labath if (success) 2555df7c6995SPavel Labath return Error(); 2556df7c6995SPavel Labath // else 2557df7c6995SPavel Labath // the call failed for some reason, let's retry the read using ptrace api. 2558df7c6995SPavel Labath } 2559df7c6995SPavel Labath 256019cbe96aSPavel Labath unsigned char *dst = static_cast<unsigned char*>(buf); 256119cbe96aSPavel Labath size_t remainder; 256219cbe96aSPavel Labath long data; 256319cbe96aSPavel Labath 256419cbe96aSPavel Labath Log *log (ProcessPOSIXLog::GetLogIfAllCategoriesSet (POSIX_LOG_ALL)); 256519cbe96aSPavel Labath if (log) 256619cbe96aSPavel Labath ProcessPOSIXLog::IncNestLevel(); 256719cbe96aSPavel Labath if (log && ProcessPOSIXLog::AtTopNestLevel() && log->GetMask().Test(POSIX_LOG_MEMORY)) 256819cbe96aSPavel Labath log->Printf ("NativeProcessLinux::%s(%p, %p, %zd, _)", __FUNCTION__, (void*)addr, buf, size); 256919cbe96aSPavel Labath 257019cbe96aSPavel Labath for (bytes_read = 0; bytes_read < size; bytes_read += remainder) 257119cbe96aSPavel Labath { 257219cbe96aSPavel Labath Error error = NativeProcessLinux::PtraceWrapper(PTRACE_PEEKDATA, GetID(), (void*)addr, nullptr, 0, &data); 257319cbe96aSPavel Labath if (error.Fail()) 257419cbe96aSPavel Labath { 257519cbe96aSPavel Labath if (log) 257619cbe96aSPavel Labath ProcessPOSIXLog::DecNestLevel(); 257719cbe96aSPavel Labath return error; 257819cbe96aSPavel Labath } 257919cbe96aSPavel Labath 258019cbe96aSPavel Labath remainder = size - bytes_read; 258119cbe96aSPavel Labath remainder = remainder > k_ptrace_word_size ? k_ptrace_word_size : remainder; 258219cbe96aSPavel Labath 258319cbe96aSPavel Labath // Copy the data into our buffer 258419cbe96aSPavel Labath for (unsigned i = 0; i < remainder; ++i) 258519cbe96aSPavel Labath dst[i] = ((data >> i*8) & 0xFF); 258619cbe96aSPavel Labath 258719cbe96aSPavel Labath if (log && ProcessPOSIXLog::AtTopNestLevel() && 258819cbe96aSPavel Labath (log->GetMask().Test(POSIX_LOG_MEMORY_DATA_LONG) || 258919cbe96aSPavel Labath (log->GetMask().Test(POSIX_LOG_MEMORY_DATA_SHORT) && 259019cbe96aSPavel Labath size <= POSIX_LOG_MEMORY_SHORT_BYTES))) 259119cbe96aSPavel Labath { 259219cbe96aSPavel Labath uintptr_t print_dst = 0; 259319cbe96aSPavel Labath // Format bytes from data by moving into print_dst for log output 259419cbe96aSPavel Labath for (unsigned i = 0; i < remainder; ++i) 259519cbe96aSPavel Labath print_dst |= (((data >> i*8) & 0xFF) << i*8); 259679203995SPavel Labath log->Printf ("NativeProcessLinux::%s() [0x%" PRIx64 "]:0x%" PRIx64 " (0x%" PRIx64 ")", 259779203995SPavel Labath __FUNCTION__, addr, uint64_t(print_dst), uint64_t(data)); 259819cbe96aSPavel Labath } 259919cbe96aSPavel Labath addr += k_ptrace_word_size; 260019cbe96aSPavel Labath dst += k_ptrace_word_size; 260119cbe96aSPavel Labath } 260219cbe96aSPavel Labath 260319cbe96aSPavel Labath if (log) 260419cbe96aSPavel Labath ProcessPOSIXLog::DecNestLevel(); 260519cbe96aSPavel Labath return Error(); 2606af245d11STodd Fiala } 2607af245d11STodd Fiala 2608af245d11STodd Fiala Error 26093eb4b458SChaoren Lin NativeProcessLinux::ReadMemoryWithoutTrap(lldb::addr_t addr, void *buf, size_t size, size_t &bytes_read) 26103eb4b458SChaoren Lin { 26113eb4b458SChaoren Lin Error error = ReadMemory(addr, buf, size, bytes_read); 26123eb4b458SChaoren Lin if (error.Fail()) return error; 26133eb4b458SChaoren Lin return m_breakpoint_list.RemoveTrapsFromBuffer(addr, buf, size); 26143eb4b458SChaoren Lin } 26153eb4b458SChaoren Lin 26163eb4b458SChaoren Lin Error 26173eb4b458SChaoren Lin NativeProcessLinux::WriteMemory(lldb::addr_t addr, const void *buf, size_t size, size_t &bytes_written) 2618af245d11STodd Fiala { 261919cbe96aSPavel Labath const unsigned char *src = static_cast<const unsigned char*>(buf); 262019cbe96aSPavel Labath size_t remainder; 262119cbe96aSPavel Labath Error error; 262219cbe96aSPavel Labath 262319cbe96aSPavel Labath Log *log (ProcessPOSIXLog::GetLogIfAllCategoriesSet (POSIX_LOG_ALL)); 262419cbe96aSPavel Labath if (log) 262519cbe96aSPavel Labath ProcessPOSIXLog::IncNestLevel(); 262619cbe96aSPavel Labath if (log && ProcessPOSIXLog::AtTopNestLevel() && log->GetMask().Test(POSIX_LOG_MEMORY)) 262779203995SPavel Labath log->Printf ("NativeProcessLinux::%s(0x%" PRIx64 ", %p, %zu)", __FUNCTION__, addr, buf, size); 262819cbe96aSPavel Labath 262919cbe96aSPavel Labath for (bytes_written = 0; bytes_written < size; bytes_written += remainder) 263019cbe96aSPavel Labath { 263119cbe96aSPavel Labath remainder = size - bytes_written; 263219cbe96aSPavel Labath remainder = remainder > k_ptrace_word_size ? k_ptrace_word_size : remainder; 263319cbe96aSPavel Labath 263419cbe96aSPavel Labath if (remainder == k_ptrace_word_size) 263519cbe96aSPavel Labath { 263619cbe96aSPavel Labath unsigned long data = 0; 263719cbe96aSPavel Labath for (unsigned i = 0; i < k_ptrace_word_size; ++i) 263819cbe96aSPavel Labath data |= (unsigned long)src[i] << i*8; 263919cbe96aSPavel Labath 264019cbe96aSPavel Labath if (log && ProcessPOSIXLog::AtTopNestLevel() && 264119cbe96aSPavel Labath (log->GetMask().Test(POSIX_LOG_MEMORY_DATA_LONG) || 264219cbe96aSPavel Labath (log->GetMask().Test(POSIX_LOG_MEMORY_DATA_SHORT) && 264319cbe96aSPavel Labath size <= POSIX_LOG_MEMORY_SHORT_BYTES))) 264419cbe96aSPavel Labath log->Printf ("NativeProcessLinux::%s() [%p]:0x%lx (0x%lx)", __FUNCTION__, 264519cbe96aSPavel Labath (void*)addr, *(const unsigned long*)src, data); 264619cbe96aSPavel Labath 264719cbe96aSPavel Labath error = NativeProcessLinux::PtraceWrapper(PTRACE_POKEDATA, GetID(), (void*)addr, (void*)data); 264819cbe96aSPavel Labath if (error.Fail()) 264919cbe96aSPavel Labath { 265019cbe96aSPavel Labath if (log) 265119cbe96aSPavel Labath ProcessPOSIXLog::DecNestLevel(); 265219cbe96aSPavel Labath return error; 265319cbe96aSPavel Labath } 265419cbe96aSPavel Labath } 265519cbe96aSPavel Labath else 265619cbe96aSPavel Labath { 265719cbe96aSPavel Labath unsigned char buff[8]; 265819cbe96aSPavel Labath size_t bytes_read; 265919cbe96aSPavel Labath error = ReadMemory(addr, buff, k_ptrace_word_size, bytes_read); 266019cbe96aSPavel Labath if (error.Fail()) 266119cbe96aSPavel Labath { 266219cbe96aSPavel Labath if (log) 266319cbe96aSPavel Labath ProcessPOSIXLog::DecNestLevel(); 266419cbe96aSPavel Labath return error; 266519cbe96aSPavel Labath } 266619cbe96aSPavel Labath 266719cbe96aSPavel Labath memcpy(buff, src, remainder); 266819cbe96aSPavel Labath 266919cbe96aSPavel Labath size_t bytes_written_rec; 267019cbe96aSPavel Labath error = WriteMemory(addr, buff, k_ptrace_word_size, bytes_written_rec); 267119cbe96aSPavel Labath if (error.Fail()) 267219cbe96aSPavel Labath { 267319cbe96aSPavel Labath if (log) 267419cbe96aSPavel Labath ProcessPOSIXLog::DecNestLevel(); 267519cbe96aSPavel Labath return error; 267619cbe96aSPavel Labath } 267719cbe96aSPavel Labath 267819cbe96aSPavel Labath if (log && ProcessPOSIXLog::AtTopNestLevel() && 267919cbe96aSPavel Labath (log->GetMask().Test(POSIX_LOG_MEMORY_DATA_LONG) || 268019cbe96aSPavel Labath (log->GetMask().Test(POSIX_LOG_MEMORY_DATA_SHORT) && 268119cbe96aSPavel Labath size <= POSIX_LOG_MEMORY_SHORT_BYTES))) 268219cbe96aSPavel Labath log->Printf ("NativeProcessLinux::%s() [%p]:0x%lx (0x%lx)", __FUNCTION__, 268319cbe96aSPavel Labath (void*)addr, *(const unsigned long*)src, *(unsigned long*)buff); 268419cbe96aSPavel Labath } 268519cbe96aSPavel Labath 268619cbe96aSPavel Labath addr += k_ptrace_word_size; 268719cbe96aSPavel Labath src += k_ptrace_word_size; 268819cbe96aSPavel Labath } 268919cbe96aSPavel Labath if (log) 269019cbe96aSPavel Labath ProcessPOSIXLog::DecNestLevel(); 269119cbe96aSPavel Labath return error; 2692af245d11STodd Fiala } 2693af245d11STodd Fiala 269497ccc294SChaoren Lin Error 2695af245d11STodd Fiala NativeProcessLinux::Resume (lldb::tid_t tid, uint32_t signo) 2696af245d11STodd Fiala { 2697af245d11STodd Fiala Log *log (GetLogIfAllCategoriesSet (LIBLLDB_LOG_PROCESS)); 2698af245d11STodd Fiala 2699af245d11STodd Fiala if (log) 2700af245d11STodd Fiala log->Printf ("NativeProcessLinux::%s() resuming thread = %" PRIu64 " with signal %s", __FUNCTION__, tid, 270198d0a4b3SChaoren Lin Host::GetSignalAsCString(signo)); 2702c7512fdcSPavel Labath 2703c7512fdcSPavel Labath 2704c7512fdcSPavel Labath 2705c7512fdcSPavel Labath intptr_t data = 0; 2706c7512fdcSPavel Labath 2707c7512fdcSPavel Labath if (signo != LLDB_INVALID_SIGNAL_NUMBER) 2708c7512fdcSPavel Labath data = signo; 2709c7512fdcSPavel Labath 271019cbe96aSPavel Labath Error error = PtraceWrapper(PTRACE_CONT, tid, nullptr, (void*)data); 2711c7512fdcSPavel Labath 2712af245d11STodd Fiala if (log) 2713c7512fdcSPavel Labath log->Printf ("NativeProcessLinux::%s() resuming thread = %" PRIu64 " result = %s", __FUNCTION__, tid, error.Success() ? "true" : "false"); 2714c7512fdcSPavel Labath return error; 2715af245d11STodd Fiala } 2716af245d11STodd Fiala 271797ccc294SChaoren Lin Error 2718af245d11STodd Fiala NativeProcessLinux::SingleStep(lldb::tid_t tid, uint32_t signo) 2719af245d11STodd Fiala { 2720c7512fdcSPavel Labath intptr_t data = 0; 2721c7512fdcSPavel Labath 2722c7512fdcSPavel Labath if (signo != LLDB_INVALID_SIGNAL_NUMBER) 2723c7512fdcSPavel Labath data = signo; 2724c7512fdcSPavel Labath 2725*0e1d729bSPavel Labath // If hardware single-stepping is not supported, we just do a continue. The breakpoint on the 2726*0e1d729bSPavel Labath // next instruction has been setup in NativeProcessLinux::Resume. 2727*0e1d729bSPavel Labath return PtraceWrapper(SupportHardwareSingleStepping() ? PTRACE_SINGLESTEP : PTRACE_CONT, 2728*0e1d729bSPavel Labath tid, nullptr, (void*)data); 2729af245d11STodd Fiala } 2730af245d11STodd Fiala 273197ccc294SChaoren Lin Error 273297ccc294SChaoren Lin NativeProcessLinux::GetSignalInfo(lldb::tid_t tid, void *siginfo) 2733af245d11STodd Fiala { 273419cbe96aSPavel Labath return PtraceWrapper(PTRACE_GETSIGINFO, tid, nullptr, siginfo); 2735af245d11STodd Fiala } 2736af245d11STodd Fiala 273797ccc294SChaoren Lin Error 2738af245d11STodd Fiala NativeProcessLinux::GetEventMessage(lldb::tid_t tid, unsigned long *message) 2739af245d11STodd Fiala { 274019cbe96aSPavel Labath return PtraceWrapper(PTRACE_GETEVENTMSG, tid, nullptr, message); 2741af245d11STodd Fiala } 2742af245d11STodd Fiala 2743db264a6dSTamas Berghammer Error 2744af245d11STodd Fiala NativeProcessLinux::Detach(lldb::tid_t tid) 2745af245d11STodd Fiala { 274697ccc294SChaoren Lin if (tid == LLDB_INVALID_THREAD_ID) 274797ccc294SChaoren Lin return Error(); 274897ccc294SChaoren Lin 274919cbe96aSPavel Labath return PtraceWrapper(PTRACE_DETACH, tid); 2750af245d11STodd Fiala } 2751af245d11STodd Fiala 2752af245d11STodd Fiala bool 2753d3173f34SChaoren Lin NativeProcessLinux::DupDescriptor(const FileSpec &file_spec, int fd, int flags) 2754af245d11STodd Fiala { 2755d3173f34SChaoren Lin int target_fd = open(file_spec.GetCString(), flags, 0666); 2756af245d11STodd Fiala 2757af245d11STodd Fiala if (target_fd == -1) 2758af245d11STodd Fiala return false; 2759af245d11STodd Fiala 2760493c3a12SPavel Labath if (dup2(target_fd, fd) == -1) 2761493c3a12SPavel Labath return false; 2762493c3a12SPavel Labath 2763493c3a12SPavel Labath return (close(target_fd) == -1) ? false : true; 2764af245d11STodd Fiala } 2765af245d11STodd Fiala 2766af245d11STodd Fiala bool 2767af245d11STodd Fiala NativeProcessLinux::HasThreadNoLock (lldb::tid_t thread_id) 2768af245d11STodd Fiala { 2769af245d11STodd Fiala for (auto thread_sp : m_threads) 2770af245d11STodd Fiala { 2771af245d11STodd Fiala assert (thread_sp && "thread list should not contain NULL threads"); 2772af245d11STodd Fiala if (thread_sp->GetID () == thread_id) 2773af245d11STodd Fiala { 2774af245d11STodd Fiala // We have this thread. 2775af245d11STodd Fiala return true; 2776af245d11STodd Fiala } 2777af245d11STodd Fiala } 2778af245d11STodd Fiala 2779af245d11STodd Fiala // We don't have this thread. 2780af245d11STodd Fiala return false; 2781af245d11STodd Fiala } 2782af245d11STodd Fiala 2783af245d11STodd Fiala NativeThreadProtocolSP 2784af245d11STodd Fiala NativeProcessLinux::MaybeGetThreadNoLock (lldb::tid_t thread_id) 2785af245d11STodd Fiala { 2786af245d11STodd Fiala // CONSIDER organize threads by map - we can do better than linear. 2787af245d11STodd Fiala for (auto thread_sp : m_threads) 2788af245d11STodd Fiala { 2789af245d11STodd Fiala if (thread_sp->GetID () == thread_id) 2790af245d11STodd Fiala return thread_sp; 2791af245d11STodd Fiala } 2792af245d11STodd Fiala 2793af245d11STodd Fiala // We don't have this thread. 2794af245d11STodd Fiala return NativeThreadProtocolSP (); 2795af245d11STodd Fiala } 2796af245d11STodd Fiala 2797af245d11STodd Fiala bool 2798af245d11STodd Fiala NativeProcessLinux::StopTrackingThread (lldb::tid_t thread_id) 2799af245d11STodd Fiala { 28001dbc6c9cSPavel Labath Log *const log = GetLogIfAllCategoriesSet (LIBLLDB_LOG_THREAD); 28011dbc6c9cSPavel Labath 28021dbc6c9cSPavel Labath if (log) 28031dbc6c9cSPavel Labath log->Printf("NativeProcessLinux::%s (tid: %" PRIu64 ")", __FUNCTION__, thread_id); 28041dbc6c9cSPavel Labath 28051dbc6c9cSPavel Labath bool found = false; 28061dbc6c9cSPavel Labath 2807af245d11STodd Fiala Mutex::Locker locker (m_threads_mutex); 2808af245d11STodd Fiala for (auto it = m_threads.begin (); it != m_threads.end (); ++it) 2809af245d11STodd Fiala { 2810af245d11STodd Fiala if (*it && ((*it)->GetID () == thread_id)) 2811af245d11STodd Fiala { 2812af245d11STodd Fiala m_threads.erase (it); 28131dbc6c9cSPavel Labath found = true; 28141dbc6c9cSPavel Labath break; 2815af245d11STodd Fiala } 2816af245d11STodd Fiala } 2817af245d11STodd Fiala 28189eb1ecb9SPavel Labath SignalIfAllThreadsStopped(); 28191dbc6c9cSPavel Labath 28201dbc6c9cSPavel Labath return found; 2821af245d11STodd Fiala } 2822af245d11STodd Fiala 2823af245d11STodd Fiala NativeThreadProtocolSP 2824af245d11STodd Fiala NativeProcessLinux::AddThread (lldb::tid_t thread_id) 2825af245d11STodd Fiala { 2826af245d11STodd Fiala Log *log (GetLogIfAllCategoriesSet (LIBLLDB_LOG_THREAD)); 2827af245d11STodd Fiala 2828af245d11STodd Fiala Mutex::Locker locker (m_threads_mutex); 2829af245d11STodd Fiala 2830af245d11STodd Fiala if (log) 2831af245d11STodd Fiala { 2832af245d11STodd Fiala log->Printf ("NativeProcessLinux::%s pid %" PRIu64 " adding thread with tid %" PRIu64, 2833af245d11STodd Fiala __FUNCTION__, 2834af245d11STodd Fiala GetID (), 2835af245d11STodd Fiala thread_id); 2836af245d11STodd Fiala } 2837af245d11STodd Fiala 2838af245d11STodd Fiala assert (!HasThreadNoLock (thread_id) && "attempted to add a thread by id that already exists"); 2839af245d11STodd Fiala 2840af245d11STodd Fiala // If this is the first thread, save it as the current thread 2841af245d11STodd Fiala if (m_threads.empty ()) 2842af245d11STodd Fiala SetCurrentThreadID (thread_id); 2843af245d11STodd Fiala 2844af245d11STodd Fiala NativeThreadProtocolSP thread_sp (new NativeThreadLinux (this, thread_id)); 2845af245d11STodd Fiala m_threads.push_back (thread_sp); 2846af245d11STodd Fiala 2847af245d11STodd Fiala return thread_sp; 2848af245d11STodd Fiala } 2849af245d11STodd Fiala 2850af245d11STodd Fiala Error 2851af245d11STodd Fiala NativeProcessLinux::FixupBreakpointPCAsNeeded (NativeThreadProtocolSP &thread_sp) 2852af245d11STodd Fiala { 285375f47c3aSTodd Fiala Log *log (GetLogIfAllCategoriesSet (LIBLLDB_LOG_BREAKPOINTS)); 2854af245d11STodd Fiala 2855af245d11STodd Fiala Error error; 2856af245d11STodd Fiala 2857af245d11STodd Fiala // Get a linux thread pointer. 2858af245d11STodd Fiala if (!thread_sp) 2859af245d11STodd Fiala { 2860af245d11STodd Fiala error.SetErrorString ("null thread_sp"); 2861af245d11STodd Fiala if (log) 2862af245d11STodd Fiala log->Printf ("NativeProcessLinux::%s failed: %s", __FUNCTION__, error.AsCString ()); 2863af245d11STodd Fiala return error; 2864af245d11STodd Fiala } 2865cb84eebbSTamas Berghammer std::shared_ptr<NativeThreadLinux> linux_thread_sp = std::static_pointer_cast<NativeThreadLinux> (thread_sp); 2866af245d11STodd Fiala 2867af245d11STodd Fiala // Find out the size of a breakpoint (might depend on where we are in the code). 2868cb84eebbSTamas Berghammer NativeRegisterContextSP context_sp = linux_thread_sp->GetRegisterContext (); 2869af245d11STodd Fiala if (!context_sp) 2870af245d11STodd Fiala { 2871af245d11STodd Fiala error.SetErrorString ("cannot get a NativeRegisterContext for the thread"); 2872af245d11STodd Fiala if (log) 2873af245d11STodd Fiala log->Printf ("NativeProcessLinux::%s failed: %s", __FUNCTION__, error.AsCString ()); 2874af245d11STodd Fiala return error; 2875af245d11STodd Fiala } 2876af245d11STodd Fiala 2877af245d11STodd Fiala uint32_t breakpoint_size = 0; 287863c8be95STamas Berghammer error = GetSoftwareBreakpointPCOffset (context_sp, breakpoint_size); 2879af245d11STodd Fiala if (error.Fail ()) 2880af245d11STodd Fiala { 2881af245d11STodd Fiala if (log) 2882af245d11STodd Fiala log->Printf ("NativeProcessLinux::%s GetBreakpointSize() failed: %s", __FUNCTION__, error.AsCString ()); 2883af245d11STodd Fiala return error; 2884af245d11STodd Fiala } 2885af245d11STodd Fiala else 2886af245d11STodd Fiala { 2887af245d11STodd Fiala if (log) 2888af245d11STodd Fiala log->Printf ("NativeProcessLinux::%s breakpoint size: %" PRIu32, __FUNCTION__, breakpoint_size); 2889af245d11STodd Fiala } 2890af245d11STodd Fiala 2891af245d11STodd Fiala // First try probing for a breakpoint at a software breakpoint location: PC - breakpoint size. 2892c60c9452SJaydeep Patil const lldb::addr_t initial_pc_addr = context_sp->GetPCfromBreakpointLocation (); 2893af245d11STodd Fiala lldb::addr_t breakpoint_addr = initial_pc_addr; 28943eb4b458SChaoren Lin if (breakpoint_size > 0) 2895af245d11STodd Fiala { 2896af245d11STodd Fiala // Do not allow breakpoint probe to wrap around. 28973eb4b458SChaoren Lin if (breakpoint_addr >= breakpoint_size) 28983eb4b458SChaoren Lin breakpoint_addr -= breakpoint_size; 2899af245d11STodd Fiala } 2900af245d11STodd Fiala 2901af245d11STodd Fiala // Check if we stopped because of a breakpoint. 2902af245d11STodd Fiala NativeBreakpointSP breakpoint_sp; 2903af245d11STodd Fiala error = m_breakpoint_list.GetBreakpoint (breakpoint_addr, breakpoint_sp); 2904af245d11STodd Fiala if (!error.Success () || !breakpoint_sp) 2905af245d11STodd Fiala { 2906af245d11STodd Fiala // We didn't find one at a software probe location. Nothing to do. 2907af245d11STodd Fiala if (log) 2908af245d11STodd Fiala log->Printf ("NativeProcessLinux::%s pid %" PRIu64 " no lldb breakpoint found at current pc with adjustment: 0x%" PRIx64, __FUNCTION__, GetID (), breakpoint_addr); 2909af245d11STodd Fiala return Error (); 2910af245d11STodd Fiala } 2911af245d11STodd Fiala 2912af245d11STodd Fiala // If the breakpoint is not a software breakpoint, nothing to do. 2913af245d11STodd Fiala if (!breakpoint_sp->IsSoftwareBreakpoint ()) 2914af245d11STodd Fiala { 2915af245d11STodd Fiala if (log) 2916af245d11STodd Fiala log->Printf ("NativeProcessLinux::%s pid %" PRIu64 " breakpoint found at 0x%" PRIx64 ", not software, nothing to adjust", __FUNCTION__, GetID (), breakpoint_addr); 2917af245d11STodd Fiala return Error (); 2918af245d11STodd Fiala } 2919af245d11STodd Fiala 2920af245d11STodd Fiala // 2921af245d11STodd Fiala // We have a software breakpoint and need to adjust the PC. 2922af245d11STodd Fiala // 2923af245d11STodd Fiala 2924af245d11STodd Fiala // Sanity check. 2925af245d11STodd Fiala if (breakpoint_size == 0) 2926af245d11STodd Fiala { 2927af245d11STodd Fiala // Nothing to do! How did we get here? 2928af245d11STodd Fiala if (log) 2929af245d11STodd Fiala log->Printf ("NativeProcessLinux::%s pid %" PRIu64 " breakpoint found at 0x%" PRIx64 ", it is software, but the size is zero, nothing to do (unexpected)", __FUNCTION__, GetID (), breakpoint_addr); 2930af245d11STodd Fiala return Error (); 2931af245d11STodd Fiala } 2932af245d11STodd Fiala 2933af245d11STodd Fiala // Change the program counter. 2934af245d11STodd Fiala if (log) 2935cb84eebbSTamas Berghammer log->Printf ("NativeProcessLinux::%s pid %" PRIu64 " tid %" PRIu64 ": changing PC from 0x%" PRIx64 " to 0x%" PRIx64, __FUNCTION__, GetID (), linux_thread_sp->GetID (), initial_pc_addr, breakpoint_addr); 2936af245d11STodd Fiala 2937af245d11STodd Fiala error = context_sp->SetPC (breakpoint_addr); 2938af245d11STodd Fiala if (error.Fail ()) 2939af245d11STodd Fiala { 2940af245d11STodd Fiala if (log) 2941cb84eebbSTamas Berghammer log->Printf ("NativeProcessLinux::%s pid %" PRIu64 " tid %" PRIu64 ": failed to set PC: %s", __FUNCTION__, GetID (), linux_thread_sp->GetID (), error.AsCString ()); 2942af245d11STodd Fiala return error; 2943af245d11STodd Fiala } 2944af245d11STodd Fiala 2945af245d11STodd Fiala return error; 2946af245d11STodd Fiala } 2947fa03ad2eSChaoren Lin 29487cb18bf5STamas Berghammer Error 29497cb18bf5STamas Berghammer NativeProcessLinux::GetLoadedModuleFileSpec(const char* module_path, FileSpec& file_spec) 29507cb18bf5STamas Berghammer { 29517cb18bf5STamas Berghammer FileSpec module_file_spec(module_path, true); 29527cb18bf5STamas Berghammer 2953162fb8e8SPavel Labath bool found = false; 29547cb18bf5STamas Berghammer file_spec.Clear(); 2955162fb8e8SPavel Labath ProcFileReader::ProcessLineByLine(GetID(), "maps", 2956162fb8e8SPavel Labath [&] (const std::string &line) 2957162fb8e8SPavel Labath { 2958162fb8e8SPavel Labath SmallVector<StringRef, 16> columns; 2959162fb8e8SPavel Labath StringRef(line).split(columns, " ", -1, false); 2960162fb8e8SPavel Labath if (columns.size() < 6) 2961162fb8e8SPavel Labath return true; // continue searching 2962162fb8e8SPavel Labath 2963162fb8e8SPavel Labath FileSpec this_file_spec(columns[5].str().c_str(), false); 2964162fb8e8SPavel Labath if (this_file_spec.GetFilename() != module_file_spec.GetFilename()) 2965162fb8e8SPavel Labath return true; // continue searching 2966162fb8e8SPavel Labath 2967162fb8e8SPavel Labath file_spec = this_file_spec; 2968162fb8e8SPavel Labath found = true; 2969162fb8e8SPavel Labath return false; // we are done 2970162fb8e8SPavel Labath }); 2971162fb8e8SPavel Labath 2972162fb8e8SPavel Labath if (! found) 29737cb18bf5STamas Berghammer return Error("Module file (%s) not found in /proc/%" PRIu64 "/maps file!", 29747cb18bf5STamas Berghammer module_file_spec.GetFilename().AsCString(), GetID()); 2975162fb8e8SPavel Labath 2976162fb8e8SPavel Labath return Error(); 29777cb18bf5STamas Berghammer } 2978c076559aSPavel Labath 29795eb721edSPavel Labath Error 2980783bfc8cSTamas Berghammer NativeProcessLinux::GetFileLoadAddress(const llvm::StringRef& file_name, lldb::addr_t& load_addr) 2981783bfc8cSTamas Berghammer { 2982783bfc8cSTamas Berghammer load_addr = LLDB_INVALID_ADDRESS; 2983783bfc8cSTamas Berghammer Error error = ProcFileReader::ProcessLineByLine (GetID (), "maps", 2984783bfc8cSTamas Berghammer [&] (const std::string &line) -> bool 2985783bfc8cSTamas Berghammer { 2986783bfc8cSTamas Berghammer StringRef maps_row(line); 2987783bfc8cSTamas Berghammer 2988783bfc8cSTamas Berghammer SmallVector<StringRef, 16> maps_columns; 2989783bfc8cSTamas Berghammer maps_row.split(maps_columns, StringRef(" "), -1, false); 2990783bfc8cSTamas Berghammer 2991783bfc8cSTamas Berghammer if (maps_columns.size() < 6) 2992783bfc8cSTamas Berghammer { 2993783bfc8cSTamas Berghammer // Return true to continue reading the proc file 2994783bfc8cSTamas Berghammer return true; 2995783bfc8cSTamas Berghammer } 2996783bfc8cSTamas Berghammer 2997783bfc8cSTamas Berghammer if (maps_columns[5] == file_name) 2998783bfc8cSTamas Berghammer { 2999783bfc8cSTamas Berghammer StringExtractor addr_extractor(maps_columns[0].str().c_str()); 3000783bfc8cSTamas Berghammer load_addr = addr_extractor.GetHexMaxU64(false, LLDB_INVALID_ADDRESS); 3001783bfc8cSTamas Berghammer 3002783bfc8cSTamas Berghammer // Return false to stop reading the proc file further 3003783bfc8cSTamas Berghammer return false; 3004783bfc8cSTamas Berghammer } 3005783bfc8cSTamas Berghammer 3006783bfc8cSTamas Berghammer // Return true to continue reading the proc file 3007783bfc8cSTamas Berghammer return true; 3008783bfc8cSTamas Berghammer }); 3009783bfc8cSTamas Berghammer return error; 3010783bfc8cSTamas Berghammer } 3011783bfc8cSTamas Berghammer 3012783bfc8cSTamas Berghammer Error 3013*0e1d729bSPavel Labath NativeProcessLinux::ResumeThread(const NativeThreadLinuxSP &thread_sp, lldb::StateType state, int signo) 3014c076559aSPavel Labath { 30155eb721edSPavel Labath Log *const log = GetLogIfAllCategoriesSet (LIBLLDB_LOG_THREAD); 30165eb721edSPavel Labath 30171dbc6c9cSPavel Labath if (log) 3018*0e1d729bSPavel Labath log->Printf("NativeProcessLinux::%s (tid: %" PRIu64 ")", 3019*0e1d729bSPavel Labath __FUNCTION__, thread_sp->GetID()); 3020c076559aSPavel Labath 3021c076559aSPavel Labath // Before we do the resume below, first check if we have a pending 3022108c325dSPavel Labath // stop notification that is currently waiting for 3023*0e1d729bSPavel Labath // all threads to stop. This is potentially a buggy situation since 3024c076559aSPavel Labath // we're ostensibly waiting for threads to stop before we send out the 3025c076559aSPavel Labath // pending notification, and here we are resuming one before we send 3026c076559aSPavel Labath // out the pending stop notification. 3027*0e1d729bSPavel Labath if (m_pending_notification_tid != LLDB_INVALID_THREAD_ID && log) 3028c076559aSPavel Labath { 3029*0e1d729bSPavel Labath log->Printf("NativeProcessLinux::%s about to resume tid %" PRIu64 " per explicit request but we have a pending stop notification (tid %" PRIu64 ") that is actively waiting for this thread to stop. Valid sequence of events?", __FUNCTION__, thread_sp->GetID(), m_pending_notification_tid); 3030c076559aSPavel Labath } 3031c076559aSPavel Labath 3032c076559aSPavel Labath // Request a resume. We expect this to be synchronous and the system 3033c076559aSPavel Labath // to reflect it is running after this completes. 3034*0e1d729bSPavel Labath switch (state) 3035c076559aSPavel Labath { 3036*0e1d729bSPavel Labath case eStateRunning: 3037*0e1d729bSPavel Labath { 3038*0e1d729bSPavel Labath thread_sp->SetRunning(); 3039*0e1d729bSPavel Labath const auto resume_result = Resume(thread_sp->GetID(), signo); 3040*0e1d729bSPavel Labath if (resume_result.Success()) 3041*0e1d729bSPavel Labath SetState(eStateRunning, true); 3042*0e1d729bSPavel Labath return resume_result; 3043c076559aSPavel Labath } 3044*0e1d729bSPavel Labath case eStateStepping: 3045*0e1d729bSPavel Labath { 3046*0e1d729bSPavel Labath thread_sp->SetStepping(); 3047*0e1d729bSPavel Labath const auto step_result = SingleStep(thread_sp->GetID(), signo); 3048*0e1d729bSPavel Labath if (step_result.Success()) 3049*0e1d729bSPavel Labath SetState(eStateRunning, true); 3050*0e1d729bSPavel Labath return step_result; 3051*0e1d729bSPavel Labath } 3052*0e1d729bSPavel Labath default: 3053*0e1d729bSPavel Labath if (log) 3054*0e1d729bSPavel Labath log->Printf("NativeProcessLinux::%s Unhandled state %s.", 3055*0e1d729bSPavel Labath __FUNCTION__, StateAsCString(state)); 3056*0e1d729bSPavel Labath llvm_unreachable("Unhandled state for resume"); 3057*0e1d729bSPavel Labath } 3058c076559aSPavel Labath } 3059c076559aSPavel Labath 3060c076559aSPavel Labath //===----------------------------------------------------------------------===// 3061c076559aSPavel Labath 3062c076559aSPavel Labath void 3063337f3eb9SPavel Labath NativeProcessLinux::StopRunningThreads(const lldb::tid_t triggering_tid) 3064c076559aSPavel Labath { 30655eb721edSPavel Labath Log *const log = GetLogIfAllCategoriesSet (LIBLLDB_LOG_THREAD); 3066c076559aSPavel Labath 30675eb721edSPavel Labath if (log) 3068c076559aSPavel Labath { 30695eb721edSPavel Labath log->Printf("NativeProcessLinux::%s about to process event: (triggering_tid: %" PRIu64 ")", 3070c076559aSPavel Labath __FUNCTION__, triggering_tid); 3071c076559aSPavel Labath } 3072c076559aSPavel Labath 3073*0e1d729bSPavel Labath m_pending_notification_tid = triggering_tid; 3074*0e1d729bSPavel Labath 3075*0e1d729bSPavel Labath // Request a stop for all the thread stops that need to be stopped 3076*0e1d729bSPavel Labath // and are not already known to be stopped. 3077*0e1d729bSPavel Labath for (const auto &thread_sp: m_threads) 3078*0e1d729bSPavel Labath { 3079*0e1d729bSPavel Labath if (StateIsRunningState(thread_sp->GetState())) 3080*0e1d729bSPavel Labath static_pointer_cast<NativeThreadLinux>(thread_sp)->RequestStop(); 3081*0e1d729bSPavel Labath } 3082*0e1d729bSPavel Labath 3083*0e1d729bSPavel Labath SignalIfAllThreadsStopped(); 3084c076559aSPavel Labath 30855eb721edSPavel Labath if (log) 3086c076559aSPavel Labath { 30875eb721edSPavel Labath log->Printf("NativeProcessLinux::%s event processing done", __FUNCTION__); 3088c076559aSPavel Labath } 3089c076559aSPavel Labath } 3090c076559aSPavel Labath 3091c076559aSPavel Labath void 30929eb1ecb9SPavel Labath NativeProcessLinux::SignalIfAllThreadsStopped() 3093c076559aSPavel Labath { 3094*0e1d729bSPavel Labath if (m_pending_notification_tid == LLDB_INVALID_THREAD_ID) 3095*0e1d729bSPavel Labath return; // No pending notification. Nothing to do. 3096*0e1d729bSPavel Labath 3097*0e1d729bSPavel Labath for (const auto &thread_sp: m_threads) 3098c076559aSPavel Labath { 3099*0e1d729bSPavel Labath if (StateIsRunningState(thread_sp->GetState())) 3100*0e1d729bSPavel Labath return; // Some threads are still running. Don't signal yet. 3101*0e1d729bSPavel Labath } 3102*0e1d729bSPavel Labath 3103*0e1d729bSPavel Labath // We have a pending notification and all threads have stopped. 31049eb1ecb9SPavel Labath Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PROCESS | LIBLLDB_LOG_BREAKPOINTS)); 31059eb1ecb9SPavel Labath 31069eb1ecb9SPavel Labath // Clear any temporary breakpoints we used to implement software single stepping. 31079eb1ecb9SPavel Labath for (const auto &thread_info: m_threads_stepping_with_breakpoint) 31089eb1ecb9SPavel Labath { 31099eb1ecb9SPavel Labath Error error = RemoveBreakpoint (thread_info.second); 31109eb1ecb9SPavel Labath if (error.Fail()) 31119eb1ecb9SPavel Labath if (log) 31129eb1ecb9SPavel Labath log->Printf("NativeProcessLinux::%s() pid = %" PRIu64 " remove stepping breakpoint: %s", 31139eb1ecb9SPavel Labath __FUNCTION__, thread_info.first, error.AsCString()); 31149eb1ecb9SPavel Labath } 31159eb1ecb9SPavel Labath m_threads_stepping_with_breakpoint.clear(); 31169eb1ecb9SPavel Labath 31179eb1ecb9SPavel Labath // Notify the delegate about the stop 3118*0e1d729bSPavel Labath SetCurrentThreadID(m_pending_notification_tid); 3119ed89c7feSPavel Labath SetState(StateType::eStateStopped, true); 3120*0e1d729bSPavel Labath m_pending_notification_tid = LLDB_INVALID_THREAD_ID; 3121c076559aSPavel Labath } 3122c076559aSPavel Labath 3123c076559aSPavel Labath void 31248c8ff7afSPavel Labath NativeProcessLinux::ThreadWasCreated (lldb::tid_t tid) 3125c076559aSPavel Labath { 31261dbc6c9cSPavel Labath Log *const log = GetLogIfAllCategoriesSet (LIBLLDB_LOG_THREAD); 31271dbc6c9cSPavel Labath 31281dbc6c9cSPavel Labath if (log) 31291dbc6c9cSPavel Labath log->Printf("NativeProcessLinux::%s (tid: %" PRIu64 ")", __FUNCTION__, tid); 31301dbc6c9cSPavel Labath 31318c8ff7afSPavel Labath auto thread_sp = std::static_pointer_cast<NativeThreadLinux>(GetThreadByID(tid)); 31328c8ff7afSPavel Labath lldbassert(thread_sp != nullptr); 3133c076559aSPavel Labath 3134*0e1d729bSPavel Labath if (m_pending_notification_tid != LLDB_INVALID_THREAD_ID && StateIsRunningState(thread_sp->GetState())) 3135c076559aSPavel Labath { 3136c076559aSPavel Labath // We will need to wait for this new thread to stop as well before firing the 3137c076559aSPavel Labath // notification. 31388c8ff7afSPavel Labath thread_sp->RequestStop(); 3139c076559aSPavel Labath } 3140c076559aSPavel Labath } 3141068f8a7eSTamas Berghammer 314219cbe96aSPavel Labath void 314319cbe96aSPavel Labath NativeProcessLinux::SigchldHandler() 3144068f8a7eSTamas Berghammer { 314519cbe96aSPavel Labath Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_PROCESS)); 314619cbe96aSPavel Labath // Process all pending waitpid notifications. 314719cbe96aSPavel Labath while (true) 314819cbe96aSPavel Labath { 314919cbe96aSPavel Labath int status = -1; 315019cbe96aSPavel Labath ::pid_t wait_pid = waitpid(-1, &status, __WALL | __WNOTHREAD | WNOHANG); 315119cbe96aSPavel Labath 315219cbe96aSPavel Labath if (wait_pid == 0) 315319cbe96aSPavel Labath break; // We are done. 315419cbe96aSPavel Labath 315519cbe96aSPavel Labath if (wait_pid == -1) 315619cbe96aSPavel Labath { 315719cbe96aSPavel Labath if (errno == EINTR) 315819cbe96aSPavel Labath continue; 315919cbe96aSPavel Labath 316019cbe96aSPavel Labath Error error(errno, eErrorTypePOSIX); 316119cbe96aSPavel Labath if (log) 316219cbe96aSPavel Labath log->Printf("NativeProcessLinux::%s waitpid (-1, &status, __WALL | __WNOTHREAD | WNOHANG) failed: %s", 316319cbe96aSPavel Labath __FUNCTION__, error.AsCString()); 316419cbe96aSPavel Labath break; 316519cbe96aSPavel Labath } 316619cbe96aSPavel Labath 316719cbe96aSPavel Labath bool exited = false; 316819cbe96aSPavel Labath int signal = 0; 316919cbe96aSPavel Labath int exit_status = 0; 317019cbe96aSPavel Labath const char *status_cstr = nullptr; 317119cbe96aSPavel Labath if (WIFSTOPPED(status)) 317219cbe96aSPavel Labath { 317319cbe96aSPavel Labath signal = WSTOPSIG(status); 317419cbe96aSPavel Labath status_cstr = "STOPPED"; 317519cbe96aSPavel Labath } 317619cbe96aSPavel Labath else if (WIFEXITED(status)) 317719cbe96aSPavel Labath { 317819cbe96aSPavel Labath exit_status = WEXITSTATUS(status); 317919cbe96aSPavel Labath status_cstr = "EXITED"; 318019cbe96aSPavel Labath exited = true; 318119cbe96aSPavel Labath } 318219cbe96aSPavel Labath else if (WIFSIGNALED(status)) 318319cbe96aSPavel Labath { 318419cbe96aSPavel Labath signal = WTERMSIG(status); 318519cbe96aSPavel Labath status_cstr = "SIGNALED"; 318619cbe96aSPavel Labath if (wait_pid == static_cast< ::pid_t>(GetID())) { 318719cbe96aSPavel Labath exited = true; 318819cbe96aSPavel Labath exit_status = -1; 318919cbe96aSPavel Labath } 319019cbe96aSPavel Labath } 319119cbe96aSPavel Labath else 319219cbe96aSPavel Labath status_cstr = "(\?\?\?)"; 319319cbe96aSPavel Labath 319419cbe96aSPavel Labath if (log) 319519cbe96aSPavel Labath log->Printf("NativeProcessLinux::%s: waitpid (-1, &status, __WALL | __WNOTHREAD | WNOHANG)" 319619cbe96aSPavel Labath "=> pid = %" PRIi32 ", status = 0x%8.8x (%s), signal = %i, exit_state = %i", 319719cbe96aSPavel Labath __FUNCTION__, wait_pid, status, status_cstr, signal, exit_status); 319819cbe96aSPavel Labath 319919cbe96aSPavel Labath MonitorCallback (wait_pid, exited, signal, exit_status); 320019cbe96aSPavel Labath } 3201068f8a7eSTamas Berghammer } 3202068f8a7eSTamas Berghammer 3203068f8a7eSTamas Berghammer // Wrapper for ptrace to catch errors and log calls. 3204068f8a7eSTamas Berghammer // Note that ptrace sets errno on error because -1 can be a valid result (i.e. for PTRACE_PEEK*) 32054a9babb2SPavel Labath Error 32064a9babb2SPavel Labath NativeProcessLinux::PtraceWrapper(int req, lldb::pid_t pid, void *addr, void *data, size_t data_size, long *result) 3207068f8a7eSTamas Berghammer { 32084a9babb2SPavel Labath Error error; 32094a9babb2SPavel Labath long int ret; 3210068f8a7eSTamas Berghammer 3211068f8a7eSTamas Berghammer Log *log (ProcessPOSIXLog::GetLogIfAllCategoriesSet (POSIX_LOG_PTRACE)); 3212068f8a7eSTamas Berghammer 3213068f8a7eSTamas Berghammer PtraceDisplayBytes(req, data, data_size); 3214068f8a7eSTamas Berghammer 3215068f8a7eSTamas Berghammer errno = 0; 3216068f8a7eSTamas Berghammer if (req == PTRACE_GETREGSET || req == PTRACE_SETREGSET) 32174a9babb2SPavel Labath ret = ptrace(static_cast<__ptrace_request>(req), static_cast< ::pid_t>(pid), *(unsigned int *)addr, data); 3218068f8a7eSTamas Berghammer else 32194a9babb2SPavel Labath ret = ptrace(static_cast<__ptrace_request>(req), static_cast< ::pid_t>(pid), addr, data); 3220068f8a7eSTamas Berghammer 32214a9babb2SPavel Labath if (ret == -1) 3222068f8a7eSTamas Berghammer error.SetErrorToErrno(); 3223068f8a7eSTamas Berghammer 32244a9babb2SPavel Labath if (result) 32254a9babb2SPavel Labath *result = ret; 32264a9babb2SPavel Labath 3227068f8a7eSTamas Berghammer if (log) 32284a9babb2SPavel Labath log->Printf("ptrace(%d, %" PRIu64 ", %p, %p, %zu)=%lX", req, pid, addr, data, data_size, ret); 3229068f8a7eSTamas Berghammer 3230068f8a7eSTamas Berghammer PtraceDisplayBytes(req, data, data_size); 3231068f8a7eSTamas Berghammer 3232068f8a7eSTamas Berghammer if (log && error.GetError() != 0) 3233068f8a7eSTamas Berghammer { 3234068f8a7eSTamas Berghammer const char* str; 3235068f8a7eSTamas Berghammer switch (error.GetError()) 3236068f8a7eSTamas Berghammer { 3237068f8a7eSTamas Berghammer case ESRCH: str = "ESRCH"; break; 3238068f8a7eSTamas Berghammer case EINVAL: str = "EINVAL"; break; 3239068f8a7eSTamas Berghammer case EBUSY: str = "EBUSY"; break; 3240068f8a7eSTamas Berghammer case EPERM: str = "EPERM"; break; 3241068f8a7eSTamas Berghammer default: str = error.AsCString(); 3242068f8a7eSTamas Berghammer } 3243068f8a7eSTamas Berghammer log->Printf("ptrace() failed; errno=%d (%s)", error.GetError(), str); 3244068f8a7eSTamas Berghammer } 3245068f8a7eSTamas Berghammer 32464a9babb2SPavel Labath return error; 3247068f8a7eSTamas Berghammer } 3248