66//
77// ===----------------------------------------------------------------------===//
88
9+ #include < chrono>
10+ #include < cstdarg>
11+ #include < fstream>
12+ #include < mutex>
13+
914#include " DAP.h"
1015#include " JSONUtils.h"
1116#include " LLDBUtils.h"
12- #include " OutputRedirector.h"
13- #include " lldb/API/SBBreakpoint.h"
1417#include " lldb/API/SBCommandInterpreter.h"
15- #include " lldb/API/SBCommandReturnObject.h"
1618#include " lldb/API/SBLanguageRuntime.h"
1719#include " lldb/API/SBListener.h"
18- #include " lldb/API/SBProcess.h"
1920#include " lldb/API/SBStream.h"
20- #include " lldb/Host/FileSystem.h"
21- #include " lldb/Utility/Status.h"
22- #include " lldb/lldb-defines.h"
23- #include " lldb/lldb-enumerations.h"
24- #include " llvm/ADT/ArrayRef.h"
2521#include " llvm/ADT/StringExtras.h"
26- #include " llvm/ADT/Twine.h"
27- #include " llvm/Support/Error.h"
28- #include " llvm/Support/ErrorHandling.h"
2922#include " llvm/Support/FormatVariadic.h"
30- #include " llvm/Support/raw_ostream.h"
31- #include < algorithm>
32- #include < cassert>
33- #include < chrono>
34- #include < cstdarg>
35- #include < cstdio>
36- #include < fstream>
37- #include < mutex>
38- #include < utility>
3923
4024#if defined(_WIN32)
4125#define NOMINMAX
4226#include < fcntl.h>
4327#include < io.h>
4428#include < windows.h>
45- #else
46- #include < unistd.h>
4729#endif
4830
4931using namespace lldb_dap ;
5032
51- namespace {
52- #ifdef _WIN32
53- const char DEV_NULL[] = " nul" ;
54- #else
55- const char DEV_NULL[] = " /dev/null" ;
56- #endif
57- } // namespace
58-
5933namespace lldb_dap {
6034
61- DAP::DAP (llvm::StringRef path, std::ofstream *log, ReplMode repl_mode,
62- StreamDescriptor input, StreamDescriptor output)
63- : debug_adaptor_path(path), log(log), input(std::move(input)),
64- output (std::move(output)), broadcaster(" lldb-dap" ),
35+ DAP::DAP (llvm::StringRef path, ReplMode repl_mode)
36+ : debug_adaptor_path(path), broadcaster(" lldb-dap" ),
6537 exception_breakpoints (), focus_tid(LLDB_INVALID_THREAD_ID),
6638 stop_at_entry(false ), is_attach(false ),
6739 enable_auto_variable_summaries(false ),
@@ -71,7 +43,21 @@ DAP::DAP(llvm::StringRef path, std::ofstream *log, ReplMode repl_mode,
7143 configuration_done_sent(false ), waiting_for_run_in_terminal(false ),
7244 progress_event_reporter(
7345 [&](const ProgressEvent &event) { SendJSON (event.ToJSON ()); }),
74- reverse_request_seq (0 ), repl_mode(repl_mode) {}
46+ reverse_request_seq (0 ), repl_mode(repl_mode) {
47+ const char *log_file_path = getenv (" LLDBDAP_LOG" );
48+ #if defined(_WIN32)
49+ // Windows opens stdout and stdin in text mode which converts \n to 13,10
50+ // while the value is just 10 on Darwin/Linux. Setting the file mode to binary
51+ // fixes this.
52+ int result = _setmode (fileno (stdout), _O_BINARY);
53+ assert (result);
54+ result = _setmode (fileno (stdin), _O_BINARY);
55+ UNUSED_IF_ASSERT_DISABLED (result);
56+ assert (result);
57+ #endif
58+ if (log_file_path)
59+ log.reset (new std::ofstream (log_file_path));
60+ }
7561
7662DAP::~DAP () = default ;
7763
@@ -187,45 +173,6 @@ ExceptionBreakpoint *DAP::GetExceptionBreakpoint(const lldb::break_id_t bp_id) {
187173 return nullptr ;
188174}
189175
190- llvm::Error DAP::ConfigureIO (std::FILE *overrideOut, std::FILE *overrideErr) {
191- in = lldb::SBFile (std::fopen (DEV_NULL, " r" ), /* transfer_ownership=*/ true );
192-
193- if (auto Error = out.RedirectTo ([this ](llvm::StringRef output) {
194- SendOutput (OutputType::Stdout, output);
195- }))
196- return Error;
197-
198- if (overrideOut) {
199- auto fd = out.GetWriteFileDescriptor ();
200- if (auto Error = fd.takeError ())
201- return Error;
202-
203- if (dup2 (*fd, fileno (overrideOut)) == -1 )
204- return llvm::errorCodeToError (llvm::errnoAsErrorCode ());
205- }
206-
207- if (auto Error = err.RedirectTo ([this ](llvm::StringRef output) {
208- SendOutput (OutputType::Stderr, output);
209- }))
210- return Error;
211-
212- if (overrideErr) {
213- auto fd = err.GetWriteFileDescriptor ();
214- if (auto Error = fd.takeError ())
215- return Error;
216-
217- if (dup2 (*fd, fileno (overrideErr)) == -1 )
218- return llvm::errorCodeToError (llvm::errnoAsErrorCode ());
219- }
220-
221- return llvm::Error::success ();
222- }
223-
224- void DAP::StopIO () {
225- out.Stop ();
226- err.Stop ();
227- }
228-
229176// Send the JSON in "json_str" to the "out" stream. Correctly send the
230177// "Content-Length:" field followed by the length, followed by the raw
231178// JSON bytes.
@@ -261,19 +208,19 @@ std::string DAP::ReadJSON() {
261208 std::string json_str;
262209 int length;
263210
264- if (!input.read_expected (log, " Content-Length: " ))
211+ if (!input.read_expected (log. get () , " Content-Length: " ))
265212 return json_str;
266213
267- if (!input.read_line (log, length_str))
214+ if (!input.read_line (log. get () , length_str))
268215 return json_str;
269216
270217 if (!llvm::to_integer (length_str, length))
271218 return json_str;
272219
273- if (!input.read_expected (log, " \r\n " ))
220+ if (!input.read_expected (log. get () , " \r\n " ))
274221 return json_str;
275222
276- if (!input.read_full (log, length, json_str))
223+ if (!input.read_full (log. get () , length, json_str))
277224 return json_str;
278225
279226 if (log) {
0 commit comments