1 //===-- MIDriverMain.cpp ----------------------------------------*- C++ -*-===//
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
7 //===----------------------------------------------------------------------===//
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
13 // The other mode is the MI when it finds on the command line
14 // the --interpreter option. Command line argument --help on its
16 // help for the LLDB driver. If entered with --interpreter then MI
19 // To implement new MI commands derive a new command class from the
21 // class. To enable the new command for interpretation add the new
23 // to the command factory. The files of relevance are:
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"
38 #include "MICmnConfig.h"
39 #include "MICmnResources.h"
40 #include "MICmnStreamStdin.h"
42 #include "MIDriverMgr.h"
43 #include "MIUtilDebug.h"
48 once : 4530) // Warning C4530: C++ exception handler used, but unwind
49 // semantics are not enabled. Specify /EHsc
52 // CODETAG_IOR_SIGNALS
54 // Details: The SIGINT signal is sent to a process by its controlling terminal
56 // user wishes to interrupt the process. This is typically initiated by
58 // Control-C, but on some systems, the "delete" character or "break"
61 // Be aware this function may be called on another thread besides the
64 // Args: vSigno - (R) Signal number.
68 void sigint_handler(int vSigno) {
69 #ifdef _WIN32 // Restore handler as it is not persistent on Windows
70 signal(SIGINT, sigint_handler);
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();
82 // Send signal to driver so that it can take suitable action
83 rDriverMgr.DeliverSignal(vSigno);
87 // Details: Init the MI driver system. Initialize the whole driver system which
89 // both the original LLDB driver and the MI driver.
92 // Return: MIstatus::success - Functional succeeded.
93 // MIstatus::failure - Functional failed.
96 bool DriverSystemInit() {
97 bool bOk = MIstatus::success;
98 CMIDriver &rMIDriver = CMIDriver::Instance();
99 CMIDriverMgr &rDriverMgr = CMIDriverMgr::Instance();
100 bOk = rDriverMgr.Initialize();
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())
106 rDriverMgr.RegisterDriver(rMIDriver, "MIDriver"); // Will be main driver
112 // Details: Shutdown the debugger system. Release / terminate resources external
114 // specifically the MI driver.
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.
122 bool DriverSystemShutdown(const bool vbAppExitOk) {
123 bool bOk = MIstatus::success;
125 // *** Order is important here ***
126 CMIDriverMgr::Instance().Shutdown();
131 // Details: MI's application start point of execution. The application runs in
133 // An LLDB native driver mode where it acts no different from the LLDB
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
138 // help for the LLDB driver. If entered with --interpreter then
140 // help will provided.
142 // Args: argc - (R) An integer that contains the count of arguments that
144 // argv. The argc parameter is always greater than or
146 // argv - (R) An array of null-terminated strings representing
148 // arguments entered by the user of the program. By
150 // argv[0] is the command with which the program is
152 // Return: int - 0 = Normal exit, program success.
153 // >0 = Program success with status i.e. Control-C signal
155 // <0 = Program failed.
156 // -1 = Program failed reason not specified here, see MI log
158 // -1000 = Program failed did not initialize successfully.
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
166 llvm::StringRef ToolName = argv[0];
167 llvm::sys::PrintStackTraceOnErrorSignal(ToolName);
168 llvm::PrettyStackTraceProgram X(argc, argv);
170 // *** Order is important here ***
171 bool bOk = DriverSystemInit();
173 DriverSystemShutdown(bOk);
177 // CODETAG_IOR_SIGNALS
178 signal(SIGINT, sigint_handler);
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();
188 // Logger and other resources shutdown now
189 DriverSystemShutdown(bOk);
191 const int appResult = bOk ? 0 : -1;