bool ProcessFreeBSD::UpdateThreadList(ThreadList &old_thread_list, ThreadList &new_thread_list) { Log *log (ProcessPOSIXLog::GetLogIfAllCategoriesSet (POSIX_LOG_THREAD)); if (log && log->GetMask().Test(POSIX_LOG_VERBOSE)) log->Printf ("ProcessFreeBSD::%s() (pid = %" PRIu64 ")", __FUNCTION__, GetID()); bool has_updated = false; const lldb::pid_t pid = GetID(); // Update the process thread list with this new thread. // FIXME: We should be using tid, not pid. assert(m_monitor); ThreadSP thread_sp (old_thread_list.FindThreadByID (pid, false)); if (!thread_sp) { ProcessSP me = this->shared_from_this(); thread_sp.reset(new POSIXThread(*me, pid)); has_updated = true; } if (log && log->GetMask().Test(POSIX_LOG_VERBOSE)) log->Printf ("ProcessFreeBSD::%s() updated tid = %" PRIu64, __FUNCTION__, pid); new_thread_list.AddThread(thread_sp); return has_updated; // the list has been updated }
void ProcessPOSIXLog::DisableLog (const char **args, Stream *feedback_strm) { Log *log (GetLog ()); if (log) { uint32_t flag_bits = 0; flag_bits = log->GetMask().Get(); for (; args[0]; args++) { const char *arg = args[0]; uint32_t bits = GetFlagBits(arg); if (bits) { flag_bits &= ~bits; } else { feedback_strm->Printf("error: unrecognized log category '%s'\n", arg); ListLogCategories (feedback_strm); } } log->GetMask().Reset (flag_bits); if (flag_bits == 0) g_log_enabled = false; } return; }
Log * lldb_private::EnableLog (StreamSP &log_stream_sp, uint32_t log_options, Args &args, Stream *feedback_strm) { // Try see if there already is a log - that way we can reuse its settings. // We could reuse the log in toto, but we don't know that the stream is the same. uint32_t flag_bits; Log* log = LogAccessor (true, NULL); if (log) flag_bits = log->GetMask().GetAllFlagBits(); else flag_bits = 0; // Now make a new log with this stream. log = LogAccessor (false, &log_stream_sp); if (log) { bool got_unknown_category = false; const size_t argc = args.GetArgumentCount(); for (size_t i=0; i<argc; ++i) { const char *arg = args.GetArgumentAtIndex(i); if (strcasecmp(arg, "all") == 0 ) flag_bits |= LIBLLDB_LOG_ALL; else if (strcasestr(arg, "break") == arg) flag_bits |= LIBLLDB_LOG_BREAKPOINTS; else if (strcasecmp(arg, "default") == 0 ) flag_bits |= LIBLLDB_LOG_DEFAULT; else if (strcasestr(arg, "event") == arg) flag_bits |= LIBLLDB_LOG_EVENTS; else if (strcasestr(arg, "expr") == arg) flag_bits |= LIBLLDB_LOG_EXPRESSIONS; else if (strcasestr(arg, "object") == arg) flag_bits |= LIBLLDB_LOG_OBJECT; else if (strcasecmp(arg, "process") == 0 ) flag_bits |= LIBLLDB_LOG_PROCESS; else if (strcasecmp(arg, "shlib") == 0 ) flag_bits |= LIBLLDB_LOG_SHLIB; else if (strcasecmp(arg, "state") == 0 ) flag_bits |= LIBLLDB_LOG_STATE; else if (strcasecmp(arg, "step") == 0 ) flag_bits |= LIBLLDB_LOG_STEP; else if (strcasecmp(arg, "thread") == 0 ) flag_bits |= LIBLLDB_LOG_THREAD; else if (strcasecmp(arg, "verbose") == 0 ) flag_bits |= LIBLLDB_LOG_VERBOSE; else if (strcasestr(arg, "watch") == arg) flag_bits |= LIBLLDB_LOG_WATCHPOINTS; else if (strcasestr(arg, "temp") == arg) flag_bits |= LIBLLDB_LOG_TEMPORARY; else if (strcasestr(arg, "comm") == arg) flag_bits |= LIBLLDB_LOG_COMMUNICATION; else if (strcasestr(arg, "conn") == arg) flag_bits |= LIBLLDB_LOG_CONNECTION; else { feedback_strm->Printf("error: unrecognized log category '%s'\n", arg); if (got_unknown_category == false) { got_unknown_category = true; ListLogCategories (feedback_strm); return log; } } } log->GetMask().SetAllFlagBits(flag_bits); log->GetOptions().SetAllFlagBits(log_options); } return log; }
POSIXThread::POSIXThread(Process &process, lldb::tid_t tid) : Thread(process, tid), m_frame_ap (), m_breakpoint (), m_thread_name_valid (false), m_thread_name (), m_posix_thread(NULL) { Log *log (ProcessPOSIXLog::GetLogIfAllCategoriesSet (POSIX_LOG_THREAD)); if (log && log->GetMask().Test(POSIX_LOG_VERBOSE)) log->Printf ("POSIXThread::%s (tid = %" PRIi64 ")", __FUNCTION__, tid); // Set the current watchpoints for this thread. Target &target = GetProcess()->GetTarget(); const WatchpointList &wp_list = target.GetWatchpointList(); size_t wp_size = wp_list.GetSize(); for (uint32_t wp_idx = 0; wp_idx < wp_size; wp_idx++) { lldb::WatchpointSP wp = wp_list.GetByIndex(wp_idx); if (wp.get() && wp->IsEnabled()) { // This watchpoint as been enabled; obviously this "new" thread // has been created since that watchpoint was enabled. Since // the POSIXBreakpointProtocol has yet to be initialized, its // m_watchpoints_initialized member will be FALSE. Attempting to // read the debug status register to determine if a watchpoint // has been hit would result in the zeroing of that register. // Since the active debug registers would have been cloned when // this thread was created, simply force the m_watchpoints_initized // member to TRUE and avoid resetting dr6 and dr7. GetPOSIXBreakpointProtocol()->ForceWatchpointsInitialized(); } } }
POSIXThread::POSIXThread(Process &process, lldb::tid_t tid) : Thread(process, tid), m_frame_ap (), m_breakpoint (), m_thread_name_valid (false), m_thread_name (), m_posix_thread(NULL) { Log *log (ProcessPOSIXLog::GetLogIfAllCategoriesSet (POSIX_LOG_THREAD)); if (log && log->GetMask().Test(POSIX_LOG_VERBOSE)) log->Printf ("POSIXThread::%s (tid = %" PRIi64 ")", __FUNCTION__, tid); // Set the current watchpoints for this thread. Target &target = GetProcess()->GetTarget(); const WatchpointList &wp_list = target.GetWatchpointList(); size_t wp_size = wp_list.GetSize(); for (uint32_t wp_idx = 0; wp_idx < wp_size; wp_idx++) { lldb::WatchpointSP wp = wp_list.GetByIndex(wp_idx); if (wp.get() && wp->IsEnabled()) { assert(EnableHardwareWatchpoint(wp.get())); } } }
bool ThreadMacOSX::RestoreSuspendCount() { Log *log = ProcessMacOSXLog::GetLogIfAllCategoriesSet(PD_LOG_THREAD); if (log && log->GetMask().IsSet(PD_LOG_VERBOSE)) log->Printf ("ThreadMacOSX::%s ( )", __FUNCTION__); Error err; lldb::tid_t tid = GetID (); if (ThreadIDIsValid(tid) == false) return false; else if (m_suspend_count > m_basic_info.suspend_count) { while (m_suspend_count > m_basic_info.suspend_count) { err = ::thread_resume (tid); if (err.Success()) --m_suspend_count; if (log || err.Fail()) err.PutToLog(log, "::thread_resume (%4.4x)", tid); } } else if (m_suspend_count < m_basic_info.suspend_count) { while (m_suspend_count < m_basic_info.suspend_count) { err = ::thread_suspend (tid); if (err.Success()) --m_suspend_count; if (log || err.Fail()) err.PutToLog(log, "::thread_suspend (%4.4x)", tid); } } return m_suspend_count == m_basic_info.suspend_count; }
Log * lldb_private::GetLogIfAnyCategoriesSet (uint32_t mask) { Log *log = LogAccessor (true, NULL); if (log && mask && (mask & log->GetMask().GetAllFlagBits())) return log; return NULL; }
uint32_t lldb_private::GetLogMask () { Log *log = LogAccessor (true, NULL); if (log) return log->GetMask().GetAllFlagBits(); return 0; }
void ProcessPOSIX::RefreshStateAfterStop() { Log *log (ProcessPOSIXLog::GetLogIfAllCategoriesSet (POSIX_LOG_PROCESS)); if (log && log->GetMask().Test(POSIX_LOG_VERBOSE)) log->Printf ("ProcessPOSIX::%s(), message_queue size = %d", __FUNCTION__, (int)m_message_queue.size()); Mutex::Locker lock(m_message_mutex); // This method used to only handle one message. Changing it to loop allows // it to handle the case where we hit a breakpoint while handling a different // breakpoint. while (!m_message_queue.empty()) { ProcessMessage &message = m_message_queue.front(); // Resolve the thread this message corresponds to and pass it along. lldb::tid_t tid = message.GetTID(); if (log) log->Printf ("ProcessPOSIX::%s(), message_queue size = %d, pid = %" PRIi64, __FUNCTION__, (int)m_message_queue.size(), tid); if (message.GetKind() == ProcessMessage::eNewThreadMessage) { if (log) log->Printf ("ProcessPOSIX::%s() adding thread, tid = %" PRIi64, __FUNCTION__, message.GetChildTID()); lldb::tid_t child_tid = message.GetChildTID(); ThreadSP thread_sp; thread_sp.reset(CreateNewPOSIXThread(*this, child_tid)); Mutex::Locker lock(m_thread_list.GetMutex()); m_thread_list.AddThread(thread_sp); } m_thread_list.RefreshStateAfterStop(); POSIXThread *thread = static_cast<POSIXThread*>( GetThreadList().FindThreadByID(tid, false).get()); if (thread) thread->Notify(message); if (message.GetKind() == ProcessMessage::eExitMessage) { // FIXME: We should tell the user about this, but the limbo message is probably better for that. if (log) log->Printf ("ProcessPOSIX::%s() removing thread, tid = %" PRIi64, __FUNCTION__, tid); Mutex::Locker lock(m_thread_list.GetMutex()); ThreadSP thread_sp = m_thread_list.RemoveThreadByID(tid, false); thread_sp.reset(); m_seen_initial_stop.erase(tid); } m_message_queue.pop(); } }
void ProcessPOSIXLog::DisableLog (const char **args, Stream *feedback_strm) { Log *log (GetLog ()); if (log) { uint32_t flag_bits = 0; flag_bits = log->GetMask().Get(); for (; args[0]; args++) { const char *arg = args[0]; if (::strcasecmp (arg, "all") == 0 ) flag_bits &= ~POSIX_LOG_ALL; else if (::strcasecmp (arg, "async") == 0 ) flag_bits &= ~POSIX_LOG_ASYNC; else if (::strncasecmp (arg, "break", 5) == 0 ) flag_bits &= ~POSIX_LOG_BREAKPOINTS; else if (::strncasecmp (arg, "comm", 4) == 0 ) flag_bits &= ~POSIX_LOG_COMM; else if (::strcasecmp (arg, "default") == 0 ) flag_bits &= ~POSIX_LOG_DEFAULT; else if (::strcasecmp (arg, "packets") == 0 ) flag_bits &= ~POSIX_LOG_PACKETS; else if (::strcasecmp (arg, "memory") == 0 ) flag_bits &= ~POSIX_LOG_MEMORY; else if (::strcasecmp (arg, "data-short") == 0 ) flag_bits &= ~POSIX_LOG_MEMORY_DATA_SHORT; else if (::strcasecmp (arg, "data-long") == 0 ) flag_bits &= ~POSIX_LOG_MEMORY_DATA_LONG; else if (::strcasecmp (arg, "process") == 0 ) flag_bits &= ~POSIX_LOG_PROCESS; else if (::strcasecmp (arg, "ptrace") == 0 ) flag_bits &= ~POSIX_LOG_PTRACE; else if (::strcasecmp (arg, "registers") == 0 ) flag_bits &= ~POSIX_LOG_REGISTERS; else if (::strcasecmp (arg, "step") == 0 ) flag_bits &= ~POSIX_LOG_STEP; else if (::strcasecmp (arg, "thread") == 0 ) flag_bits &= ~POSIX_LOG_THREAD; else if (::strcasecmp (arg, "verbose") == 0 ) flag_bits &= ~POSIX_LOG_VERBOSE; else if (::strncasecmp (arg, "watch", 5) == 0 ) flag_bits &= ~POSIX_LOG_WATCHPOINTS; else { feedback_strm->Printf("error: unrecognized log category '%s'\n", arg); ListLogCategories (feedback_strm); } } log->GetMask().Reset (flag_bits); if (flag_bits == 0) g_log_enabled = false; } return; }
bool MachVMRegion::GetRegionForAddress(lldb::addr_t addr) { // Restore any original protections and clear our vars Clear(); m_addr = addr; m_start = addr; m_depth = 1024; mach_msg_type_number_t info_size = kRegionInfoSize; assert(sizeof(info_size) == 4); m_err = ::mach_vm_region_recurse (m_task, &m_start, &m_size, &m_depth, (vm_region_recurse_info_t)&m_data, &info_size); Log *log = ProcessMacOSXLog::GetLogIfAllCategoriesSet (PD_LOG_MEMORY_PROTECTIONS); if (log || m_err.Fail()) m_err.PutToLog(log, "::mach_vm_region_recurse ( task = 0x%4.4x, address => 0x%8.8llx, size => %llu, nesting_depth => %d, info => %p, infoCnt => %d) addr = 0x%8.8llx ", m_task, (uint64_t)m_start, (uint64_t)m_size, m_depth, &m_data, info_size, (uint64_t)addr); if (m_err.Fail()) { return false; } else { if (log && log->GetMask().IsSet(PD_LOG_VERBOSE)) { log->Printf("info = { prot = %u, " "max_prot = %u, " "inheritance = 0x%8.8x, " "offset = 0x%8.8llx, " "user_tag = 0x%8.8x, " "ref_count = %u, " "shadow_depth = %u, " "ext_pager = %u, " "share_mode = %u, " "is_submap = %d, " "behavior = %d, " "object_id = 0x%8.8x, " "user_wired_count = 0x%4.4x }", m_data.protection, m_data.max_protection, m_data.inheritance, (uint64_t)m_data.offset, m_data.user_tag, m_data.ref_count, m_data.shadow_depth, m_data.external_pager, m_data.share_mode, m_data.is_submap, m_data.behavior, m_data.object_id, m_data.user_wired_count); } } m_curr_protection = m_data.protection; return true; }
Log * LogChannelDWARF::GetLogIfAll (uint32_t mask) { Log *log = GetLog(); if (log) { if (log->GetMask().AllSet(mask)) return log; } return NULL; }
bool ProcessPOSIX::UpdateThreadList(ThreadList &old_thread_list, ThreadList &new_thread_list) { Log *log (ProcessPOSIXLog::GetLogIfAllCategoriesSet (POSIX_LOG_THREAD)); if (log && log->GetMask().Test(POSIX_LOG_VERBOSE)) log->Printf ("ProcessPOSIX::%s() (pid = %" PRIi64 ")", __FUNCTION__, GetID()); // Update the process thread list with this new thread. // FIXME: We should be using tid, not pid. assert(m_monitor); ThreadSP thread_sp (old_thread_list.FindThreadByID (GetID(), false)); if (!thread_sp) { thread_sp.reset(CreateNewPOSIXThread(*this, GetID())); } if (log && log->GetMask().Test(POSIX_LOG_VERBOSE)) log->Printf ("ProcessPOSIX::%s() updated pid = %" PRIi64, __FUNCTION__, GetID()); new_thread_list.AddThread(thread_sp); return new_thread_list.GetSize(false) > 0; }
Log * lldb_private::GetLogIfAllCategoriesSet (uint32_t mask) { Log *log = LogAccessor (true, NULL); if (log && mask) { uint32_t log_mask = log->GetMask().GetAllFlagBits(); if ((log_mask & mask) != mask) return NULL; } return log; }
// by global constructors before other threads // were done with it. Log * ProcessMacOSXLog::GetLogIfAllCategoriesSet (uint32_t mask) { Log *log = g_log; if (log && mask) { uint32_t log_mask = log->GetMask().GetAllFlagBits(); if ((log_mask & mask) != mask) return NULL; } return log; }
void LogChannelDWARF::LogIf (uint32_t mask, const char *format, ...) { if (g_log_channel) { Log *log = g_log_channel->m_log_ap.get(); if (log && log->GetMask().AnySet(mask)) { va_list args; va_start (args, format); log->VAPrintf (format, args); va_end (args); } } }
Error ProcessFreeBSD::DoAttachToProcessWithID (lldb::pid_t pid, const ProcessAttachInfo &attach_info) { Error error; assert(m_monitor == NULL); Log *log (ProcessPOSIXLog::GetLogIfAllCategoriesSet (POSIX_LOG_PROCESS)); if (log && log->GetMask().Test(POSIX_LOG_VERBOSE)) log->Printf ("ProcessFreeBSD::%s(pid = %" PRIi64 ")", __FUNCTION__, GetID()); m_monitor = new ProcessMonitor(this, pid, error); if (!error.Success()) return error; PlatformSP platform_sp (m_target.GetPlatform ()); assert (platform_sp.get()); if (!platform_sp) return error; // FIXME: Detatch? // Find out what we can about this process ProcessInstanceInfo process_info; platform_sp->GetProcessInfo (pid, process_info); // Resolve the executable module ModuleSP exe_module_sp; FileSpecList executable_search_paths (Target::GetDefaultExecutableSearchPaths()); ModuleSpec exe_module_spec(process_info.GetExecutableFile(), m_target.GetArchitecture()); error = platform_sp->ResolveExecutable(exe_module_spec, exe_module_sp, executable_search_paths.GetSize() ? &executable_search_paths : NULL); if (!error.Success()) return error; // Fix the target architecture if necessary const ArchSpec &module_arch = exe_module_sp->GetArchitecture(); if (module_arch.IsValid() && !m_target.GetArchitecture().IsExactMatch(module_arch)) m_target.SetArchitecture(module_arch); // Initialize the target module list m_target.SetExecutableModule (exe_module_sp, true); SetSTDIOFileDescriptor(m_monitor->GetTerminalFD()); SetID(pid); return error; }
bool ProcessKDP::UpdateThreadList (ThreadList &old_thread_list, ThreadList &new_thread_list) { // locker will keep a mutex locked until it goes out of scope Log *log (ProcessKDPLog::GetLogIfAllCategoriesSet (KDP_LOG_THREAD)); if (log && log->GetMask().Test(KDP_LOG_VERBOSE)) log->Printf ("ProcessKDP::%s (pid = %" PRIu64 ")", __FUNCTION__, GetID()); // Even though there is a CPU mask, it doesn't mean we can see each CPU // individually, there is really only one. Lets call this thread 1. ThreadSP thread_sp (old_thread_list.FindThreadByProtocolID(g_kernel_tid, false)); if (!thread_sp) thread_sp = GetKernelThread (); new_thread_list.AddThread(thread_sp); return new_thread_list.GetSize(false) > 0; }
int32_t ThreadMacOSX::Suspend() { Log *log = ProcessMacOSXLog::GetLogIfAllCategoriesSet(PD_LOG_THREAD); if (log && log->GetMask().IsSet(PD_LOG_VERBOSE)) log->Printf ("ThreadMacOSX::%s ( )", __FUNCTION__); lldb::tid_t tid = GetID (); if (ThreadIDIsValid(tid)) { Error err(::thread_suspend (tid), eErrorTypeMachKernel); if (err.Success()) m_suspend_count++; if (log || err.Fail()) err.PutToLog(log, "::thread_suspend (%4.4x)", tid); } return GetSuspendCount(); }
lldb::RegisterContextSP POSIXThread::CreateRegisterContextForFrame(lldb_private::StackFrame *frame) { lldb::RegisterContextSP reg_ctx_sp; uint32_t concrete_frame_idx = 0; Log *log (ProcessPOSIXLog::GetLogIfAllCategoriesSet (POSIX_LOG_THREAD)); if (log && log->GetMask().Test(POSIX_LOG_VERBOSE)) log->Printf ("POSIXThread::%s ()", __FUNCTION__); if (frame) concrete_frame_idx = frame->GetConcreteFrameIndex(); if (concrete_frame_idx == 0) reg_ctx_sp = GetRegisterContext(); else { assert(GetUnwinder()); reg_ctx_sp = GetUnwinder()->CreateRegisterContextForFrame(frame); } return reg_ctx_sp; }