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