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