Skip to content
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion lldb/tools/lldb-dap/DAP.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ const char DEV_NULL[] = "/dev/null";

namespace lldb_dap {

DAP::DAP(llvm::StringRef path, std::ofstream *log,
DAP::DAP(llvm::StringRef path, Log *log,
const ReplMode default_repl_mode,
std::vector<std::string> pre_init_commands, Transport &transport)
: debug_adapter_path(path), log(log), transport(transport),
Expand Down
6 changes: 3 additions & 3 deletions lldb/tools/lldb-dap/DAP.h
Original file line number Diff line number Diff line change
Expand Up @@ -144,7 +144,7 @@ struct SendEventRequestHandler : public lldb::SBCommandPluginInterface {

struct DAP {
llvm::StringRef debug_adapter_path;
std::ofstream *log;
Log *log;
Transport &transport;
lldb::SBFile in;
OutputRedirector out;
Expand Down Expand Up @@ -211,14 +211,14 @@ struct DAP {
/// \param[in] path
/// Path to the lldb-dap binary.
/// \param[in] log
/// Log file stream, if configured.
/// Log stream, if configured.
/// \param[in] default_repl_mode
/// Default repl mode behavior, as configured by the binary.
/// \param[in] pre_init_commands
/// LLDB commands to execute as soon as the debugger instance is allocaed.
/// \param[in] transport
/// Transport for this debug session.
DAP(llvm::StringRef path, std::ofstream *log,
DAP(llvm::StringRef path, Log *log,
const ReplMode default_repl_mode,
std::vector<std::string> pre_init_commands, Transport &transport);

Expand Down
38 changes: 30 additions & 8 deletions lldb/tools/lldb-dap/DAPLog.h
Original file line number Diff line number Diff line change
Expand Up @@ -9,44 +9,66 @@
#ifndef LLDB_TOOLS_LLDB_DAP_DAPLOG_H
#define LLDB_TOOLS_LLDB_DAP_DAPLOG_H

#include "llvm/ADT/StringRef.h"
#include "llvm/Support/Error.h"
#include "llvm/Support/FormatAdapters.h"
#include "llvm/Support/FormatVariadic.h"
#include <chrono>
#include <fstream>
#include <mutex>
#include <string>

// Write a message to log, if logging is enabled.
#define DAP_LOG(log, ...) \
do { \
::std::ofstream *log_private = (log); \
::lldb_dap::Log *log_private = (log); \
if (log_private) { \
::std::chrono::duration<double> now{ \
::std::chrono::system_clock::now().time_since_epoch()}; \
*log_private << ::llvm::formatv("{0:f9} ", now.count()).str() \
<< ::llvm::formatv(__VA_ARGS__).str() << std::endl; \
::std::string out; \
::llvm::raw_string_ostream os(out); \
os << ::llvm::formatv("{0:f9} ", now.count()).str() \
<< ::llvm::formatv(__VA_ARGS__).str() << "\n"; \
log_private->WriteMessage(out); \
} \
} while (0)

// Write message to log, if error is set. In the log message refer to the error
// with {0}. Error is cleared regardless of whether logging is enabled.
#define DAP_LOG_ERROR(log, error, ...) \
do { \
::std::ofstream *log_private = (log); \
::lldb_dap::Log *log_private = (log); \
::llvm::Error error_private = (error); \
if (log_private && error_private) { \
::std::chrono::duration<double> now{ \
std::chrono::system_clock::now().time_since_epoch()}; \
*log_private << ::llvm::formatv("{0:f9} ", now.count()).str() \
<< ::lldb_dap::FormatError(::std::move(error_private), \
__VA_ARGS__) \
<< std::endl; \
::std::string out; \
::llvm::raw_string_ostream os(out); \
os << ::llvm::formatv("{0:f9} ", now.count()).str() \
<< ::lldb_dap::FormatError(::std::move(error_private), __VA_ARGS__) \
<< "\n"; \
log_private->WriteMessage(out); \
} else \
::llvm::consumeError(::std::move(error_private)); \
} while (0)

namespace lldb_dap {

class Log {
public:
Log(std::ofstream stream) : m_stream(std::move(stream)) {}

void WriteMessage(llvm::StringRef message) {
std::scoped_lock<std::mutex> lock(m_mutex);
m_stream << message.str();
m_stream.flush();
}

private:
std::mutex m_mutex;
std::ofstream m_stream;
};

template <typename... Args>
inline auto FormatError(llvm::Error error, const char *format, Args &&...args) {
return llvm::formatv(format, llvm::toString(std::move(error)),
Expand Down
12 changes: 5 additions & 7 deletions lldb/tools/lldb-dap/EventHelper.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -178,15 +178,13 @@ void SendThreadStoppedEvent(DAP &dap) {
SendThreadExitedEvent(dap, tid);
}
} else {
if (dap.log)
*dap.log << "error: SendThreadStoppedEvent() when process"
" isn't stopped ("
<< lldb::SBDebugger::StateAsCString(state) << ')' << std::endl;
DAP_LOG(
dap.log,
"error: SendThreadStoppedEvent() when process isn't stopped ({0})",
lldb::SBDebugger::StateAsCString(state));
}
} else {
if (dap.log)
*dap.log << "error: SendThreadStoppedEvent() invalid process"
<< std::endl;
DAP_LOG(dap.log, "error: SendThreadStoppedEvent() invalid process");
}
dap.RunStopCommands();
}
Expand Down
2 changes: 1 addition & 1 deletion lldb/tools/lldb-dap/Transport.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ static constexpr StringLiteral kHeaderSeparator = "\r\n\r\n";

namespace lldb_dap {

Transport::Transport(StringRef client_name, std::ofstream *log,
Transport::Transport(StringRef client_name, Log *log,
IOObjectSP input, IOObjectSP output)
: m_client_name(client_name), m_log(log), m_input(std::move(input)),
m_output(std::move(output)) {}
Expand Down
8 changes: 4 additions & 4 deletions lldb/tools/lldb-dap/Transport.h
Original file line number Diff line number Diff line change
Expand Up @@ -14,11 +14,11 @@
#ifndef LLDB_TOOLS_LLDB_DAP_TRANSPORT_H
#define LLDB_TOOLS_LLDB_DAP_TRANSPORT_H

#include "DAPLog.h"
#include "Protocol/ProtocolBase.h"
#include "lldb/lldb-forward.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/Support/Error.h"
#include <fstream>
#include <optional>

namespace lldb_dap {
Expand All @@ -27,8 +27,8 @@ namespace lldb_dap {
/// with the client.
class Transport {
public:
Transport(llvm::StringRef client_name, std::ofstream *log,
lldb::IOObjectSP input, lldb::IOObjectSP output);
Transport(llvm::StringRef client_name, Log *log, lldb::IOObjectSP input,
lldb::IOObjectSP output);
~Transport() = default;

/// Transport is not copyable.
Expand All @@ -51,7 +51,7 @@ class Transport {

private:
llvm::StringRef m_client_name;
std::ofstream *m_log;
Log *m_log;
lldb::IOObjectSP m_input;
lldb::IOObjectSP m_output;
};
Expand Down
6 changes: 3 additions & 3 deletions lldb/tools/lldb-dap/lldb-dap.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -281,7 +281,7 @@ validateConnection(llvm::StringRef conn) {

static llvm::Error
serveConnection(const Socket::SocketProtocol &protocol, const std::string &name,
std::ofstream *log, llvm::StringRef program_path,
Log *log, llvm::StringRef program_path,
const ReplMode default_repl_mode,
const std::vector<std::string> &pre_init_commands) {
Status status;
Expand Down Expand Up @@ -484,10 +484,10 @@ int main(int argc, char *argv[]) {
}
#endif

std::unique_ptr<std::ofstream> log = nullptr;
std::unique_ptr<Log> log = nullptr;
const char *log_file_path = getenv("LLDBDAP_LOG");
if (log_file_path)
log = std::make_unique<std::ofstream>(log_file_path);
log = std::make_unique<Log>(std::ofstream(log_file_path));

// Initialize LLDB first before we do anything.
lldb::SBError error = lldb::SBDebugger::InitializeWithErrorHandling();
Expand Down
Loading