1be691f3bSpatrick //===-- ProcessTrace.cpp --------------------------------------------------===//
2be691f3bSpatrick //
3be691f3bSpatrick // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4be691f3bSpatrick // See https://llvm.org/LICENSE.txt for license information.
5be691f3bSpatrick // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6be691f3bSpatrick //
7be691f3bSpatrick //===----------------------------------------------------------------------===//
8be691f3bSpatrick
9be691f3bSpatrick #include "lldb/Target/ProcessTrace.h"
10be691f3bSpatrick
11be691f3bSpatrick #include <memory>
12be691f3bSpatrick
13be691f3bSpatrick #include "lldb/Core/Module.h"
14be691f3bSpatrick #include "lldb/Core/PluginManager.h"
15be691f3bSpatrick #include "lldb/Core/Section.h"
16*f6aab3d8Srobert #include "lldb/Target/ABI.h"
17be691f3bSpatrick #include "lldb/Target/SectionLoadList.h"
18be691f3bSpatrick #include "lldb/Target/Target.h"
19be691f3bSpatrick
20be691f3bSpatrick using namespace lldb;
21be691f3bSpatrick using namespace lldb_private;
22be691f3bSpatrick
GetPluginDescriptionStatic()23*f6aab3d8Srobert llvm::StringRef ProcessTrace::GetPluginDescriptionStatic() {
24be691f3bSpatrick return "Trace process plug-in.";
25be691f3bSpatrick }
26be691f3bSpatrick
Terminate()27be691f3bSpatrick void ProcessTrace::Terminate() {
28be691f3bSpatrick PluginManager::UnregisterPlugin(ProcessTrace::CreateInstance);
29be691f3bSpatrick }
30be691f3bSpatrick
CreateInstance(TargetSP target_sp,ListenerSP listener_sp,const FileSpec * crash_file,bool can_connect)31be691f3bSpatrick ProcessSP ProcessTrace::CreateInstance(TargetSP target_sp,
32be691f3bSpatrick ListenerSP listener_sp,
33be691f3bSpatrick const FileSpec *crash_file,
34be691f3bSpatrick bool can_connect) {
35be691f3bSpatrick if (can_connect)
36be691f3bSpatrick return nullptr;
37be691f3bSpatrick return std::make_shared<ProcessTrace>(target_sp, listener_sp);
38be691f3bSpatrick }
39be691f3bSpatrick
CanDebug(TargetSP target_sp,bool plugin_specified_by_name)40be691f3bSpatrick bool ProcessTrace::CanDebug(TargetSP target_sp, bool plugin_specified_by_name) {
41be691f3bSpatrick return plugin_specified_by_name;
42be691f3bSpatrick }
43be691f3bSpatrick
ProcessTrace(TargetSP target_sp,ListenerSP listener_sp)44be691f3bSpatrick ProcessTrace::ProcessTrace(TargetSP target_sp, ListenerSP listener_sp)
45be691f3bSpatrick : PostMortemProcess(target_sp, listener_sp) {}
46be691f3bSpatrick
~ProcessTrace()47be691f3bSpatrick ProcessTrace::~ProcessTrace() {
48be691f3bSpatrick Clear();
49be691f3bSpatrick // We need to call finalize on the process before destroying ourselves to
50be691f3bSpatrick // make sure all of the broadcaster cleanup goes as planned. If we destruct
51be691f3bSpatrick // this class, then Process::~Process() might have problems trying to fully
52be691f3bSpatrick // destroy the broadcaster.
53be691f3bSpatrick Finalize();
54be691f3bSpatrick }
55be691f3bSpatrick
DidAttach(ArchSpec & process_arch)56be691f3bSpatrick void ProcessTrace::DidAttach(ArchSpec &process_arch) {
57be691f3bSpatrick ListenerSP listener_sp(
58be691f3bSpatrick Listener::MakeListener("lldb.process_trace.did_attach_listener"));
59be691f3bSpatrick HijackProcessEvents(listener_sp);
60be691f3bSpatrick
61be691f3bSpatrick SetCanJIT(false);
62be691f3bSpatrick StartPrivateStateThread();
63be691f3bSpatrick SetPrivateState(eStateStopped);
64be691f3bSpatrick
65be691f3bSpatrick EventSP event_sp;
66*f6aab3d8Srobert WaitForProcessToStop(std::nullopt, &event_sp, true, listener_sp);
67be691f3bSpatrick
68be691f3bSpatrick RestoreProcessEvents();
69be691f3bSpatrick
70be691f3bSpatrick Process::DidAttach(process_arch);
71be691f3bSpatrick }
72be691f3bSpatrick
DoUpdateThreadList(ThreadList & old_thread_list,ThreadList & new_thread_list)73be691f3bSpatrick bool ProcessTrace::DoUpdateThreadList(ThreadList &old_thread_list,
74be691f3bSpatrick ThreadList &new_thread_list) {
75be691f3bSpatrick return false;
76be691f3bSpatrick }
77be691f3bSpatrick
RefreshStateAfterStop()78be691f3bSpatrick void ProcessTrace::RefreshStateAfterStop() {}
79be691f3bSpatrick
DoDestroy()80be691f3bSpatrick Status ProcessTrace::DoDestroy() { return Status(); }
81be691f3bSpatrick
ReadMemory(addr_t addr,void * buf,size_t size,Status & error)82be691f3bSpatrick size_t ProcessTrace::ReadMemory(addr_t addr, void *buf, size_t size,
83be691f3bSpatrick Status &error) {
84*f6aab3d8Srobert if (const ABISP &abi = GetABI())
85*f6aab3d8Srobert addr = abi->FixAnyAddress(addr);
86*f6aab3d8Srobert
87be691f3bSpatrick // Don't allow the caching that lldb_private::Process::ReadMemory does since
88be691f3bSpatrick // we have it all cached in the trace files.
89be691f3bSpatrick return DoReadMemory(addr, buf, size, error);
90be691f3bSpatrick }
91be691f3bSpatrick
Clear()92be691f3bSpatrick void ProcessTrace::Clear() { m_thread_list.Clear(); }
93be691f3bSpatrick
Initialize()94be691f3bSpatrick void ProcessTrace::Initialize() {
95be691f3bSpatrick static llvm::once_flag g_once_flag;
96be691f3bSpatrick
97be691f3bSpatrick llvm::call_once(g_once_flag, []() {
98be691f3bSpatrick PluginManager::RegisterPlugin(GetPluginNameStatic(),
99be691f3bSpatrick GetPluginDescriptionStatic(), CreateInstance);
100be691f3bSpatrick });
101be691f3bSpatrick }
102be691f3bSpatrick
GetArchitecture()103be691f3bSpatrick ArchSpec ProcessTrace::GetArchitecture() {
104be691f3bSpatrick return GetTarget().GetArchitecture();
105be691f3bSpatrick }
106be691f3bSpatrick
GetProcessInfo(ProcessInstanceInfo & info)107be691f3bSpatrick bool ProcessTrace::GetProcessInfo(ProcessInstanceInfo &info) {
108be691f3bSpatrick info.Clear();
109be691f3bSpatrick info.SetProcessID(GetID());
110be691f3bSpatrick info.SetArchitecture(GetArchitecture());
111be691f3bSpatrick ModuleSP module_sp = GetTarget().GetExecutableModule();
112be691f3bSpatrick if (module_sp) {
113be691f3bSpatrick const bool add_exe_file_as_first_arg = false;
114be691f3bSpatrick info.SetExecutableFile(GetTarget().GetExecutableModule()->GetFileSpec(),
115be691f3bSpatrick add_exe_file_as_first_arg);
116be691f3bSpatrick }
117be691f3bSpatrick return true;
118be691f3bSpatrick }
119be691f3bSpatrick
DoReadMemory(addr_t addr,void * buf,size_t size,Status & error)120be691f3bSpatrick size_t ProcessTrace::DoReadMemory(addr_t addr, void *buf, size_t size,
121be691f3bSpatrick Status &error) {
122be691f3bSpatrick Address resolved_address;
123be691f3bSpatrick GetTarget().GetSectionLoadList().ResolveLoadAddress(addr, resolved_address);
124be691f3bSpatrick
125be691f3bSpatrick return GetTarget().ReadMemoryFromFileCache(resolved_address, buf, size,
126be691f3bSpatrick error);
127be691f3bSpatrick }
128