File: ProcessTrace.cpp

package info (click to toggle)
llvm-toolchain-17 1%3A17.0.6-22
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 1,799,624 kB
  • sloc: cpp: 6,428,607; ansic: 1,383,196; asm: 793,408; python: 223,504; objc: 75,364; f90: 60,502; lisp: 33,869; pascal: 15,282; sh: 9,684; perl: 7,453; ml: 4,937; awk: 3,523; makefile: 2,889; javascript: 2,149; xml: 888; fortran: 619; cs: 573
file content (127 lines) | stat: -rw-r--r-- 4,046 bytes parent folder | download | duplicates (3)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
//===-- ProcessTrace.cpp --------------------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//

#include "lldb/Target/ProcessTrace.h"

#include <memory>

#include "lldb/Core/Module.h"
#include "lldb/Core/PluginManager.h"
#include "lldb/Core/Section.h"
#include "lldb/Target/ABI.h"
#include "lldb/Target/SectionLoadList.h"
#include "lldb/Target/Target.h"

using namespace lldb;
using namespace lldb_private;

llvm::StringRef ProcessTrace::GetPluginDescriptionStatic() {
  return "Trace process plug-in.";
}

void ProcessTrace::Terminate() {
  PluginManager::UnregisterPlugin(ProcessTrace::CreateInstance);
}

ProcessSP ProcessTrace::CreateInstance(TargetSP target_sp,
                                       ListenerSP listener_sp,
                                       const FileSpec *crash_file,
                                       bool can_connect) {
  if (can_connect)
    return nullptr;
  return std::make_shared<ProcessTrace>(target_sp, listener_sp);
}

bool ProcessTrace::CanDebug(TargetSP target_sp, bool plugin_specified_by_name) {
  return plugin_specified_by_name;
}

ProcessTrace::ProcessTrace(TargetSP target_sp, ListenerSP listener_sp)
    : PostMortemProcess(target_sp, listener_sp) {}

ProcessTrace::~ProcessTrace() {
  Clear();
  // We need to call finalize on the process before destroying ourselves to
  // make sure all of the broadcaster cleanup goes as planned. If we destruct
  // this class, then Process::~Process() might have problems trying to fully
  // destroy the broadcaster.
  Finalize();
}

void ProcessTrace::DidAttach(ArchSpec &process_arch) {
  ListenerSP listener_sp(
      Listener::MakeListener("lldb.process_trace.did_attach_listener"));
  HijackProcessEvents(listener_sp);

  SetCanJIT(false);
  StartPrivateStateThread();
  SetPrivateState(eStateStopped);

  EventSP event_sp;
  WaitForProcessToStop(std::nullopt, &event_sp, true, listener_sp);

  RestoreProcessEvents();

  Process::DidAttach(process_arch);
}

bool ProcessTrace::DoUpdateThreadList(ThreadList &old_thread_list,
                                      ThreadList &new_thread_list) {
  return false;
}

void ProcessTrace::RefreshStateAfterStop() {}

Status ProcessTrace::DoDestroy() { return Status(); }

size_t ProcessTrace::ReadMemory(addr_t addr, void *buf, size_t size,
                                Status &error) {
  if (const ABISP &abi = GetABI())
    addr = abi->FixAnyAddress(addr);

  // Don't allow the caching that lldb_private::Process::ReadMemory does since
  // we have it all cached in the trace files.
  return DoReadMemory(addr, buf, size, error);
}

void ProcessTrace::Clear() { m_thread_list.Clear(); }

void ProcessTrace::Initialize() {
  static llvm::once_flag g_once_flag;

  llvm::call_once(g_once_flag, []() {
    PluginManager::RegisterPlugin(GetPluginNameStatic(),
                                  GetPluginDescriptionStatic(), CreateInstance);
  });
}

ArchSpec ProcessTrace::GetArchitecture() {
  return GetTarget().GetArchitecture();
}

bool ProcessTrace::GetProcessInfo(ProcessInstanceInfo &info) {
  info.Clear();
  info.SetProcessID(GetID());
  info.SetArchitecture(GetArchitecture());
  ModuleSP module_sp = GetTarget().GetExecutableModule();
  if (module_sp) {
    const bool add_exe_file_as_first_arg = false;
    info.SetExecutableFile(GetTarget().GetExecutableModule()->GetFileSpec(),
                           add_exe_file_as_first_arg);
  }
  return true;
}

size_t ProcessTrace::DoReadMemory(addr_t addr, void *buf, size_t size,
                                  Status &error) {
  Address resolved_address;
  GetTarget().GetSectionLoadList().ResolveLoadAddress(addr, resolved_address);

  return GetTarget().ReadMemoryFromFileCache(resolved_address, buf, size,
                                             error);
}