1 //===-- SystemInitializerCommon.cpp ---------------------------------------===//
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 #include "lldb/Initialization/SystemInitializerCommon.h"
10 
11 #include "Plugins/Process/gdb-remote/ProcessGDBRemoteLog.h"
12 #include "lldb/Host/FileSystem.h"
13 #include "lldb/Host/Host.h"
14 #include "lldb/Host/Socket.h"
15 #include "lldb/Utility/LLDBLog.h"
16 #include "lldb/Utility/ReproducerProvider.h"
17 #include "lldb/Utility/Timer.h"
18 #include "lldb/Version/Version.h"
19 
20 #if defined(__linux__) || defined(__FreeBSD__) || defined(__NetBSD__)
21 #include "Plugins/Process/POSIX/ProcessPOSIXLog.h"
22 #endif
23 
24 #if defined(_WIN32)
25 #include "Plugins/Process/Windows/Common/ProcessWindowsLog.h"
26 #include "lldb/Host/windows/windows.h"
27 #include <crtdbg.h>
28 #endif
29 
30 #include "llvm/Support/TargetSelect.h"
31 
32 #include <string>
33 
34 using namespace lldb_private;
35 using namespace lldb_private::repro;
36 
37 SystemInitializerCommon::SystemInitializerCommon(
38     HostInfo::SharedLibraryDirectoryHelper *helper)
39     : m_shlib_dir_helper(helper) {}
40 
41 SystemInitializerCommon::~SystemInitializerCommon() = default;
42 
43 /// Initialize the FileSystem based on the current reproducer mode.
44 static llvm::Error InitializeFileSystem() {
45   auto &r = repro::Reproducer::Instance();
46   if (repro::Generator *g = r.GetGenerator()) {
47     repro::VersionProvider &vp = g->GetOrCreate<repro::VersionProvider>();
48     vp.SetVersion(lldb_private::GetVersion());
49 
50     repro::FileProvider &fp = g->GetOrCreate<repro::FileProvider>();
51     FileSystem::Initialize(fp.GetFileCollector());
52 
53     fp.RecordInterestingDirectory(
54         g->GetOrCreate<repro::WorkingDirectoryProvider>().GetDirectory());
55     fp.RecordInterestingDirectory(
56         g->GetOrCreate<repro::HomeDirectoryProvider>().GetDirectory());
57 
58     return llvm::Error::success();
59   }
60 
61   FileSystem::Initialize();
62   return llvm::Error::success();
63 }
64 
65 llvm::Error SystemInitializerCommon::Initialize() {
66 #if defined(_WIN32)
67   const char *disable_crash_dialog_var = getenv("LLDB_DISABLE_CRASH_DIALOG");
68   if (disable_crash_dialog_var &&
69       llvm::StringRef(disable_crash_dialog_var).equals_insensitive("true")) {
70     // This will prevent Windows from displaying a dialog box requiring user
71     // interaction when
72     // LLDB crashes.  This is mostly useful when automating LLDB, for example
73     // via the test
74     // suite, so that a crash in LLDB does not prevent completion of the test
75     // suite.
76     ::SetErrorMode(GetErrorMode() | SEM_FAILCRITICALERRORS |
77                    SEM_NOGPFAULTERRORBOX);
78 
79     _CrtSetReportMode(_CRT_ASSERT, _CRTDBG_MODE_FILE | _CRTDBG_MODE_DEBUG);
80     _CrtSetReportMode(_CRT_WARN, _CRTDBG_MODE_FILE | _CRTDBG_MODE_DEBUG);
81     _CrtSetReportMode(_CRT_ERROR, _CRTDBG_MODE_FILE | _CRTDBG_MODE_DEBUG);
82     _CrtSetReportFile(_CRT_ASSERT, _CRTDBG_FILE_STDERR);
83     _CrtSetReportFile(_CRT_WARN, _CRTDBG_FILE_STDERR);
84     _CrtSetReportFile(_CRT_ERROR, _CRTDBG_FILE_STDERR);
85   }
86 #endif
87 
88   // If the reproducer wasn't initialized before, we can safely assume it's
89   // off.
90   if (!Reproducer::Initialized()) {
91     if (auto e = Reproducer::Initialize(ReproducerMode::Off, llvm::None))
92       return e;
93   }
94 
95   if (auto e = InitializeFileSystem())
96     return e;
97 
98   InitializeLldbChannel();
99   HostInfo::Initialize(m_shlib_dir_helper);
100 
101   llvm::Error error = Socket::Initialize();
102   if (error)
103     return error;
104 
105   LLDB_SCOPED_TIMER();
106 
107   process_gdb_remote::ProcessGDBRemoteLog::Initialize();
108 
109 #if defined(__linux__) || defined(__FreeBSD__) || defined(__NetBSD__)
110   ProcessPOSIXLog::Initialize();
111 #endif
112 #if defined(_WIN32)
113   ProcessWindowsLog::Initialize();
114 #endif
115 
116   return llvm::Error::success();
117 }
118 
119 void SystemInitializerCommon::Terminate() {
120   LLDB_SCOPED_TIMER();
121 
122 #if defined(_WIN32)
123   ProcessWindowsLog::Terminate();
124 #endif
125 
126   Socket::Terminate();
127   HostInfo::Terminate();
128   Log::DisableAllLogChannels();
129   FileSystem::Terminate();
130   Reproducer::Terminate();
131 }
132