1 change: 1 addition & 0 deletions lldb/source/Commands/CommandObjectType.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
#include "lldb/Core/Debugger.h"
#include "lldb/Core/IOHandler.h"
#include "lldb/DataFormatters/DataVisualization.h"
#include "lldb/Host/Config.h"
#include "lldb/Host/OptionParser.h"
#include "lldb/Interpreter/CommandInterpreter.h"
#include "lldb/Interpreter/CommandObject.h"
Expand Down
1 change: 1 addition & 0 deletions lldb/source/Core/IOHandlerCursesGUI.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
//===----------------------------------------------------------------------===//

#include "lldb/Core/IOHandlerCursesGUI.h"
#include "lldb/Host/Config.h"

#ifndef LLDB_DISABLE_CURSES
#include <curses.h>
Expand Down
1 change: 1 addition & 0 deletions lldb/source/Core/ValueObject.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
#include "lldb/DataFormatters/TypeValidator.h"
#include "lldb/DataFormatters/ValueObjectPrinter.h"
#include "lldb/Expression/ExpressionVariable.h"
#include "lldb/Host/Config.h"
#include "lldb/Symbol/ClangASTContext.h"
#include "lldb/Symbol/CompileUnit.h"
#include "lldb/Symbol/CompilerType.h"
Expand Down
5 changes: 3 additions & 2 deletions lldb/source/Interpreter/CommandInterpreter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@
#include "lldb/Utility/Stream.h"
#include "lldb/Utility/Timer.h"

#include "lldb/Host/Config.h"
#ifndef LLDB_DISABLE_LIBEDIT
#include "lldb/Host/Editline.h"
#endif
Expand Down Expand Up @@ -362,8 +363,8 @@ void CommandInterpreter::Initialize() {
"controlled by the type's author.");
po->SetHelpLong("");
}
CommandAlias *parray_alias = AddAlias("parray", cmd_obj_sp,
"--element-count %1 --");
CommandAlias *parray_alias =
AddAlias("parray", cmd_obj_sp, "--element-count %1 --");
if (parray_alias) {
parray_alias->SetHelp
("parray <COUNT> <EXPRESSION> -- lldb will evaluate EXPRESSION "
Expand Down
5 changes: 1 addition & 4 deletions lldb/source/Interpreter/CommandObjectScript.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -7,12 +7,9 @@
//===----------------------------------------------------------------------===//

#include "CommandObjectScript.h"


#include "lldb/Core/Debugger.h"

#include "lldb/DataFormatters/DataVisualization.h"

#include "lldb/Host/Config.h"
#include "lldb/Interpreter/CommandInterpreter.h"
#include "lldb/Interpreter/CommandReturnObject.h"
#include "lldb/Interpreter/ScriptInterpreter.h"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@
//
//===----------------------------------------------------------------------===//

#include "lldb/Host/Config.h"

#ifndef LLDB_DISABLE_PYTHON

#include "OperatingSystemPython.h"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@
#ifndef liblldb_OperatingSystemPython_h_
#define liblldb_OperatingSystemPython_h_

#include "lldb/Host/Config.h"

#ifndef LLDB_DISABLE_PYTHON

#include "lldb/Target/OperatingSystem.h"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@
#include "lldb/Utility/FileSpec.h"
#include "lldb/Utility/Log.h"
#include "lldb/Utility/RegularExpression.h"
#include "lldb/Utility/Reproducer.h"
#include "lldb/Utility/StreamString.h"
#include "llvm/ADT/SmallString.h"
#include "llvm/Support/ScopedPrinter.h"
Expand Down Expand Up @@ -1243,8 +1244,9 @@ Status GDBRemoteCommunication::StartDebugserverProcess(

void GDBRemoteCommunication::DumpHistory(Stream &strm) { m_history.Dump(strm); }

void GDBRemoteCommunication::SetHistoryStream(llvm::raw_ostream *strm) {
m_history.SetStream(strm);
void GDBRemoteCommunication::SetPacketRecorder(
repro::PacketRecorder *recorder) {
m_history.SetRecorder(recorder);
}

llvm::Error
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,9 @@
#include "lldb/lldb-public.h"

namespace lldb_private {
namespace repro {
class PacketRecorder;
}
namespace process_gdb_remote {

enum GDBStoppointType {
Expand Down Expand Up @@ -133,7 +136,8 @@ class GDBRemoteCommunication : public Communication {
// fork/exec to avoid having to connect/accept

void DumpHistory(Stream &strm);
void SetHistoryStream(llvm::raw_ostream *strm);

void SetPacketRecorder(repro::PacketRecorder *recorder);

static llvm::Error ConnectLocally(GDBRemoteCommunication &client,
GDBRemoteCommunication &server);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -40,8 +40,8 @@ void GDBRemoteCommunicationHistory::AddPacket(char packet_char,
m_packets[idx].bytes_transmitted = bytes_transmitted;
m_packets[idx].packet_idx = m_total_packet_count;
m_packets[idx].tid = llvm::get_threadid();
if (m_stream)
m_packets[idx].Serialize(*m_stream);
if (m_recorder)
m_recorder->Record(m_packets[idx]);
}

void GDBRemoteCommunicationHistory::AddPacket(const std::string &src,
Expand All @@ -58,8 +58,8 @@ void GDBRemoteCommunicationHistory::AddPacket(const std::string &src,
m_packets[idx].bytes_transmitted = bytes_transmitted;
m_packets[idx].packet_idx = m_total_packet_count;
m_packets[idx].tid = llvm::get_threadid();
if (m_stream)
m_packets[idx].Serialize(*m_stream);
if (m_recorder)
m_recorder->Record(m_packets[idx]);
}

void GDBRemoteCommunicationHistory::Dump(Stream &strm) const {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,11 +13,15 @@
#include <vector>

#include "lldb/Utility/GDBRemote.h"
#include "lldb/Utility/Reproducer.h"
#include "lldb/lldb-public.h"
#include "llvm/Support/YAMLTraits.h"
#include "llvm/Support/raw_ostream.h"

namespace lldb_private {
namespace repro {
class PacketRecorder;
}
namespace process_gdb_remote {

/// The history keeps a circular buffer of GDB remote packets. The history is
Expand All @@ -41,7 +45,7 @@ class GDBRemoteCommunicationHistory {
void Dump(Log *log) const;
bool DidDumpToLog() const { return m_dumped_to_log; }

void SetStream(llvm::raw_ostream *strm) { m_stream = strm; }
void SetRecorder(repro::PacketRecorder *recorder) { m_recorder = recorder; }

private:
uint32_t GetFirstSavedPacketIndex() const {
Expand Down Expand Up @@ -73,7 +77,7 @@ class GDBRemoteCommunicationHistory {
uint32_t m_curr_idx;
uint32_t m_total_packet_count;
mutable bool m_dumped_to_log;
llvm::raw_ostream *m_stream = nullptr;
repro::PacketRecorder *m_recorder = nullptr;
};

} // namespace process_gdb_remote
Expand Down
31 changes: 17 additions & 14 deletions lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -279,12 +279,9 @@ ProcessGDBRemote::ProcessGDBRemote(lldb::TargetSP target_sp,
"async thread did exit");

if (repro::Generator *g = repro::Reproducer::Instance().GetGenerator()) {
repro::ProcessGDBRemoteProvider &provider =
g->GetOrCreate<repro::ProcessGDBRemoteProvider>();
// Set the history stream to the stream owned by the provider.
m_gdb_comm.SetHistoryStream(provider.GetHistoryStream());
// Make sure to clear the stream again when we're finished.
provider.SetCallback([&]() { m_gdb_comm.SetHistoryStream(nullptr); });
repro::GDBRemoteProvider &provider =
g->GetOrCreate<repro::GDBRemoteProvider>();
m_gdb_comm.SetPacketRecorder(provider.GetNewPacketRecorder());
}

Log *log(ProcessGDBRemoteLog::GetLogIfAllCategoriesSet(GDBR_LOG_ASYNC));
Expand Down Expand Up @@ -3362,24 +3359,30 @@ Status ProcessGDBRemote::ConnectToReplayServer(repro::Loader *loader) {
if (!loader)
return Status("No loader provided.");

// Construct replay history path.
FileSpec history_file =
loader->GetFile<repro::ProcessGDBRemoteProvider::Info>();
if (!history_file)
return Status("No provider for gdb-remote.");
static std::unique_ptr<repro::MultiLoader<repro::GDBRemoteProvider>>
multi_loader = repro::MultiLoader<repro::GDBRemoteProvider>::Create(
repro::Reproducer::Instance().GetLoader());

// Enable replay mode.
m_replay_mode = true;
if (!multi_loader)
return Status("No gdb remote provider found.");

llvm::Optional<std::string> history_file = multi_loader->GetNextFile();
if (!history_file)
return Status("No gdb remote packet log found.");

// Load replay history.
if (auto error = m_gdb_replay_server.LoadReplayHistory(history_file))
if (auto error =
m_gdb_replay_server.LoadReplayHistory(FileSpec(*history_file)))
return Status("Unable to load replay history");

// Make a local connection.
if (auto error = GDBRemoteCommunication::ConnectLocally(m_gdb_comm,
m_gdb_replay_server))
return Status("Unable to connect to replay server");

// Enable replay mode.
m_replay_mode = true;

// Start server thread.
m_gdb_replay_server.StartAsyncThread();

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,9 @@
//
//===----------------------------------------------------------------------===//

#ifdef LLDB_DISABLE_PYTHON
#include "lldb/Host/Config.h"

// Python is disabled in this build

#else
#ifndef LLDB_DISABLE_PYTHON

#include "PythonDataObjects.h"
#include "ScriptInterpreterPython.h"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,8 @@
#ifndef LLDB_PLUGINS_SCRIPTINTERPRETER_PYTHON_PYTHONDATAOBJECTS_H
#define LLDB_PLUGINS_SCRIPTINTERPRETER_PYTHON_PYTHONDATAOBJECTS_H

#include "lldb/Host/Config.h"

#ifndef LLDB_DISABLE_PYTHON

// LLDB Python header must be included first
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,9 @@
//
//===----------------------------------------------------------------------===//

#ifdef LLDB_DISABLE_PYTHON
#include "lldb/Host/Config.h"

// Python is disabled in this build

#else
#ifndef LLDB_DISABLE_PYTHON

// LLDB Python header must be included first
#include "lldb-python.h"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@
#ifndef LLDB_PLUGINS_SCRIPTINTERPRETER_PYTHON_SCRIPTINTERPRETERPYTHON_H
#define LLDB_PLUGINS_SCRIPTINTERPRETER_PYTHON_SCRIPTINTERPRETERPYTHON_H

#include "lldb/Host/Config.h"

#ifdef LLDB_DISABLE_PYTHON

// Python is disabled in this build
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,9 @@
//
//===----------------------------------------------------------------------===//

#ifdef LLDB_DISABLE_PYTHON
#include "lldb/Host/Config.h"

// Python is disabled in this build

#else
#ifndef LLDB_DISABLE_PYTHON

#include "lldb-python.h"

Expand Down
2 changes: 2 additions & 0 deletions lldb/source/Plugins/ScriptInterpreter/Python/lldb-python.h
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@
#ifndef LLDB_PLUGINS_SCRIPTINTERPRETER_PYTHON_LLDB_PYTHON_H
#define LLDB_PLUGINS_SCRIPTINTERPRETER_PYTHON_LLDB_PYTHON_H

#include "lldb/Host/Config.h"

// Python.h needs to be included before any system headers in order to avoid
// redefinition of macros

Expand Down
70 changes: 64 additions & 6 deletions lldb/source/Utility/GDBRemote.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
#include <stdio.h>

using namespace lldb;
using namespace lldb_private::repro;
using namespace lldb_private;
using namespace llvm;

Expand Down Expand Up @@ -45,12 +46,6 @@ int StreamGDBRemote::PutEscapedBytes(const void *s, size_t src_len) {
return bytes_written;
}

void GDBRemotePacket::Serialize(raw_ostream &strm) const {
yaml::Output yout(strm);
yout << const_cast<GDBRemotePacket &>(*this);
strm.flush();
}

llvm::StringRef GDBRemotePacket::GetTypeStr() const {
switch (type) {
case GDBRemotePacket::ePacketTypeSend:
Expand Down Expand Up @@ -103,3 +98,66 @@ yaml::MappingTraits<GDBRemotePacket>::validate(IO &io,

return {};
}

void GDBRemoteProvider::Keep() {
std::vector<std::string> files;
for (auto &recorder : m_packet_recorders) {
files.push_back(recorder->GetFilename().GetPath());
}

FileSpec file = GetRoot().CopyByAppendingPathComponent(Info::file);
std::error_code ec;
llvm::raw_fd_ostream os(file.GetPath(), ec, llvm::sys::fs::OF_Text);
if (ec)
return;
yaml::Output yout(os);
yout << files;
}

void GDBRemoteProvider::Discard() { m_packet_recorders.clear(); }

llvm::Expected<std::unique_ptr<PacketRecorder>>
PacketRecorder::Create(const FileSpec &filename) {
std::error_code ec;
auto recorder = std::make_unique<PacketRecorder>(std::move(filename), ec);
if (ec)
return llvm::errorCodeToError(ec);
return std::move(recorder);
}

PacketRecorder *GDBRemoteProvider::GetNewPacketRecorder() {
std::size_t i = m_packet_recorders.size() + 1;
std::string filename = (llvm::Twine(Info::name) + llvm::Twine("-") +
llvm::Twine(i) + llvm::Twine(".yaml"))
.str();
auto recorder_or_error =
PacketRecorder::Create(GetRoot().CopyByAppendingPathComponent(filename));
if (!recorder_or_error) {
llvm::consumeError(recorder_or_error.takeError());
return nullptr;
}

m_packet_recorders.push_back(std::move(*recorder_or_error));
return m_packet_recorders.back().get();
}

void PacketRecorder::Record(const GDBRemotePacket &packet) {
if (!m_record)
return;
yaml::Output yout(m_os);
yout << const_cast<GDBRemotePacket &>(packet);
m_os.flush();
}

llvm::raw_ostream *GDBRemoteProvider::GetHistoryStream() {
FileSpec history_file = GetRoot().CopyByAppendingPathComponent(Info::file);

std::error_code EC;
m_stream_up = std::make_unique<raw_fd_ostream>(history_file.GetPath(), EC,
sys::fs::OpenFlags::OF_Text);
return m_stream_up.get();
}

char GDBRemoteProvider::ID = 0;
const char *GDBRemoteProvider::Info::file = "gdb-remote.yaml";
const char *GDBRemoteProvider::Info::name = "gdb-remote";
48 changes: 1 addition & 47 deletions lldb/source/Utility/Reproducer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -255,7 +255,7 @@ DataRecorder::Create(const FileSpec &filename) {
DataRecorder *CommandProvider::GetNewDataRecorder() {
std::size_t i = m_data_recorders.size() + 1;
std::string filename = (llvm::Twine(Info::name) + llvm::Twine("-") +
llvm::Twine(i) + llvm::Twine(".txt"))
llvm::Twine(i) + llvm::Twine(".yaml"))
.str();
auto recorder_or_error =
DataRecorder::Create(GetRoot().CopyByAppendingPathComponent(filename));
Expand Down Expand Up @@ -304,62 +304,16 @@ void WorkingDirectoryProvider::Keep() {
os << m_cwd << "\n";
}

llvm::raw_ostream *ProcessGDBRemoteProvider::GetHistoryStream() {
FileSpec history_file = GetRoot().CopyByAppendingPathComponent(Info::file);

std::error_code EC;
m_stream_up = std::make_unique<raw_fd_ostream>(history_file.GetPath(), EC,
sys::fs::OpenFlags::OF_Text);
return m_stream_up.get();
}

std::unique_ptr<CommandLoader> CommandLoader::Create(Loader *loader) {
if (!loader)
return {};

FileSpec file = loader->GetFile<repro::CommandProvider::Info>();
if (!file)
return {};

auto error_or_file = llvm::MemoryBuffer::getFile(file.GetPath());
if (auto err = error_or_file.getError())
return {};

std::vector<std::string> files;
llvm::yaml::Input yin((*error_or_file)->getBuffer());
yin >> files;

if (auto err = yin.error())
return {};

for (auto &file : files) {
FileSpec absolute_path =
loader->GetRoot().CopyByAppendingPathComponent(file);
file = absolute_path.GetPath();
}

return std::make_unique<CommandLoader>(std::move(files));
}

llvm::Optional<std::string> CommandLoader::GetNextFile() {
if (m_index >= m_files.size())
return {};
return m_files[m_index++];
}

void ProviderBase::anchor() {}
char CommandProvider::ID = 0;
char FileProvider::ID = 0;
char ProcessGDBRemoteProvider::ID = 0;
char ProviderBase::ID = 0;
char VersionProvider::ID = 0;
char WorkingDirectoryProvider::ID = 0;
const char *CommandProvider::Info::file = "command-interpreter.yaml";
const char *CommandProvider::Info::name = "command-interpreter";
const char *FileProvider::Info::file = "files.yaml";
const char *FileProvider::Info::name = "files";
const char *ProcessGDBRemoteProvider::Info::file = "gdb-remote.yaml";
const char *ProcessGDBRemoteProvider::Info::name = "gdb-remote";
const char *VersionProvider::Info::file = "version.txt";
const char *VersionProvider::Info::name = "version";
const char *WorkingDirectoryProvider::Info::file = "cwd.txt";
Expand Down
12 changes: 12 additions & 0 deletions lldb/test/Shell/Reproducer/Inputs/MultipleTargetsCapture.in
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
target select 0
breakpoint set -f simple.c -l 12
run
target select 1
breakpoint set -f simple.c -l 16
run
target select 0
cont
target select 1
cont
reproducer status
reproducer generate
23 changes: 23 additions & 0 deletions lldb/test/Shell/Reproducer/TestMultipleTargets.test
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
# UNSUPPORTED: system-windows, system-freebsd

# This tests the replaying with multiple targets.

# RUN: %clang_host %S/Inputs/simple.c -g -o %t.out

# RUN: rm -rf %t.repro
# RUN: %lldb -x -b --capture --capture-path %t.repro -o 'target create %t.out' -o 'target create %t.out' -s %S/Inputs/MultipleTargetsCapture.in | FileCheck %s --check-prefix CHECK --check-prefix CAPTURE
# RUN: env FOO=BAR %lldb --replay %t.repro | FileCheck %s --check-prefix CHECK --check-prefix REPLAY

# CHECK: Process [[TARGET0:[0-9]+]] stopped
# CHECK: stop reason = breakpoint 1.1
# CHECK: simple.c:12:5
# CHECK: Process [[TARGET1:[0-9]+]] stopped
# CHECK: stop reason = breakpoint 1.1
# CHECK: simple.c:16:5
# CHECK: Process [[TARGET0]] resuming
# CHECK: Process [[TARGET0]] exited
# CHECK: Process [[TARGET1]] resuming
# CHECK: Process [[TARGET1]] exited

# CAPTURE: Reproducer is in capture mode.
# CAPTURE: Reproducer written
2 changes: 2 additions & 0 deletions lldb/unittests/Editline/EditlineTest.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@
//
//===----------------------------------------------------------------------===//

#include "lldb/Host/Config.h"

#ifndef LLDB_DISABLE_LIBEDIT

#define EDITLINE_TEST_DUMP_OUTPUT 0
Expand Down