Skip to content

Commit 8d57635

Browse files
authored
[lldb-dap] Improving logging support and formatting. (#170731)
Adjusting logs in a few ways: * The `DAP_LOG` and `DAP_LOG_ERROR` macros now include the file/line of the log statement. * Added support for creating a log with a prefix. This simplifies how we create logs for the `lldb_dap::DAP` instance and `lldb_dap::Transport` instance, allowing us to not have to pass the client name around as much. * Updated logging usage to take the `lldb_dap::Log` as a reference but it now defaults to `llvm::raw_null_stream` if not configured. This ensures more uniform access to the logger, even if its not written anywhere. The logs now look like: ``` 1764896564.038788080 (stdio) --> {"command":"initialize","arguments":{...},"type":"request","seq":1} 1764896564.039064884 DAP.cpp:1007 (stdio) queued (command=initialize seq=1) 1764896564.039768934 (stdio) <-- {"body":{...},"command":"initialize","request_seq":1,"seq":1,"success":true,"type":"response"} ```
1 parent 2e2fe68 commit 8d57635

File tree

14 files changed

+166
-110
lines changed

14 files changed

+166
-110
lines changed

lldb/tools/lldb-dap/DAP.cpp

Lines changed: 15 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -122,7 +122,7 @@ static std::string capitalize(llvm::StringRef str) {
122122

123123
llvm::StringRef DAP::debug_adapter_path = "";
124124

125-
DAP::DAP(Log *log, const ReplMode default_repl_mode,
125+
DAP::DAP(Log &log, const ReplMode default_repl_mode,
126126
std::vector<std::string> pre_init_commands, bool no_lldbinit,
127127
llvm::StringRef client_name, DAPTransport &transport, MainLoop &loop)
128128
: log(log), transport(transport), broadcaster("lldb-dap"),
@@ -134,8 +134,6 @@ DAP::DAP(Log *log, const ReplMode default_repl_mode,
134134
RegisterRequests();
135135
}
136136

137-
DAP::~DAP() = default;
138-
139137
void DAP::PopulateExceptionBreakpoints() {
140138
if (lldb::SBDebugger::SupportsLanguage(lldb::eLanguageTypeC_plus_plus)) {
141139
exception_breakpoints.emplace_back(*this, "cpp_catch", "C++ Catch",
@@ -263,8 +261,7 @@ void DAP::SendJSON(const llvm::json::Value &json) {
263261
Message message;
264262
llvm::json::Path::Root root;
265263
if (!fromJSON(json, message, root)) {
266-
DAP_LOG_ERROR(log, root.getError(), "({1}) encoding failed: {0}",
267-
m_client_name);
264+
DAP_LOG_ERROR(log, root.getError(), "encoding failed: {0}");
268265
return;
269266
}
270267
Send(message);
@@ -285,15 +282,13 @@ Id DAP::Send(const Message &message) {
285282

286283
if (const protocol::Event *event = std::get_if<protocol::Event>(&msg)) {
287284
if (llvm::Error err = transport.Send(*event))
288-
DAP_LOG_ERROR(log, std::move(err), "({0}) sending event failed",
289-
m_client_name);
285+
DAP_LOG_ERROR(log, std::move(err), "sending event failed: {0}");
290286
return event->seq;
291287
}
292288

293289
if (const Request *req = std::get_if<Request>(&msg)) {
294290
if (llvm::Error err = transport.Send(*req))
295-
DAP_LOG_ERROR(log, std::move(err), "({0}) sending request failed",
296-
m_client_name);
291+
DAP_LOG_ERROR(log, std::move(err), "sending request failed: {0}");
297292
return req->seq;
298293
}
299294

@@ -313,8 +308,7 @@ Id DAP::Send(const Message &message) {
313308
})
314309
: transport.Send(*resp);
315310
if (err)
316-
DAP_LOG_ERROR(log, std::move(err), "({0}) sending response failed",
317-
m_client_name);
311+
DAP_LOG_ERROR(log, std::move(err), "sending response failed: {0}");
318312
return resp->seq;
319313
}
320314

@@ -857,8 +851,7 @@ bool DAP::HandleObject(const Message &M) {
857851

858852
dispatcher.Set("error",
859853
llvm::Twine("unhandled-command:" + req->command).str());
860-
DAP_LOG(log, "({0}) error: unhandled command '{1}'", m_client_name,
861-
req->command);
854+
DAP_LOG(log, "error: unhandled command '{0}'", req->command);
862855
return false; // Fail
863856
}
864857

@@ -1004,35 +997,33 @@ void DAP::Received(const protocol::Request &request) {
1004997
// effort attempt to interrupt.
1005998
std::lock_guard<std::mutex> guard(m_active_request_mutex);
1006999
if (m_active_request && cancel_args->requestId == m_active_request->seq) {
1007-
DAP_LOG(log, "({0}) interrupting inflight request (command={1} seq={2})",
1008-
m_client_name, m_active_request->command, m_active_request->seq);
1000+
DAP_LOG(log, "interrupting inflight request (command={0} seq={1})",
1001+
m_active_request->command, m_active_request->seq);
10091002
debugger.RequestInterrupt();
10101003
}
10111004
}
10121005

10131006
std::lock_guard<std::mutex> guard(m_queue_mutex);
1014-
DAP_LOG(log, "({0}) queued (command={1} seq={2})", m_client_name,
1015-
request.command, request.seq);
1007+
DAP_LOG(log, "queued (command={0} seq={1})", request.command, request.seq);
10161008
m_queue.push_back(request);
10171009
m_queue_cv.notify_one();
10181010
}
10191011

10201012
void DAP::Received(const protocol::Response &response) {
10211013
std::lock_guard<std::mutex> guard(m_queue_mutex);
1022-
DAP_LOG(log, "({0}) queued (command={1} seq={2})", m_client_name,
1023-
response.command, response.request_seq);
1014+
DAP_LOG(log, "queued (command={0} seq={1})", response.command,
1015+
response.request_seq);
10241016
m_queue.push_back(response);
10251017
m_queue_cv.notify_one();
10261018
}
10271019

10281020
void DAP::OnError(llvm::Error error) {
1029-
DAP_LOG_ERROR(log, std::move(error), "({1}) received error: {0}",
1030-
m_client_name);
1021+
DAP_LOG_ERROR(log, std::move(error), "transport error: {0}");
10311022
TerminateLoop(/*failed=*/true);
10321023
}
10331024

10341025
void DAP::OnClosed() {
1035-
DAP_LOG(log, "({0}) received EOF", m_client_name);
1026+
DAP_LOG(log, "transport closed");
10361027
TerminateLoop();
10371028
}
10381029

@@ -1058,16 +1049,14 @@ void DAP::TransportHandler() {
10581049
auto handle = transport.RegisterMessageHandler(m_loop, *this);
10591050
if (!handle) {
10601051
DAP_LOG_ERROR(log, handle.takeError(),
1061-
"({1}) registering message handler failed: {0}",
1062-
m_client_name);
1052+
"registering message handler failed: {0}");
10631053
std::lock_guard<std::mutex> guard(m_queue_mutex);
10641054
m_error_occurred = true;
10651055
return;
10661056
}
10671057

10681058
if (Status status = m_loop.Run(); status.Fail()) {
1069-
DAP_LOG_ERROR(log, status.takeError(), "({1}) MainLoop run failed: {0}",
1070-
m_client_name);
1059+
DAP_LOG_ERROR(log, status.takeError(), "MainLoop run failed: {0}");
10711060
std::lock_guard<std::mutex> guard(m_queue_mutex);
10721061
m_error_occurred = true;
10731062
return;

lldb/tools/lldb-dap/DAP.h

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -33,11 +33,9 @@
3333
#include "lldb/API/SBTarget.h"
3434
#include "lldb/API/SBThread.h"
3535
#include "lldb/Host/MainLoop.h"
36-
#include "lldb/Utility/Status.h"
3736
#include "lldb/lldb-types.h"
3837
#include "llvm/ADT/DenseMap.h"
3938
#include "llvm/ADT/DenseSet.h"
40-
#include "llvm/ADT/FunctionExtras.h"
4139
#include "llvm/ADT/SmallSet.h"
4240
#include "llvm/ADT/StringMap.h"
4341
#include "llvm/ADT/StringRef.h"
@@ -88,7 +86,7 @@ struct DAP final : public DAPTransport::MessageHandler {
8886
/// Path to the lldb-dap binary itself.
8987
static llvm::StringRef debug_adapter_path;
9088

91-
Log *log;
89+
Log &log;
9290
DAPTransport &transport;
9391
lldb::SBFile in;
9492
OutputRedirector out;
@@ -194,12 +192,12 @@ struct DAP final : public DAPTransport::MessageHandler {
194192
/// Transport for this debug session.
195193
/// \param[in] loop
196194
/// Main loop associated with this instance.
197-
DAP(Log *log, const ReplMode default_repl_mode,
195+
DAP(Log &log, const ReplMode default_repl_mode,
198196
std::vector<std::string> pre_init_commands, bool no_lldbinit,
199197
llvm::StringRef client_name, DAPTransport &transport,
200198
lldb_private::MainLoop &loop);
201199

202-
~DAP();
200+
~DAP() override = default;
203201

204202
/// DAP is not copyable.
205203
/// @{

lldb/tools/lldb-dap/DAPLog.cpp

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -9,21 +9,26 @@
99
#include "DAPLog.h"
1010
#include "llvm/ADT/StringRef.h"
1111
#include "llvm/Support/Chrono.h"
12+
#include "llvm/Support/Path.h"
1213
#include "llvm/Support/raw_ostream.h"
1314
#include <chrono>
1415
#include <mutex>
15-
#include <system_error>
1616

1717
using namespace llvm;
1818

1919
namespace lldb_dap {
2020

21-
Log::Log(StringRef filename, std::error_code &EC) : m_stream(filename, EC) {}
21+
void Log::Emit(StringRef message) { Emit(message, "", 0); }
2222

23-
void Log::WriteMessage(StringRef message) {
24-
std::lock_guard<std::mutex> lock(m_mutex);
23+
void Log::Emit(StringRef message, StringRef file, size_t line) {
24+
std::lock_guard<Log::Mutex> lock(m_mutex);
2525
const llvm::sys::TimePoint<> time = std::chrono::system_clock::now();
26-
m_stream << formatv("[{0:%H:%M:%S.%L}] ", time) << message << '\n';
26+
m_stream << formatv("[{0:%H:%M:%S.%L}]", time) << " ";
27+
if (!file.empty())
28+
m_stream << sys::path::filename(file) << ":" << line << " ";
29+
if (!m_prefix.empty())
30+
m_stream << m_prefix;
31+
m_stream << message << "\n";
2732
m_stream.flush();
2833
}
2934

lldb/tools/lldb-dap/DAPLog.h

Lines changed: 30 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -11,33 +11,28 @@
1111

1212
#include "llvm/ADT/StringRef.h"
1313
#include "llvm/Support/Error.h"
14-
#include "llvm/Support/FormatAdapters.h"
1514
#include "llvm/Support/FormatVariadic.h"
1615
#include "llvm/Support/raw_ostream.h"
1716
#include <mutex>
1817
#include <string>
19-
#include <system_error>
2018

2119
// Write a message to log, if logging is enabled.
2220
#define DAP_LOG(log, ...) \
2321
do { \
24-
::lldb_dap::Log *log_private = (log); \
25-
if (log_private) { \
26-
log_private->WriteMessage(::llvm::formatv(__VA_ARGS__).str()); \
27-
} \
22+
::lldb_dap::Log &log_private = (log); \
23+
log_private.Emit(::llvm::formatv(__VA_ARGS__).str(), __FILE__, __LINE__); \
2824
} while (0)
2925

3026
// Write message to log, if error is set. In the log message refer to the error
3127
// with {0}. Error is cleared regardless of whether logging is enabled.
3228
#define DAP_LOG_ERROR(log, error, ...) \
3329
do { \
34-
::lldb_dap::Log *log_private = (log); \
30+
::lldb_dap::Log &log_private = (log); \
3531
::llvm::Error error_private = (error); \
36-
if (log_private && error_private) { \
37-
log_private->WriteMessage( \
38-
::lldb_dap::FormatError(::std::move(error_private), __VA_ARGS__)); \
39-
} else \
40-
::llvm::consumeError(::std::move(error_private)); \
32+
if (error_private) \
33+
log_private.Emit( \
34+
::lldb_dap::FormatError(::std::move(error_private), __VA_ARGS__), \
35+
__FILE__, __LINE__); \
4136
} while (0)
4237

4338
namespace lldb_dap {
@@ -46,14 +41,32 @@ namespace lldb_dap {
4641
/// `DAP_LOG_ERROR` helpers.
4742
class Log final {
4843
public:
49-
/// Creates a log file with the given filename.
50-
Log(llvm::StringRef filename, std::error_code &EC);
44+
using Mutex = std::mutex;
5145

52-
void WriteMessage(llvm::StringRef message);
46+
Log(llvm::raw_ostream &stream, Mutex &mutex)
47+
: m_stream(stream), m_mutex(mutex) {}
48+
Log(llvm::StringRef prefix, const Log &log)
49+
: m_prefix(prefix), m_stream(log.m_stream), m_mutex(log.m_mutex) {}
50+
51+
/// Retuns a new Log instance with the associated prefix for all messages.
52+
inline Log WithPrefix(llvm::StringRef prefix) const {
53+
std::string full_prefix =
54+
m_prefix.empty() ? prefix.str() : m_prefix + prefix.str();
55+
full_prefix += " ";
56+
return Log(full_prefix, *this);
57+
}
58+
59+
/// Emit writes a message to the underlying stream.
60+
void Emit(llvm::StringRef message);
61+
62+
/// Emit writes a message to the underlying stream, including the file and
63+
/// line the message originated from.
64+
void Emit(llvm::StringRef message, llvm::StringRef file, size_t line);
5365

5466
private:
55-
std::mutex m_mutex;
56-
llvm::raw_fd_ostream m_stream;
67+
std::string m_prefix;
68+
llvm::raw_ostream &m_stream;
69+
Mutex &m_mutex;
5770
};
5871

5972
template <typename... Args>

lldb/tools/lldb-dap/DAPSessionManager.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -110,7 +110,8 @@ DAPSessionManager::GetEventThreadForDebugger(lldb::SBDebugger debugger,
110110
auto new_thread_sp = std::make_shared<ManagedEventThread>(
111111
requesting_dap->broadcaster,
112112
std::thread(EventThread, debugger, requesting_dap->broadcaster,
113-
requesting_dap->m_client_name, requesting_dap->log));
113+
requesting_dap->m_client_name,
114+
std::ref(requesting_dap->log)));
114115
m_debugger_event_threads[debugger_id] = new_thread_sp;
115116
return new_thread_sp;
116117
}

lldb/tools/lldb-dap/EventHelper.cpp

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -324,8 +324,8 @@ void SendMemoryEvent(DAP &dap, lldb::SBValue variable) {
324324
// the original DAP::Handle*Event pattern while supporting multi-session
325325
// debugging.
326326

327-
void HandleProcessEvent(const lldb::SBEvent &event, bool &process_exited,
328-
Log *log) {
327+
static void HandleProcessEvent(const lldb::SBEvent &event, bool &process_exited,
328+
Log &log) {
329329
lldb::SBProcess process = lldb::SBProcess::GetProcessFromEvent(event);
330330

331331
// Find the DAP instance that owns this process's target.
@@ -393,7 +393,7 @@ void HandleProcessEvent(const lldb::SBEvent &event, bool &process_exited,
393393
}
394394
}
395395

396-
void HandleTargetEvent(const lldb::SBEvent &event, Log *log) {
396+
static void HandleTargetEvent(const lldb::SBEvent &event, Log &log) {
397397
lldb::SBTarget target = lldb::SBTarget::GetTargetFromEvent(event);
398398

399399
// Find the DAP instance that owns this target.
@@ -480,7 +480,7 @@ void HandleTargetEvent(const lldb::SBEvent &event, Log *log) {
480480
}
481481
}
482482

483-
void HandleBreakpointEvent(const lldb::SBEvent &event, Log *log) {
483+
static void HandleBreakpointEvent(const lldb::SBEvent &event, Log &log) {
484484
const uint32_t event_mask = event.GetType();
485485
if (!(event_mask & lldb::SBTarget::eBroadcastBitBreakpointChanged))
486486
return;
@@ -529,7 +529,7 @@ void HandleBreakpointEvent(const lldb::SBEvent &event, Log *log) {
529529
}
530530
}
531531

532-
void HandleThreadEvent(const lldb::SBEvent &event, Log *log) {
532+
static void HandleThreadEvent(const lldb::SBEvent &event, Log &log) {
533533
uint32_t event_type = event.GetType();
534534

535535
if (!(event_type & lldb::SBThread::eBroadcastBitStackChanged))
@@ -550,7 +550,7 @@ void HandleThreadEvent(const lldb::SBEvent &event, Log *log) {
550550
thread.GetThreadID());
551551
}
552552

553-
void HandleDiagnosticEvent(const lldb::SBEvent &event, Log *log) {
553+
static void HandleDiagnosticEvent(const lldb::SBEvent &event, Log &log) {
554554
// Global debugger events - send to all DAP instances.
555555
std::vector<DAP *> active_instances =
556556
DAPSessionManager::GetInstance().GetActiveSessions();
@@ -588,7 +588,7 @@ void HandleDiagnosticEvent(const lldb::SBEvent &event, Log *log) {
588588
// them prevent multiple threads from writing simultaneously so no locking
589589
// is required.
590590
void EventThread(lldb::SBDebugger debugger, lldb::SBBroadcaster broadcaster,
591-
llvm::StringRef client_name, Log *log) {
591+
llvm::StringRef client_name, Log &log) {
592592
llvm::set_thread_name("lldb.DAP.client." + client_name + ".event_handler");
593593
lldb::SBListener listener = debugger.GetListener();
594594
broadcaster.AddListener(listener, eBroadcastBitStopEventThread);

lldb/tools/lldb-dap/EventHelper.h

Lines changed: 1 addition & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -51,16 +51,7 @@ void SendMemoryEvent(DAP &dap, lldb::SBValue variable);
5151
/// \param client_name The client name for thread naming/logging purposes.
5252
/// \param log The log instance for logging.
5353
void EventThread(lldb::SBDebugger debugger, lldb::SBBroadcaster broadcaster,
54-
llvm::StringRef client_name, Log *log);
55-
56-
/// Event handler functions called by EventThread.
57-
/// These handlers extract the necessary objects from events and find the
58-
/// appropriate DAP instance to handle them.
59-
void HandleProcessEvent(const lldb::SBEvent &event, bool &done, Log *log);
60-
void HandleTargetEvent(const lldb::SBEvent &event, Log *log);
61-
void HandleBreakpointEvent(const lldb::SBEvent &event, Log *log);
62-
void HandleThreadEvent(const lldb::SBEvent &event, Log *log);
63-
void HandleDiagnosticEvent(const lldb::SBEvent &event, Log *log);
54+
llvm::StringRef client_name, Log &log);
6455

6556
} // namespace lldb_dap
6657

lldb/tools/lldb-dap/Transport.cpp

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -17,13 +17,13 @@ using namespace lldb_private;
1717

1818
namespace lldb_dap {
1919

20-
Transport::Transport(llvm::StringRef client_name, lldb_dap::Log *log,
21-
lldb::IOObjectSP input, lldb::IOObjectSP output)
22-
: HTTPDelimitedJSONTransport(input, output), m_client_name(client_name),
23-
m_log(log) {}
20+
Transport::Transport(lldb_dap::Log &log, lldb::IOObjectSP input,
21+
lldb::IOObjectSP output)
22+
: HTTPDelimitedJSONTransport(input, output), m_log(log) {}
2423

2524
void Transport::Log(llvm::StringRef message) {
26-
DAP_LOG(m_log, "({0}) {1}", m_client_name, message);
25+
// Emit the message directly, since this log was forwarded.
26+
m_log.Emit(message);
2727
}
2828

2929
} // namespace lldb_dap

lldb/tools/lldb-dap/Transport.h

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -35,15 +35,14 @@ class Transport final
3535
: public lldb_private::transport::HTTPDelimitedJSONTransport<
3636
ProtocolDescriptor> {
3737
public:
38-
Transport(llvm::StringRef client_name, lldb_dap::Log *log,
39-
lldb::IOObjectSP input, lldb::IOObjectSP output);
38+
Transport(lldb_dap::Log &log, lldb::IOObjectSP input,
39+
lldb::IOObjectSP output);
4040
virtual ~Transport() = default;
4141

4242
void Log(llvm::StringRef message) override;
4343

4444
private:
45-
llvm::StringRef m_client_name;
46-
lldb_dap::Log *m_log;
45+
lldb_dap::Log &m_log;
4746
};
4847

4948
} // namespace lldb_dap

0 commit comments

Comments
 (0)