]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - contrib/llvm/tools/lldb/tools/lldb-mi/MIDriverMain.cpp
Merge llvm, clang, compiler-rt, libc++, libunwind, lld, lldb and openmp
[FreeBSD/FreeBSD.git] / contrib / llvm / tools / lldb / tools / lldb-mi / MIDriverMain.cpp
1 //===-- MIDriverMain.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 // Overview:    Defines the entry point for the console application.
10 //              The MI application (project name MI) runs in two modes:
11 //              An LLDB native driver mode where it acts no different from the
12 //              LLDB driver.
13 //              The other mode is the MI when it finds on the command line
14 //              the --interpreter option. Command line argument --help on its
15 //              own will give
16 //              help for the LLDB driver. If entered with --interpreter then MI
17 //              help will
18 //              provided.
19 //              To implement new MI commands derive a new command class from the
20 //              command base
21 //              class. To enable the new command for interpretation add the new
22 //              command class
23 //              to the command factory. The files of relevance are:
24 //                  MICmdCommands.cpp
25 //                  MICmdBase.h / .cpp
26 //                  MICmdCmd.h / .cpp
27
28 // Third party headers:
29 #include "lldb/API/SBHostOS.h"
30 #include "llvm/ADT/StringRef.h"
31 #include "llvm/Support/PrettyStackTrace.h"
32 #include "llvm/Support/Signals.h"
33 #include <atomic>
34 #include <csignal>
35 #include <stdio.h>
36
37 // In house headers:
38 #include "MICmnConfig.h"
39 #include "MICmnResources.h"
40 #include "MICmnStreamStdin.h"
41 #include "MIDriver.h"
42 #include "MIDriverMgr.h"
43 #include "MIUtilDebug.h"
44 #include "Platform.h"
45
46 #if defined(_MSC_VER)
47 #pragma warning(                                                               \
48     once : 4530) // Warning C4530: C++ exception handler used, but unwind
49                  // semantics are not enabled. Specify /EHsc
50 #endif           // _MSC_VER
51
52 // CODETAG_IOR_SIGNALS
53 //++
54 // Details: The SIGINT signal is sent to a process by its controlling terminal
55 // when a
56 //          user wishes to interrupt the process. This is typically initiated by
57 //          pressing
58 //          Control-C, but on some systems, the "delete" character or "break"
59 //          key can be
60 //          used.
61 //          Be aware this function may be called on another thread besides the
62 //          main thread.
63 // Type:    Function.
64 // Args:    vSigno  - (R) Signal number.
65 // Return:  None.
66 // Throws:  None.
67 //--
68 void sigint_handler(int vSigno) {
69 #ifdef _WIN32 // Restore handler as it is not persistent on Windows
70   signal(SIGINT, sigint_handler);
71 #endif
72   static std::atomic_flag g_interrupt_sent = ATOMIC_FLAG_INIT;
73   CMIDriverMgr &rDriverMgr = CMIDriverMgr::Instance();
74   lldb::SBDebugger *pDebugger = rDriverMgr.DriverGetTheDebugger();
75   if (pDebugger != nullptr) {
76     if (!g_interrupt_sent.test_and_set()) {
77       pDebugger->DispatchInputInterrupt();
78       g_interrupt_sent.clear();
79     }
80   }
81
82   // Send signal to driver so that it can take suitable action
83   rDriverMgr.DeliverSignal(vSigno);
84 }
85
86 //++
87 // Details: Init the MI driver system. Initialize the whole driver system which
88 // includes
89 //          both the original LLDB driver and the MI driver.
90 // Type:    Function.
91 // Args:    None.
92 // Return:  MIstatus::success - Functional succeeded.
93 //          MIstatus::failure - Functional failed.
94 // Throws:  None.
95 //--
96 bool DriverSystemInit() {
97   bool bOk = MIstatus::success;
98   CMIDriver &rMIDriver = CMIDriver::Instance();
99   CMIDriverMgr &rDriverMgr = CMIDriverMgr::Instance();
100   bOk = rDriverMgr.Initialize();
101
102   // Register MIDriver first as it needs to initialize and be ready
103   // for the Driver to get information from MIDriver when it initializes
104   // (LLDB Driver is registered with the Driver Manager in MI's Initialize())
105   bOk = bOk &&
106         rDriverMgr.RegisterDriver(rMIDriver, "MIDriver"); // Will be main driver
107
108   return bOk;
109 }
110
111 //++
112 // Details: Shutdown the debugger system. Release / terminate resources external
113 // to
114 //          specifically the MI driver.
115 // Type:    Function.
116 // Args:    vbAppExitOk - (R) True = No problems, false = App exiting with
117 // problems (investigate!).
118 // Return:  MIstatus::success - Functional succeeded.
119 //          MIstatus::failure - Functional failed.
120 // Throws:  None.
121 //--
122 bool DriverSystemShutdown(const bool vbAppExitOk) {
123   bool bOk = MIstatus::success;
124
125   // *** Order is important here ***
126   CMIDriverMgr::Instance().Shutdown();
127   return bOk;
128 }
129
130 //++
131 // Details: MI's application start point of execution. The application runs in
132 // two modes.
133 //          An LLDB native driver mode where it acts no different from the LLDB
134 //          driver.
135 //          The other mode is the MI when it finds on the command line
136 //          the --interpreter option. Command line argument --help on its own
137 //          will give
138 //          help for the LLDB driver. If entered with --interpreter then
139 //          application
140 //          help will provided.
141 // Type:    Method.
142 // Args:    argc    - (R) An integer that contains the count of arguments that
143 // follow in
144 //                        argv. The argc parameter is always greater than or
145 //                        equal to 1.
146 //          argv    - (R) An array of null-terminated strings representing
147 //          command-line
148 //                        arguments entered by the user of the program. By
149 //                        convention,
150 //                        argv[0] is the command with which the program is
151 //                        invoked.
152 // Return:  int -  0 =   Normal exit, program success.
153 //                >0    = Program success with status i.e. Control-C signal
154 //                status
155 //                <0    = Program failed.
156 //              -1      = Program failed reason not specified here, see MI log
157 //              file.
158 //              -1000   = Program failed did not initialize successfully.
159 // Throws:  None.
160 //--
161 int main(int argc, char const *argv[]) {
162 #if MICONFIG_DEBUG_SHOW_ATTACH_DBG_DLG
163   CMIUtilDebug::WaitForDbgAttachInfinteLoop();
164 #endif // MICONFIG_DEBUG_SHOW_ATTACH_DBG_DLG
165
166   llvm::StringRef ToolName = argv[0];
167   llvm::sys::PrintStackTraceOnErrorSignal(ToolName);
168   llvm::PrettyStackTraceProgram X(argc, argv);
169
170   // *** Order is important here ***
171   bool bOk = DriverSystemInit();
172   if (!bOk) {
173     DriverSystemShutdown(bOk);
174     return -1000;
175   }
176
177   // CODETAG_IOR_SIGNALS
178   signal(SIGINT, sigint_handler);
179
180   bool bExiting = false;
181   CMIDriverMgr &rDriverMgr = CMIDriverMgr::Instance();
182   bOk = bOk && rDriverMgr.ParseArgs(argc, argv, bExiting);
183   if (bOk && !bExiting)
184     bOk = rDriverMgr.DriverParseArgs(argc, argv, stdout, bExiting);
185   if (bOk && !bExiting)
186     bOk = rDriverMgr.DriverMainLoop();
187
188   // Logger and other resources shutdown now
189   DriverSystemShutdown(bOk);
190
191   const int appResult = bOk ? 0 : -1;
192
193   return appResult;
194 }