180814287SRaphael Isemann //===-- SystemInitializerCommon.cpp ---------------------------------------===//
2e6e2bb38SZachary Turner //
32946cd70SChandler Carruth // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
42946cd70SChandler Carruth // See https://llvm.org/LICENSE.txt for license information.
52946cd70SChandler Carruth // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6e6e2bb38SZachary Turner //
7e6e2bb38SZachary Turner //===----------------------------------------------------------------------===//
8e6e2bb38SZachary Turner 
9e6e2bb38SZachary Turner #include "lldb/Initialization/SystemInitializerCommon.h"
10e6e2bb38SZachary Turner 
11e6e2bb38SZachary Turner #include "Plugins/Process/gdb-remote/ProcessGDBRemoteLog.h"
1246376966SJonas Devlieghere #include "lldb/Host/FileSystem.h"
13b9c1b51eSKate Stone #include "lldb/Host/Host.h"
14f8a74c18SAaron Smith #include "lldb/Host/Socket.h"
156f9e6901SZachary Turner #include "lldb/Utility/Log.h"
16bb894b97SJonas Devlieghere #include "lldb/Utility/ReproducerProvider.h"
1738d0632eSPavel Labath #include "lldb/Utility/Timer.h"
18c2e2df7fSJonas Devlieghere #include "lldb/lldb-private.h"
19e6e2bb38SZachary Turner 
20a87101d6SKamil Rytarowski #if defined(__linux__) || defined(__FreeBSD__) || defined(__NetBSD__)
21e6e2bb38SZachary Turner #include "Plugins/Process/POSIX/ProcessPOSIXLog.h"
22e6e2bb38SZachary Turner #endif
23e6e2bb38SZachary Turner 
24d179ce99SSaleem Abdulrasool #if defined(_WIN32)
2518a9135dSAdrian McCarthy #include "Plugins/Process/Windows/Common/ProcessWindowsLog.h"
2674e08ca0SZachary Turner #include "lldb/Host/windows/windows.h"
27a63417feSHaibo Huang #include <crtdbg.h>
28e6e2bb38SZachary Turner #endif
29e6e2bb38SZachary Turner 
30e6e2bb38SZachary Turner #include "llvm/Support/TargetSelect.h"
31e6e2bb38SZachary Turner 
32e6e2bb38SZachary Turner #include <string>
33e6e2bb38SZachary Turner 
34e6e2bb38SZachary Turner using namespace lldb_private;
3515eacd74SJonas Devlieghere using namespace lldb_private::repro;
36e6e2bb38SZachary Turner 
37*004a264fSPavel Labath SystemInitializerCommon::SystemInitializerCommon(
38*004a264fSPavel Labath     HostInfo::SharedLibraryDirectoryHelper *helper)
39*004a264fSPavel Labath     : m_shlib_dir_helper(helper) {}
40e6e2bb38SZachary Turner 
41b9c1b51eSKate Stone SystemInitializerCommon::~SystemInitializerCommon() {}
42e6e2bb38SZachary Turner 
43ed17b6f6SJonas Devlieghere /// Initialize the FileSystem based on the current reproducer mode.
44ed17b6f6SJonas Devlieghere static llvm::Error InitializeFileSystem() {
45ed17b6f6SJonas Devlieghere   auto &r = repro::Reproducer::Instance();
46ed17b6f6SJonas Devlieghere   if (repro::Loader *loader = r.GetLoader()) {
47ed17b6f6SJonas Devlieghere     FileSpec vfs_mapping = loader->GetFile<FileProvider::Info>();
48ed17b6f6SJonas Devlieghere     if (vfs_mapping) {
49ed17b6f6SJonas Devlieghere       if (llvm::Error e = FileSystem::Initialize(vfs_mapping))
50ed17b6f6SJonas Devlieghere         return e;
51ed17b6f6SJonas Devlieghere     } else {
52ed17b6f6SJonas Devlieghere       FileSystem::Initialize();
53ed17b6f6SJonas Devlieghere     }
54ed17b6f6SJonas Devlieghere 
5573af341bSJonas Devlieghere     // Set the current working directory form the reproducer.
5673af341bSJonas Devlieghere     llvm::Expected<std::string> working_dir =
5773af341bSJonas Devlieghere         repro::GetDirectoryFrom<WorkingDirectoryProvider>(loader);
5873af341bSJonas Devlieghere     if (!working_dir)
5973af341bSJonas Devlieghere       return working_dir.takeError();
60ed17b6f6SJonas Devlieghere     if (std::error_code ec = FileSystem::Instance()
61ed17b6f6SJonas Devlieghere                                  .GetVirtualFileSystem()
6273af341bSJonas Devlieghere                                  ->setCurrentWorkingDirectory(*working_dir)) {
63ed17b6f6SJonas Devlieghere       return llvm::errorCodeToError(ec);
64ed17b6f6SJonas Devlieghere     }
65ed17b6f6SJonas Devlieghere 
6673af341bSJonas Devlieghere     // Set the home directory from the reproducer.
6773af341bSJonas Devlieghere     llvm::Expected<std::string> home_dir =
6873af341bSJonas Devlieghere         repro::GetDirectoryFrom<HomeDirectoryProvider>(loader);
6973af341bSJonas Devlieghere     if (!home_dir)
7073af341bSJonas Devlieghere       return home_dir.takeError();
7173af341bSJonas Devlieghere     FileSystem::Instance().SetHomeDirectory(*home_dir);
7273af341bSJonas Devlieghere 
73ed17b6f6SJonas Devlieghere     return llvm::Error::success();
74ed17b6f6SJonas Devlieghere   }
75ed17b6f6SJonas Devlieghere 
76ed17b6f6SJonas Devlieghere   if (repro::Generator *g = r.GetGenerator()) {
77ed17b6f6SJonas Devlieghere     repro::VersionProvider &vp = g->GetOrCreate<repro::VersionProvider>();
78ed17b6f6SJonas Devlieghere     vp.SetVersion(lldb_private::GetVersion());
79ed17b6f6SJonas Devlieghere 
80ed17b6f6SJonas Devlieghere     repro::FileProvider &fp = g->GetOrCreate<repro::FileProvider>();
81ed17b6f6SJonas Devlieghere     FileSystem::Initialize(fp.GetFileCollector());
82ed17b6f6SJonas Devlieghere 
83426fa35bSJonas Devlieghere     fp.RecordInterestingDirectory(
84426fa35bSJonas Devlieghere         g->GetOrCreate<repro::WorkingDirectoryProvider>().GetDirectory());
85426fa35bSJonas Devlieghere     fp.RecordInterestingDirectory(
86426fa35bSJonas Devlieghere         g->GetOrCreate<repro::HomeDirectoryProvider>().GetDirectory());
87ed17b6f6SJonas Devlieghere 
88ed17b6f6SJonas Devlieghere     return llvm::Error::success();
89ed17b6f6SJonas Devlieghere   }
90ed17b6f6SJonas Devlieghere 
91ed17b6f6SJonas Devlieghere   FileSystem::Initialize();
92ed17b6f6SJonas Devlieghere   return llvm::Error::success();
93ed17b6f6SJonas Devlieghere }
94ed17b6f6SJonas Devlieghere 
95936c6242SJonas Devlieghere llvm::Error SystemInitializerCommon::Initialize() {
96d179ce99SSaleem Abdulrasool #if defined(_WIN32)
97e6e2bb38SZachary Turner   const char *disable_crash_dialog_var = getenv("LLDB_DISABLE_CRASH_DIALOG");
98b9c1b51eSKate Stone   if (disable_crash_dialog_var &&
99b9c1b51eSKate Stone       llvm::StringRef(disable_crash_dialog_var).equals_lower("true")) {
100b9c1b51eSKate Stone     // This will prevent Windows from displaying a dialog box requiring user
101b9c1b51eSKate Stone     // interaction when
102b9c1b51eSKate Stone     // LLDB crashes.  This is mostly useful when automating LLDB, for example
103b9c1b51eSKate Stone     // via the test
104b9c1b51eSKate Stone     // suite, so that a crash in LLDB does not prevent completion of the test
105b9c1b51eSKate Stone     // suite.
106b9c1b51eSKate Stone     ::SetErrorMode(GetErrorMode() | SEM_FAILCRITICALERRORS |
107b9c1b51eSKate Stone                    SEM_NOGPFAULTERRORBOX);
108e6e2bb38SZachary Turner 
109e6e2bb38SZachary Turner     _CrtSetReportMode(_CRT_ASSERT, _CRTDBG_MODE_FILE | _CRTDBG_MODE_DEBUG);
110e6e2bb38SZachary Turner     _CrtSetReportMode(_CRT_WARN, _CRTDBG_MODE_FILE | _CRTDBG_MODE_DEBUG);
111e6e2bb38SZachary Turner     _CrtSetReportMode(_CRT_ERROR, _CRTDBG_MODE_FILE | _CRTDBG_MODE_DEBUG);
112e6e2bb38SZachary Turner     _CrtSetReportFile(_CRT_ASSERT, _CRTDBG_FILE_STDERR);
113e6e2bb38SZachary Turner     _CrtSetReportFile(_CRT_WARN, _CRTDBG_FILE_STDERR);
114e6e2bb38SZachary Turner     _CrtSetReportFile(_CRT_ERROR, _CRTDBG_FILE_STDERR);
115e6e2bb38SZachary Turner   }
116e6e2bb38SZachary Turner #endif
117e6e2bb38SZachary Turner 
118936c6242SJonas Devlieghere   // If the reproducer wasn't initialized before, we can safely assume it's
119936c6242SJonas Devlieghere   // off.
120936c6242SJonas Devlieghere   if (!Reproducer::Initialized()) {
121936c6242SJonas Devlieghere     if (auto e = Reproducer::Initialize(ReproducerMode::Off, llvm::None))
12215eacd74SJonas Devlieghere       return e;
123936c6242SJonas Devlieghere   }
12415eacd74SJonas Devlieghere 
125ed17b6f6SJonas Devlieghere   if (auto e = InitializeFileSystem())
12646575176SJonas Devlieghere     return e;
12746575176SJonas Devlieghere 
128d813309eSPavel Labath   Log::Initialize();
129*004a264fSPavel Labath   HostInfo::Initialize(m_shlib_dir_helper);
130f8a74c18SAaron Smith 
131f8a74c18SAaron Smith   llvm::Error error = Socket::Initialize();
132f8a74c18SAaron Smith   if (error)
133f8a74c18SAaron Smith     return error;
134f8a74c18SAaron Smith 
1355c1c8443SJonas Devlieghere   LLDB_SCOPED_TIMER();
136e6e2bb38SZachary Turner 
137e6e2bb38SZachary Turner   process_gdb_remote::ProcessGDBRemoteLog::Initialize();
138e6e2bb38SZachary Turner 
139a87101d6SKamil Rytarowski #if defined(__linux__) || defined(__FreeBSD__) || defined(__NetBSD__)
140c29f7ff3SPavel Labath   ProcessPOSIXLog::Initialize();
141e6e2bb38SZachary Turner #endif
142d179ce99SSaleem Abdulrasool #if defined(_WIN32)
14342b33806SAdrian McCarthy   ProcessWindowsLog::Initialize();
14442b33806SAdrian McCarthy #endif
14515eacd74SJonas Devlieghere 
14615eacd74SJonas Devlieghere   return llvm::Error::success();
147e6e2bb38SZachary Turner }
148e6e2bb38SZachary Turner 
149b9c1b51eSKate Stone void SystemInitializerCommon::Terminate() {
1505c1c8443SJonas Devlieghere   LLDB_SCOPED_TIMER();
151e6e2bb38SZachary Turner 
152d179ce99SSaleem Abdulrasool #if defined(_WIN32)
153610e5291SZachary Turner   ProcessWindowsLog::Terminate();
154610e5291SZachary Turner #endif
155610e5291SZachary Turner 
156f8a74c18SAaron Smith   Socket::Terminate();
15741331afaSZachary Turner   HostInfo::Terminate();
158775588c0SPavel Labath   Log::DisableAllLogChannels();
15946376966SJonas Devlieghere   FileSystem::Terminate();
16015eacd74SJonas Devlieghere   Reproducer::Terminate();
161e6e2bb38SZachary Turner }
162