18a203bb2SWalter Erquinigo //===-- ProcessTrace.cpp --------------------------------------------------===// 28a203bb2SWalter Erquinigo // 38a203bb2SWalter Erquinigo // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 48a203bb2SWalter Erquinigo // See https://llvm.org/LICENSE.txt for license information. 58a203bb2SWalter Erquinigo // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 68a203bb2SWalter Erquinigo // 78a203bb2SWalter Erquinigo //===----------------------------------------------------------------------===// 88a203bb2SWalter Erquinigo 98a203bb2SWalter Erquinigo #include "lldb/Target/ProcessTrace.h" 108a203bb2SWalter Erquinigo 118a203bb2SWalter Erquinigo #include <memory> 128a203bb2SWalter Erquinigo 138a203bb2SWalter Erquinigo #include "lldb/Core/Module.h" 148a203bb2SWalter Erquinigo #include "lldb/Core/PluginManager.h" 15*cfd96f05SWalter Erquinigo #include "lldb/Core/Section.h" 16*cfd96f05SWalter Erquinigo #include "lldb/Target/SectionLoadList.h" 178a203bb2SWalter Erquinigo #include "lldb/Target/Target.h" 188a203bb2SWalter Erquinigo 198a203bb2SWalter Erquinigo using namespace lldb; 208a203bb2SWalter Erquinigo using namespace lldb_private; 218a203bb2SWalter Erquinigo 228a203bb2SWalter Erquinigo ConstString ProcessTrace::GetPluginNameStatic() { 238a203bb2SWalter Erquinigo static ConstString g_name("trace"); 248a203bb2SWalter Erquinigo return g_name; 258a203bb2SWalter Erquinigo } 268a203bb2SWalter Erquinigo 278a203bb2SWalter Erquinigo const char *ProcessTrace::GetPluginDescriptionStatic() { 288a203bb2SWalter Erquinigo return "Trace process plug-in."; 298a203bb2SWalter Erquinigo } 308a203bb2SWalter Erquinigo 318a203bb2SWalter Erquinigo void ProcessTrace::Terminate() { 328a203bb2SWalter Erquinigo PluginManager::UnregisterPlugin(ProcessTrace::CreateInstance); 338a203bb2SWalter Erquinigo } 348a203bb2SWalter Erquinigo 358a203bb2SWalter Erquinigo ProcessSP ProcessTrace::CreateInstance(TargetSP target_sp, 368a203bb2SWalter Erquinigo ListenerSP listener_sp, 378a203bb2SWalter Erquinigo const FileSpec *crash_file) { 388a203bb2SWalter Erquinigo return std::make_shared<ProcessTrace>(target_sp, listener_sp); 398a203bb2SWalter Erquinigo } 408a203bb2SWalter Erquinigo 418a203bb2SWalter Erquinigo bool ProcessTrace::CanDebug(TargetSP target_sp, bool plugin_specified_by_name) { 428a203bb2SWalter Erquinigo return plugin_specified_by_name; 438a203bb2SWalter Erquinigo } 448a203bb2SWalter Erquinigo 458a203bb2SWalter Erquinigo ProcessTrace::ProcessTrace(TargetSP target_sp, ListenerSP listener_sp) 468a203bb2SWalter Erquinigo : Process(target_sp, listener_sp) {} 478a203bb2SWalter Erquinigo 488a203bb2SWalter Erquinigo ProcessTrace::~ProcessTrace() { 498a203bb2SWalter Erquinigo Clear(); 508a203bb2SWalter Erquinigo // We need to call finalize on the process before destroying ourselves to 518a203bb2SWalter Erquinigo // make sure all of the broadcaster cleanup goes as planned. If we destruct 528a203bb2SWalter Erquinigo // this class, then Process::~Process() might have problems trying to fully 538a203bb2SWalter Erquinigo // destroy the broadcaster. 548a203bb2SWalter Erquinigo Finalize(); 558a203bb2SWalter Erquinigo } 568a203bb2SWalter Erquinigo 578a203bb2SWalter Erquinigo ConstString ProcessTrace::GetPluginName() { return GetPluginNameStatic(); } 588a203bb2SWalter Erquinigo 598a203bb2SWalter Erquinigo uint32_t ProcessTrace::GetPluginVersion() { return 1; } 608a203bb2SWalter Erquinigo 618a203bb2SWalter Erquinigo void ProcessTrace::DidAttach(ArchSpec &process_arch) { 628a203bb2SWalter Erquinigo ListenerSP listener_sp( 638a203bb2SWalter Erquinigo Listener::MakeListener("lldb.process_trace.did_attach_listener")); 648a203bb2SWalter Erquinigo HijackProcessEvents(listener_sp); 658a203bb2SWalter Erquinigo 668a203bb2SWalter Erquinigo SetCanJIT(false); 678a203bb2SWalter Erquinigo StartPrivateStateThread(); 688a203bb2SWalter Erquinigo SetPrivateState(eStateStopped); 698a203bb2SWalter Erquinigo 708a203bb2SWalter Erquinigo EventSP event_sp; 718a203bb2SWalter Erquinigo WaitForProcessToStop(llvm::None, &event_sp, true, listener_sp); 728a203bb2SWalter Erquinigo 738a203bb2SWalter Erquinigo RestoreProcessEvents(); 748a203bb2SWalter Erquinigo 758a203bb2SWalter Erquinigo Process::DidAttach(process_arch); 768a203bb2SWalter Erquinigo } 778a203bb2SWalter Erquinigo 788a203bb2SWalter Erquinigo bool ProcessTrace::UpdateThreadList(ThreadList &old_thread_list, 798a203bb2SWalter Erquinigo ThreadList &new_thread_list) { 808a203bb2SWalter Erquinigo return false; 818a203bb2SWalter Erquinigo } 828a203bb2SWalter Erquinigo 838a203bb2SWalter Erquinigo void ProcessTrace::RefreshStateAfterStop() {} 848a203bb2SWalter Erquinigo 858a203bb2SWalter Erquinigo Status ProcessTrace::DoDestroy() { return Status(); } 868a203bb2SWalter Erquinigo 878a203bb2SWalter Erquinigo bool ProcessTrace::IsAlive() { return true; } 888a203bb2SWalter Erquinigo 898a203bb2SWalter Erquinigo size_t ProcessTrace::ReadMemory(addr_t addr, void *buf, size_t size, 908a203bb2SWalter Erquinigo Status &error) { 918a203bb2SWalter Erquinigo // Don't allow the caching that lldb_private::Process::ReadMemory does since 928a203bb2SWalter Erquinigo // we have it all cached in the trace files. 938a203bb2SWalter Erquinigo return DoReadMemory(addr, buf, size, error); 948a203bb2SWalter Erquinigo } 958a203bb2SWalter Erquinigo 968a203bb2SWalter Erquinigo void ProcessTrace::Clear() { m_thread_list.Clear(); } 978a203bb2SWalter Erquinigo 988a203bb2SWalter Erquinigo void ProcessTrace::Initialize() { 998a203bb2SWalter Erquinigo static llvm::once_flag g_once_flag; 1008a203bb2SWalter Erquinigo 1018a203bb2SWalter Erquinigo llvm::call_once(g_once_flag, []() { 1028a203bb2SWalter Erquinigo PluginManager::RegisterPlugin(GetPluginNameStatic(), 1038a203bb2SWalter Erquinigo GetPluginDescriptionStatic(), CreateInstance); 1048a203bb2SWalter Erquinigo }); 1058a203bb2SWalter Erquinigo } 1068a203bb2SWalter Erquinigo 1078a203bb2SWalter Erquinigo ArchSpec ProcessTrace::GetArchitecture() { 1088a203bb2SWalter Erquinigo return GetTarget().GetArchitecture(); 1098a203bb2SWalter Erquinigo } 1108a203bb2SWalter Erquinigo 1118a203bb2SWalter Erquinigo bool ProcessTrace::GetProcessInfo(ProcessInstanceInfo &info) { 1128a203bb2SWalter Erquinigo info.Clear(); 1138a203bb2SWalter Erquinigo info.SetProcessID(GetID()); 1148a203bb2SWalter Erquinigo info.SetArchitecture(GetArchitecture()); 1158a203bb2SWalter Erquinigo ModuleSP module_sp = GetTarget().GetExecutableModule(); 1168a203bb2SWalter Erquinigo if (module_sp) { 1178a203bb2SWalter Erquinigo const bool add_exe_file_as_first_arg = false; 1188a203bb2SWalter Erquinigo info.SetExecutableFile(GetTarget().GetExecutableModule()->GetFileSpec(), 1198a203bb2SWalter Erquinigo add_exe_file_as_first_arg); 1208a203bb2SWalter Erquinigo } 1218a203bb2SWalter Erquinigo return true; 1228a203bb2SWalter Erquinigo } 1238a203bb2SWalter Erquinigo 1248a203bb2SWalter Erquinigo size_t ProcessTrace::DoReadMemory(addr_t addr, void *buf, size_t size, 1258a203bb2SWalter Erquinigo Status &error) { 126*cfd96f05SWalter Erquinigo Address resolved_address; 127*cfd96f05SWalter Erquinigo GetTarget().GetSectionLoadList().ResolveLoadAddress(addr, resolved_address); 128*cfd96f05SWalter Erquinigo 129*cfd96f05SWalter Erquinigo return GetTarget().ReadMemoryFromFileCache(resolved_address, buf, size, 130*cfd96f05SWalter Erquinigo error); 1318a203bb2SWalter Erquinigo } 132