Coverage Report

Created: 2022-01-18 06:27

/Users/buildslave/jenkins/workspace/coverage/llvm-project/lldb/include/lldb/Utility/Reproducer.h
Line
Count
Source (jump to first uncovered line)
1
//===-- Reproducer.h --------------------------------------------*- C++ -*-===//
2
//
3
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4
// See https://llvm.org/LICENSE.txt for license information.
5
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6
//
7
//===----------------------------------------------------------------------===//
8
9
#ifndef LLDB_UTILITY_REPRODUCER_H
10
#define LLDB_UTILITY_REPRODUCER_H
11
12
#include "lldb/Utility/FileSpec.h"
13
#include "llvm/ADT/DenseMap.h"
14
#include "llvm/ADT/StringRef.h"
15
#include "llvm/Support/Error.h"
16
#include "llvm/Support/VirtualFileSystem.h"
17
#include "llvm/Support/YAMLTraits.h"
18
19
#include <mutex>
20
#include <string>
21
#include <utility>
22
#include <vector>
23
24
namespace lldb_private {
25
class UUID;
26
namespace repro {
27
28
class Reproducer;
29
30
enum class ReproducerMode {
31
  Capture,
32
  Off,
33
};
34
35
/// The provider defines an interface for generating files needed for
36
/// reproducing.
37
///
38
/// Different components will implement different providers.
39
class ProviderBase {
40
public:
41
120
  virtual ~ProviderBase() = default;
42
43
125
  const FileSpec &GetRoot() const { return m_root; }
44
45
  /// The Keep method is called when it is decided that we need to keep the
46
  /// data in order to provide a reproducer.
47
15
  virtual void Keep(){};
48
49
  /// The Discard method is called when it is decided that we do not need to
50
  /// keep any information and will not generate a reproducer.
51
27
  virtual void Discard(){};
52
53
  // Returns the class ID for this type.
54
0
  static const void *ClassID() { return &ID; }
55
56
  // Returns the class ID for the dynamic type of this Provider instance.
57
  virtual const void *DynamicClassID() const = 0;
58
59
  virtual llvm::StringRef GetName() const = 0;
60
  virtual llvm::StringRef GetFile() const = 0;
61
62
protected:
63
120
  ProviderBase(const FileSpec &root) : m_root(root) {}
64
65
private:
66
  /// Every provider knows where to dump its potential files.
67
  FileSpec m_root;
68
69
  virtual void anchor();
70
  static char ID;
71
};
72
73
template <typename ThisProviderT> class Provider : public ProviderBase {
74
public:
75
190
  static const void *ClassID() { return &ThisProviderT::ID; }
lldb_private::repro::Provider<lldb_private::repro::ProcessInfoProvider>::ClassID()
Line
Count
Source
75
1
  static const void *ClassID() { return &ThisProviderT::ID; }
lldb_private::repro::Provider<lldb_private::repro::VersionProvider>::ClassID()
Line
Count
Source
75
19
  static const void *ClassID() { return &ThisProviderT::ID; }
lldb_private::repro::Provider<lldb_private::repro::FileProvider>::ClassID()
Line
Count
Source
75
36
  static const void *ClassID() { return &ThisProviderT::ID; }
lldb_private::repro::Provider<lldb_private::repro::WorkingDirectoryProvider>::ClassID()
Line
Count
Source
75
43
  static const void *ClassID() { return &ThisProviderT::ID; }
lldb_private::repro::Provider<lldb_private::repro::HomeDirectoryProvider>::ClassID()
Line
Count
Source
75
43
  static const void *ClassID() { return &ThisProviderT::ID; }
lldb_private::repro::Provider<lldb_private::repro::CommandProvider>::ClassID()
Line
Count
Source
75
38
  static const void *ClassID() { return &ThisProviderT::ID; }
lldb_private::repro::Provider<lldb_private::repro::SymbolFileProvider>::ClassID()
Line
Count
Source
75
1
  static const void *ClassID() { return &ThisProviderT::ID; }
lldb_private::repro::Provider<lldb_private::repro::GDBRemoteProvider>::ClassID()
Line
Count
Source
75
9
  static const void *ClassID() { return &ThisProviderT::ID; }
76
77
116
  const void *DynamicClassID() const override { return &ThisProviderT::ID; }
lldb_private::repro::Provider<lldb_private::repro::FileProvider>::DynamicClassID() const
Line
Count
Source
77
19
  const void *DynamicClassID() const override { return &ThisProviderT::ID; }
lldb_private::repro::Provider<lldb_private::repro::VersionProvider>::DynamicClassID() const
Line
Count
Source
77
19
  const void *DynamicClassID() const override { return &ThisProviderT::ID; }
lldb_private::repro::Provider<lldb_private::repro::WorkingDirectoryProvider>::DynamicClassID() const
Line
Count
Source
77
24
  const void *DynamicClassID() const override { return &ThisProviderT::ID; }
lldb_private::repro::Provider<lldb_private::repro::HomeDirectoryProvider>::DynamicClassID() const
Line
Count
Source
77
24
  const void *DynamicClassID() const override { return &ThisProviderT::ID; }
lldb_private::repro::Provider<lldb_private::repro::SymbolFileProvider>::DynamicClassID() const
Line
Count
Source
77
1
  const void *DynamicClassID() const override { return &ThisProviderT::ID; }
lldb_private::repro::Provider<lldb_private::repro::CommandProvider>::DynamicClassID() const
Line
Count
Source
77
19
  const void *DynamicClassID() const override { return &ThisProviderT::ID; }
lldb_private::repro::Provider<lldb_private::repro::ProcessInfoProvider>::DynamicClassID() const
Line
Count
Source
77
1
  const void *DynamicClassID() const override { return &ThisProviderT::ID; }
lldb_private::repro::Provider<lldb_private::repro::GDBRemoteProvider>::DynamicClassID() const
Line
Count
Source
77
9
  const void *DynamicClassID() const override { return &ThisProviderT::ID; }
78
79
0
  llvm::StringRef GetName() const override { return ThisProviderT::Info::name; }
Unexecuted instantiation: lldb_private::repro::Provider<lldb_private::repro::FileProvider>::GetName() const
Unexecuted instantiation: lldb_private::repro::Provider<lldb_private::repro::VersionProvider>::GetName() const
Unexecuted instantiation: lldb_private::repro::Provider<lldb_private::repro::WorkingDirectoryProvider>::GetName() const
Unexecuted instantiation: lldb_private::repro::Provider<lldb_private::repro::HomeDirectoryProvider>::GetName() const
Unexecuted instantiation: lldb_private::repro::Provider<lldb_private::repro::SymbolFileProvider>::GetName() const
Unexecuted instantiation: lldb_private::repro::Provider<lldb_private::repro::CommandProvider>::GetName() const
Unexecuted instantiation: lldb_private::repro::Provider<lldb_private::repro::ProcessInfoProvider>::GetName() const
Unexecuted instantiation: lldb_private::repro::Provider<lldb_private::repro::GDBRemoteProvider>::GetName() const
80
87
  llvm::StringRef GetFile() const override { return ThisProviderT::Info::file; }
lldb_private::repro::Provider<lldb_private::repro::FileProvider>::GetFile() const
Line
Count
Source
80
15
  llvm::StringRef GetFile() const override { return ThisProviderT::Info::file; }
lldb_private::repro::Provider<lldb_private::repro::VersionProvider>::GetFile() const
Line
Count
Source
80
15
  llvm::StringRef GetFile() const override { return ThisProviderT::Info::file; }
lldb_private::repro::Provider<lldb_private::repro::WorkingDirectoryProvider>::GetFile() const
Line
Count
Source
80
16
  llvm::StringRef GetFile() const override { return ThisProviderT::Info::file; }
lldb_private::repro::Provider<lldb_private::repro::HomeDirectoryProvider>::GetFile() const
Line
Count
Source
80
16
  llvm::StringRef GetFile() const override { return ThisProviderT::Info::file; }
lldb_private::repro::Provider<lldb_private::repro::SymbolFileProvider>::GetFile() const
Line
Count
Source
80
1
  llvm::StringRef GetFile() const override { return ThisProviderT::Info::file; }
lldb_private::repro::Provider<lldb_private::repro::CommandProvider>::GetFile() const
Line
Count
Source
80
15
  llvm::StringRef GetFile() const override { return ThisProviderT::Info::file; }
lldb_private::repro::Provider<lldb_private::repro::ProcessInfoProvider>::GetFile() const
Line
Count
Source
80
1
  llvm::StringRef GetFile() const override { return ThisProviderT::Info::file; }
lldb_private::repro::Provider<lldb_private::repro::GDBRemoteProvider>::GetFile() const
Line
Count
Source
80
8
  llvm::StringRef GetFile() const override { return ThisProviderT::Info::file; }
81
82
protected:
83
  using ProviderBase::ProviderBase; // Inherit constructor.
84
};
85
86
/// The generator is responsible for the logic needed to generate a
87
/// reproducer. For doing so it relies on providers, who serialize data that
88
/// is necessary for reproducing  a failure.
89
class Generator final {
90
91
public:
92
  Generator(FileSpec root);
93
  ~Generator();
94
95
  /// Method to indicate we want to keep the reproducer. If reproducer
96
  /// generation is disabled, this does nothing.
97
  void Keep();
98
99
  /// Method to indicate we do not want to keep the reproducer. This is
100
  /// unaffected by whether or not generation reproduction is enabled, as we
101
  /// might need to clean up files already written to disk.
102
  void Discard();
103
104
  /// Enable or disable auto generate.
105
  void SetAutoGenerate(bool b);
106
107
  /// Return whether auto generate is enabled.
108
  bool IsAutoGenerate() const;
109
110
  /// Create and register a new provider.
111
116
  template <typename T> T *Create() {
112
116
    std::unique_ptr<ProviderBase> provider = std::make_unique<T>(m_root);
113
116
    return static_cast<T *>(Register(std::move(provider)));
114
116
  }
lldb_private::repro::ProcessInfoProvider* lldb_private::repro::Generator::Create<lldb_private::repro::ProcessInfoProvider>()
Line
Count
Source
111
1
  template <typename T> T *Create() {
112
1
    std::unique_ptr<ProviderBase> provider = std::make_unique<T>(m_root);
113
1
    return static_cast<T *>(Register(std::move(provider)));
114
1
  }
lldb_private::repro::VersionProvider* lldb_private::repro::Generator::Create<lldb_private::repro::VersionProvider>()
Line
Count
Source
111
19
  template <typename T> T *Create() {
112
19
    std::unique_ptr<ProviderBase> provider = std::make_unique<T>(m_root);
113
19
    return static_cast<T *>(Register(std::move(provider)));
114
19
  }
lldb_private::repro::FileProvider* lldb_private::repro::Generator::Create<lldb_private::repro::FileProvider>()
Line
Count
Source
111
19
  template <typename T> T *Create() {
112
19
    std::unique_ptr<ProviderBase> provider = std::make_unique<T>(m_root);
113
19
    return static_cast<T *>(Register(std::move(provider)));
114
19
  }
lldb_private::repro::WorkingDirectoryProvider* lldb_private::repro::Generator::Create<lldb_private::repro::WorkingDirectoryProvider>()
Line
Count
Source
111
24
  template <typename T> T *Create() {
112
24
    std::unique_ptr<ProviderBase> provider = std::make_unique<T>(m_root);
113
24
    return static_cast<T *>(Register(std::move(provider)));
114
24
  }
lldb_private::repro::HomeDirectoryProvider* lldb_private::repro::Generator::Create<lldb_private::repro::HomeDirectoryProvider>()
Line
Count
Source
111
24
  template <typename T> T *Create() {
112
24
    std::unique_ptr<ProviderBase> provider = std::make_unique<T>(m_root);
113
24
    return static_cast<T *>(Register(std::move(provider)));
114
24
  }
lldb_private::repro::CommandProvider* lldb_private::repro::Generator::Create<lldb_private::repro::CommandProvider>()
Line
Count
Source
111
19
  template <typename T> T *Create() {
112
19
    std::unique_ptr<ProviderBase> provider = std::make_unique<T>(m_root);
113
19
    return static_cast<T *>(Register(std::move(provider)));
114
19
  }
lldb_private::repro::SymbolFileProvider* lldb_private::repro::Generator::Create<lldb_private::repro::SymbolFileProvider>()
Line
Count
Source
111
1
  template <typename T> T *Create() {
112
1
    std::unique_ptr<ProviderBase> provider = std::make_unique<T>(m_root);
113
1
    return static_cast<T *>(Register(std::move(provider)));
114
1
  }
lldb_private::repro::GDBRemoteProvider* lldb_private::repro::Generator::Create<lldb_private::repro::GDBRemoteProvider>()
Line
Count
Source
111
9
  template <typename T> T *Create() {
112
9
    std::unique_ptr<ProviderBase> provider = std::make_unique<T>(m_root);
113
9
    return static_cast<T *>(Register(std::move(provider)));
114
9
  }
115
116
  /// Get an existing provider.
117
190
  template <typename T> T *Get() {
118
190
    auto it = m_providers.find(T::ClassID());
119
190
    if (it == m_providers.end())
120
116
      return nullptr;
121
74
    return static_cast<T *>(it->second.get());
122
190
  }
lldb_private::repro::ProcessInfoProvider* lldb_private::repro::Generator::Get<lldb_private::repro::ProcessInfoProvider>()
Line
Count
Source
117
1
  template <typename T> T *Get() {
118
1
    auto it = m_providers.find(T::ClassID());
119
1
    if (it == m_providers.end())
120
1
      return nullptr;
121
0
    return static_cast<T *>(it->second.get());
122
1
  }
lldb_private::repro::VersionProvider* lldb_private::repro::Generator::Get<lldb_private::repro::VersionProvider>()
Line
Count
Source
117
19
  template <typename T> T *Get() {
118
19
    auto it = m_providers.find(T::ClassID());
119
19
    if (it == m_providers.end())
120
19
      return nullptr;
121
0
    return static_cast<T *>(it->second.get());
122
19
  }
lldb_private::repro::FileProvider* lldb_private::repro::Generator::Get<lldb_private::repro::FileProvider>()
Line
Count
Source
117
36
  template <typename T> T *Get() {
118
36
    auto it = m_providers.find(T::ClassID());
119
36
    if (it == m_providers.end())
120
19
      return nullptr;
121
17
    return static_cast<T *>(it->second.get());
122
36
  }
lldb_private::repro::WorkingDirectoryProvider* lldb_private::repro::Generator::Get<lldb_private::repro::WorkingDirectoryProvider>()
Line
Count
Source
117
43
  template <typename T> T *Get() {
118
43
    auto it = m_providers.find(T::ClassID());
119
43
    if (it == m_providers.end())
120
24
      return nullptr;
121
19
    return static_cast<T *>(it->second.get());
122
43
  }
lldb_private::repro::HomeDirectoryProvider* lldb_private::repro::Generator::Get<lldb_private::repro::HomeDirectoryProvider>()
Line
Count
Source
117
43
  template <typename T> T *Get() {
118
43
    auto it = m_providers.find(T::ClassID());
119
43
    if (it == m_providers.end())
120
24
      return nullptr;
121
19
    return static_cast<T *>(it->second.get());
122
43
  }
lldb_private::repro::CommandProvider* lldb_private::repro::Generator::Get<lldb_private::repro::CommandProvider>()
Line
Count
Source
117
38
  template <typename T> T *Get() {
118
38
    auto it = m_providers.find(T::ClassID());
119
38
    if (it == m_providers.end())
120
19
      return nullptr;
121
19
    return static_cast<T *>(it->second.get());
122
38
  }
lldb_private::repro::SymbolFileProvider* lldb_private::repro::Generator::Get<lldb_private::repro::SymbolFileProvider>()
Line
Count
Source
117
1
  template <typename T> T *Get() {
118
1
    auto it = m_providers.find(T::ClassID());
119
1
    if (it == m_providers.end())
120
1
      return nullptr;
121
0
    return static_cast<T *>(it->second.get());
122
1
  }
lldb_private::repro::GDBRemoteProvider* lldb_private::repro::Generator::Get<lldb_private::repro::GDBRemoteProvider>()
Line
Count
Source
117
9
  template <typename T> T *Get() {
118
9
    auto it = m_providers.find(T::ClassID());
119
9
    if (it == m_providers.end())
120
9
      return nullptr;
121
0
    return static_cast<T *>(it->second.get());
122
9
  }
123
124
  /// Get a provider if it exists, otherwise create it.
125
190
  template <typename T> T &GetOrCreate() {
126
190
    auto *provider = Get<T>();
127
190
    if (provider)
128
74
      return *provider;
129
116
    return *Create<T>();
130
190
  }
lldb_private::repro::ProcessInfoProvider& lldb_private::repro::Generator::GetOrCreate<lldb_private::repro::ProcessInfoProvider>()
Line
Count
Source
125
1
  template <typename T> T &GetOrCreate() {
126
1
    auto *provider = Get<T>();
127
1
    if (provider)
128
0
      return *provider;
129
1
    return *Create<T>();
130
1
  }
lldb_private::repro::VersionProvider& lldb_private::repro::Generator::GetOrCreate<lldb_private::repro::VersionProvider>()
Line
Count
Source
125
19
  template <typename T> T &GetOrCreate() {
126
19
    auto *provider = Get<T>();
127
19
    if (provider)
128
0
      return *provider;
129
19
    return *Create<T>();
130
19
  }
lldb_private::repro::FileProvider& lldb_private::repro::Generator::GetOrCreate<lldb_private::repro::FileProvider>()
Line
Count
Source
125
36
  template <typename T> T &GetOrCreate() {
126
36
    auto *provider = Get<T>();
127
36
    if (provider)
128
17
      return *provider;
129
19
    return *Create<T>();
130
36
  }
lldb_private::repro::WorkingDirectoryProvider& lldb_private::repro::Generator::GetOrCreate<lldb_private::repro::WorkingDirectoryProvider>()
Line
Count
Source
125
43
  template <typename T> T &GetOrCreate() {
126
43
    auto *provider = Get<T>();
127
43
    if (provider)
128
19
      return *provider;
129
24
    return *Create<T>();
130
43
  }
lldb_private::repro::HomeDirectoryProvider& lldb_private::repro::Generator::GetOrCreate<lldb_private::repro::HomeDirectoryProvider>()
Line
Count
Source
125
43
  template <typename T> T &GetOrCreate() {
126
43
    auto *provider = Get<T>();
127
43
    if (provider)
128
19
      return *provider;
129
24
    return *Create<T>();
130
43
  }
lldb_private::repro::CommandProvider& lldb_private::repro::Generator::GetOrCreate<lldb_private::repro::CommandProvider>()
Line
Count
Source
125
38
  template <typename T> T &GetOrCreate() {
126
38
    auto *provider = Get<T>();
127
38
    if (provider)
128
19
      return *provider;
129
19
    return *Create<T>();
130
38
  }
lldb_private::repro::SymbolFileProvider& lldb_private::repro::Generator::GetOrCreate<lldb_private::repro::SymbolFileProvider>()
Line
Count
Source
125
1
  template <typename T> T &GetOrCreate() {
126
1
    auto *provider = Get<T>();
127
1
    if (provider)
128
0
      return *provider;
129
1
    return *Create<T>();
130
1
  }
lldb_private::repro::GDBRemoteProvider& lldb_private::repro::Generator::GetOrCreate<lldb_private::repro::GDBRemoteProvider>()
Line
Count
Source
125
9
  template <typename T> T &GetOrCreate() {
126
9
    auto *provider = Get<T>();
127
9
    if (provider)
128
0
      return *provider;
129
9
    return *Create<T>();
130
9
  }
131
132
  const FileSpec &GetRoot() const;
133
134
private:
135
  friend Reproducer;
136
137
  ProviderBase *Register(std::unique_ptr<ProviderBase> provider);
138
139
  /// Builds and index with provider info.
140
  void AddProvidersToIndex();
141
142
  /// Map of provider IDs to provider instances.
143
  llvm::DenseMap<const void *, std::unique_ptr<ProviderBase>> m_providers;
144
  std::mutex m_providers_mutex;
145
146
  /// The reproducer root directory.
147
  FileSpec m_root;
148
149
  /// Flag to ensure that we never call both keep and discard.
150
  bool m_done = false;
151
152
  /// Flag to auto generate a reproducer when it would otherwise be discarded.
153
  bool m_auto_generate = false;
154
};
155
156
class Loader final {
157
public:
158
  Loader(FileSpec root, bool passive = false);
159
160
23
  template <typename T> FileSpec GetFile() {
161
23
    if (!HasFile(T::file))
162
2
      return {};
163
164
21
    return GetRoot().CopyByAppendingPathComponent(T::file);
165
23
  }
lldb_private::FileSpec lldb_private::repro::Loader::GetFile<lldb_private::repro::FileProvider::Info>()
Line
Count
Source
160
6
  template <typename T> FileSpec GetFile() {
161
6
    if (!HasFile(T::file))
162
0
      return {};
163
164
6
    return GetRoot().CopyByAppendingPathComponent(T::file);
165
6
  }
lldb_private::FileSpec lldb_private::repro::Loader::GetFile<lldb_private::repro::WorkingDirectoryProvider::Info>()
Line
Count
Source
160
3
  template <typename T> FileSpec GetFile() {
161
3
    if (!HasFile(T::file))
162
0
      return {};
163
164
3
    return GetRoot().CopyByAppendingPathComponent(T::file);
165
3
  }
lldb_private::FileSpec lldb_private::repro::Loader::GetFile<lldb_private::repro::HomeDirectoryProvider::Info>()
Line
Count
Source
160
4
  template <typename T> FileSpec GetFile() {
161
4
    if (!HasFile(T::file))
162
0
      return {};
163
164
4
    return GetRoot().CopyByAppendingPathComponent(T::file);
165
4
  }
lldb_private::FileSpec lldb_private::repro::Loader::GetFile<lldb_private::repro::CommandProvider::Info>()
Line
Count
Source
160
2
  template <typename T> FileSpec GetFile() {
161
2
    if (!HasFile(T::file))
162
0
      return {};
163
164
2
    return GetRoot().CopyByAppendingPathComponent(T::file);
165
2
  }
lldb_private::FileSpec lldb_private::repro::Loader::GetFile<lldb_private::repro::VersionProvider::Info>()
Line
Count
Source
160
1
  template <typename T> FileSpec GetFile() {
161
1
    if (!HasFile(T::file))
162
0
      return {};
163
164
1
    return GetRoot().CopyByAppendingPathComponent(T::file);
165
1
  }
lldb_private::FileSpec lldb_private::repro::Loader::GetFile<lldb_private::repro::GDBRemoteProvider::Info>()
Line
Count
Source
160
2
  template <typename T> FileSpec GetFile() {
161
2
    if (!HasFile(T::file))
162
0
      return {};
163
164
2
    return GetRoot().CopyByAppendingPathComponent(T::file);
165
2
  }
lldb_private::FileSpec lldb_private::repro::Loader::GetFile<lldb_private::repro::ProcessInfoProvider::Info>()
Line
Count
Source
160
1
  template <typename T> FileSpec GetFile() {
161
1
    if (!HasFile(T::file))
162
0
      return {};
163
164
1
    return GetRoot().CopyByAppendingPathComponent(T::file);
165
1
  }
lldb_private::FileSpec lldb_private::repro::Loader::GetFile<lldb_private::repro::SymbolFileProvider::Info>()
Line
Count
Source
160
4
  template <typename T> FileSpec GetFile() {
161
4
    if (!HasFile(T::file))
162
2
      return {};
163
164
2
    return GetRoot().CopyByAppendingPathComponent(T::file);
165
4
  }
166
167
12
  template <typename T> llvm::Expected<std::string> LoadBuffer() {
168
12
    FileSpec file = GetFile<typename T::Info>();
169
12
    llvm::ErrorOr<std::unique_ptr<llvm::MemoryBuffer>> buffer =
170
12
        llvm::vfs::getRealFileSystem()->getBufferForFile(file.GetPath());
171
12
    if (!buffer)
172
2
      return llvm::errorCodeToError(buffer.getError());
173
10
    return (*buffer)->getBuffer().str();
174
12
  }
llvm::Expected<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > > lldb_private::repro::Loader::LoadBuffer<lldb_private::repro::WorkingDirectoryProvider>()
Line
Count
Source
167
3
  template <typename T> llvm::Expected<std::string> LoadBuffer() {
168
3
    FileSpec file = GetFile<typename T::Info>();
169
3
    llvm::ErrorOr<std::unique_ptr<llvm::MemoryBuffer>> buffer =
170
3
        llvm::vfs::getRealFileSystem()->getBufferForFile(file.GetPath());
171
3
    if (!buffer)
172
0
      return llvm::errorCodeToError(buffer.getError());
173
3
    return (*buffer)->getBuffer().str();
174
3
  }
llvm::Expected<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > > lldb_private::repro::Loader::LoadBuffer<lldb_private::repro::HomeDirectoryProvider>()
Line
Count
Source
167
4
  template <typename T> llvm::Expected<std::string> LoadBuffer() {
168
4
    FileSpec file = GetFile<typename T::Info>();
169
4
    llvm::ErrorOr<std::unique_ptr<llvm::MemoryBuffer>> buffer =
170
4
        llvm::vfs::getRealFileSystem()->getBufferForFile(file.GetPath());
171
4
    if (!buffer)
172
0
      return llvm::errorCodeToError(buffer.getError());
173
4
    return (*buffer)->getBuffer().str();
174
4
  }
llvm::Expected<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > > lldb_private::repro::Loader::LoadBuffer<lldb_private::repro::VersionProvider>()
Line
Count
Source
167
1
  template <typename T> llvm::Expected<std::string> LoadBuffer() {
168
1
    FileSpec file = GetFile<typename T::Info>();
169
1
    llvm::ErrorOr<std::unique_ptr<llvm::MemoryBuffer>> buffer =
170
1
        llvm::vfs::getRealFileSystem()->getBufferForFile(file.GetPath());
171
1
    if (!buffer)
172
0
      return llvm::errorCodeToError(buffer.getError());
173
1
    return (*buffer)->getBuffer().str();
174
1
  }
llvm::Expected<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > > lldb_private::repro::Loader::LoadBuffer<lldb_private::repro::SymbolFileProvider>()
Line
Count
Source
167
4
  template <typename T> llvm::Expected<std::string> LoadBuffer() {
168
4
    FileSpec file = GetFile<typename T::Info>();
169
4
    llvm::ErrorOr<std::unique_ptr<llvm::MemoryBuffer>> buffer =
170
4
        llvm::vfs::getRealFileSystem()->getBufferForFile(file.GetPath());
171
4
    if (!buffer)
172
2
      return llvm::errorCodeToError(buffer.getError());
173
2
    return (*buffer)->getBuffer().str();
174
4
  }
175
176
  llvm::Error LoadIndex();
177
178
40
  const FileSpec &GetRoot() const { return m_root; }
179
180
private:
181
  bool HasFile(llvm::StringRef file);
182
183
  FileSpec m_root;
184
  std::vector<std::string> m_files;
185
  bool m_loaded;
186
};
187
188
/// The reproducer enables clients to obtain access to the Generator and
189
/// Loader.
190
class Reproducer {
191
public:
192
  static Reproducer &Instance();
193
  static llvm::Error Initialize(ReproducerMode mode,
194
                                llvm::Optional<FileSpec> root);
195
  static void Initialize();
196
  static bool Initialized();
197
  static void Terminate();
198
199
3.46k
  Reproducer() = default;
200
201
  Generator *GetGenerator();
202
  Loader *GetLoader();
203
204
  const Generator *GetGenerator() const;
205
  const Loader *GetLoader() const;
206
207
  FileSpec GetReproducerPath() const;
208
209
11
  bool IsCapturing() { return static_cast<bool>(m_generator); };
210
211
protected:
212
  llvm::Error SetCapture(llvm::Optional<FileSpec> root);
213
214
private:
215
  static llvm::Optional<Reproducer> &InstanceImpl();
216
217
  llvm::Optional<Generator> m_generator;
218
  llvm::Optional<Loader> m_loader;
219
220
  mutable std::mutex m_mutex;
221
};
222
223
class Verifier {
224
public:
225
3
  Verifier(Loader *loader) : m_loader(loader) {}
226
  void Verify(llvm::function_ref<void(llvm::StringRef)> error_callback,
227
              llvm::function_ref<void(llvm::StringRef)> warning_callback,
228
              llvm::function_ref<void(llvm::StringRef)> note_callback) const;
229
230
private:
231
  Loader *m_loader;
232
};
233
234
struct ReplayOptions {
235
  bool verify = true;
236
  bool check_version = true;
237
};
238
239
llvm::Error Finalize(Loader *loader);
240
llvm::Error Finalize(const FileSpec &root);
241
242
} // namespace repro
243
} // namespace lldb_private
244
245
#endif // LLDB_UTILITY_REPRODUCER_H